Skip to content

Commit c215b91

Browse files
Address a bug with message during instantiation. (#4366)
## Motivation The scenario of a smart contract emitting a message during instantiation breaks the `TestValidator` framework. We address the problem here. Fixes #3539 ## Proposal The correction pointed out in the issue is exactly what is needed. A smart contract has been created that demonstrates that the correction works and also test in the end-to-end test, which is nice to check. ## Test Plan CI. ## Release Plan - Nothing to do / These changes follow the usual release cycle. ## Links None.
1 parent 9cf38c1 commit c215b91

File tree

12 files changed

+211
-1
lines changed

12 files changed

+211
-1
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ native-fungible = { path = "./examples/native-fungible" }
315315
non-fungible = { path = "./examples/non-fungible" }
316316
publish-read-data-blob = { path = "./examples/publish-read-data-blob" }
317317
social = { path = "./examples/social" }
318+
track-instantiation = { path = "./examples/track-instantiation" }
318319

319320
[workspace.dependencies.aws-config]
320321
default-features = false

examples/Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ members = [
2121
"publish-read-data-blob",
2222
"rfq",
2323
"social",
24+
"track-instantiation",
2425
]
2526

2627
[workspace.dependencies]
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "track-instantiation"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
linera-sdk = { path = "../../linera-sdk" }
8+
serde = { version = "1.0", features = ["derive"] }
9+
10+
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
11+
futures = "0.3"
12+
linera-sdk = { workspace = true, features = ["test", "wasmer"] }
13+
tokio.workspace = true
14+
15+
[[bin]]
16+
name = "track_instantiation_contract"
17+
path = "src/contract.rs"
18+
19+
[[bin]]
20+
name = "track_instantiation_service"
21+
path = "src/service.rs"
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![cfg_attr(target_arch = "wasm32", no_main)]
5+
6+
mod state;
7+
8+
use linera_sdk::{
9+
linera_base_types::WithContractAbi,
10+
views::{RootView, View},
11+
Contract, ContractRuntime,
12+
};
13+
use track_instantiation::TrackInstantiationAbi;
14+
15+
use self::state::TrackInstantiationState;
16+
17+
pub struct TrackInstantiationContract {
18+
state: TrackInstantiationState,
19+
runtime: ContractRuntime<Self>,
20+
}
21+
22+
linera_sdk::contract!(TrackInstantiationContract);
23+
24+
impl WithContractAbi for TrackInstantiationContract {
25+
type Abi = TrackInstantiationAbi;
26+
}
27+
28+
impl Contract for TrackInstantiationContract {
29+
type Message = ();
30+
type InstantiationArgument = ();
31+
type Parameters = ();
32+
type EventValue = ();
33+
34+
async fn load(runtime: ContractRuntime<Self>) -> Self {
35+
let state = TrackInstantiationState::load(runtime.root_view_storage_context())
36+
.await
37+
.expect("Failed to load state");
38+
39+
TrackInstantiationContract { state, runtime }
40+
}
41+
42+
async fn instantiate(&mut self, _argument: ()) {
43+
self.runtime.application_parameters();
44+
45+
// Send message to creator chain about instantiation
46+
let creator_chain = self.runtime.application_creator_chain_id();
47+
self.runtime
48+
.prepare_message(())
49+
.with_authentication()
50+
.send_to(creator_chain);
51+
}
52+
53+
async fn execute_operation(&mut self, _operation: ()) {
54+
panic!("No operation being executed");
55+
}
56+
57+
async fn execute_message(&mut self, _message: ()) {
58+
let count = self.state.stats.get_mut();
59+
*count += 1;
60+
}
61+
62+
async fn store(mut self) {
63+
self.state.save().await.expect("Failed to save state");
64+
}
65+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
/*! ABI of the Track Instantiation Load Operation Application */
5+
6+
use linera_sdk::linera_base_types::{ContractAbi, ServiceAbi};
7+
use serde::{Deserialize, Serialize};
8+
9+
pub struct TrackInstantiationAbi;
10+
11+
#[derive(Debug, Clone, Serialize, Deserialize)]
12+
pub enum Query {
13+
GetCount,
14+
}
15+
16+
impl ContractAbi for TrackInstantiationAbi {
17+
type Operation = ();
18+
type Response = ();
19+
}
20+
21+
impl ServiceAbi for TrackInstantiationAbi {
22+
type Query = Query;
23+
type QueryResponse = u64;
24+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#![cfg_attr(target_arch = "wasm32", no_main)]
5+
6+
mod state;
7+
8+
use linera_sdk::{linera_base_types::WithServiceAbi, views::View, Service, ServiceRuntime};
9+
use track_instantiation::{Query, TrackInstantiationAbi};
10+
11+
use self::state::TrackInstantiationState;
12+
13+
pub struct TrackInstantiationService {
14+
state: TrackInstantiationState,
15+
}
16+
17+
linera_sdk::service!(TrackInstantiationService);
18+
19+
impl WithServiceAbi for TrackInstantiationService {
20+
type Abi = TrackInstantiationAbi;
21+
}
22+
23+
impl Service for TrackInstantiationService {
24+
type Parameters = ();
25+
26+
async fn new(runtime: ServiceRuntime<Self>) -> Self {
27+
let state = TrackInstantiationState::load(runtime.root_view_storage_context())
28+
.await
29+
.expect("Failed to load state");
30+
TrackInstantiationService { state }
31+
}
32+
33+
async fn handle_query(&self, query: Query) -> u64 {
34+
match query {
35+
Query::GetCount => *self.state.stats.get(),
36+
}
37+
}
38+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
use linera_sdk::views::{linera_views, RegisterView, RootView, ViewStorageContext};
5+
6+
/// The application state.
7+
#[derive(RootView)]
8+
#[view(context = ViewStorageContext)]
9+
pub struct TrackInstantiationState {
10+
pub stats: RegisterView<u64>,
11+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Integration tests for the Fungible Token application.
5+
6+
#![cfg(not(target_arch = "wasm32"))]
7+
8+
use linera_sdk::test::TestValidator;
9+
use track_instantiation::{Query, TrackInstantiationAbi};
10+
11+
/// Test transferring tokens across microchains.
12+
///
13+
/// Creates the application on a `sender_chain`, initializing it with a single account with some
14+
/// tokens for that chain's owner. Transfers some of those tokens to a new `receiver_chain`, and
15+
/// checks that the balances on each microchain are correct.
16+
#[tokio::test]
17+
async fn test_instantiation_messages() {
18+
let (validator, module_id) =
19+
TestValidator::with_current_module::<TrackInstantiationAbi, (), ()>().await;
20+
let mut sender_chain = validator.new_chain().await;
21+
22+
let application_id = sender_chain
23+
.create_application(module_id, (), (), vec![])
24+
.await;
25+
26+
sender_chain.handle_received_messages().await;
27+
28+
let query = Query::GetCount;
29+
assert_eq!(sender_chain.query(application_id, query).await.response, 1);
30+
}

0 commit comments

Comments
 (0)