Skip to content

Commit 4cd863f

Browse files
Merge branch 'main' into register-functions-auth-docs-4i70bh
2 parents 5b5fbf6 + 88a8d51 commit 4cd863f

11 files changed

Lines changed: 483 additions & 77 deletions

File tree

Cargo.lock

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

Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ members = [
1515
]
1616

1717
[workspace.package]
18-
version = "27.0.1"
18+
version = "27.0.2"
1919
rust-version = "1.91.0"
2020

2121
[workspace.dependencies]
22-
soroban-sdk = { version = "27.0.1", path = "soroban-sdk" }
23-
soroban-sdk-macros = { version = "27.0.1", path = "soroban-sdk-macros" }
24-
soroban-meta = { version = "27.0.1", path = "soroban-meta" }
25-
soroban-spec = { version = "27.0.1", path = "soroban-spec" }
26-
soroban-spec-rust = { version = "27.0.1", path = "soroban-spec-rust" }
27-
soroban-ledger-snapshot = { version = "27.0.1", path = "soroban-ledger-snapshot" }
28-
soroban-token-sdk = { version = "27.0.1", path = "soroban-token-sdk" }
29-
soroban-token-spec = { version = "27.0.1", path = "soroban-token-spec" }
30-
stellar-asset-spec = { version = "27.0.1", path = "stellar-asset-spec" }
22+
soroban-sdk = { version = "27.0.2", path = "soroban-sdk" }
23+
soroban-sdk-macros = { version = "27.0.2", path = "soroban-sdk-macros" }
24+
soroban-meta = { version = "27.0.2", path = "soroban-meta" }
25+
soroban-spec = { version = "27.0.2", path = "soroban-spec" }
26+
soroban-spec-rust = { version = "27.0.2", path = "soroban-spec-rust" }
27+
soroban-ledger-snapshot = { version = "27.0.2", path = "soroban-ledger-snapshot" }
28+
soroban-token-sdk = { version = "27.0.2", path = "soroban-token-sdk" }
29+
soroban-token-spec = { version = "27.0.2", path = "soroban-token-spec" }
30+
stellar-asset-spec = { version = "27.0.2", path = "stellar-asset-spec" }
3131

3232
[workspace.dependencies.soroban-env-common]
3333
version = "=27.0.1"

soroban-sdk/src/_migrating.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
// NOTE FOR EDITORS: These migration guides describe the breaking changes
2+
// between major versions and what a developer needs to change when upgrading
3+
// the SDK from one major version to another. They are not a changelog: not
4+
// every small change is captured here. This is the document a developer should
5+
// read to understand what they need to change when upgrading.
6+
17
//! # Migrating from v26 to v27
28
//!
39
//! 1. [`bytes!` and `bytesn!` no longer accept base10 (decimal) integer literals][v27_bytes_literals].

soroban-sdk/src/env.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,13 +1045,21 @@ impl Env {
10451045
} else {
10461046
Address::generate(self)
10471047
};
1048+
// Convert the constructor arguments before switching auth managers, so
1049+
// that a panic during conversion cannot leave the environment stuck in
1050+
// recording auth. This matches the wasm registration path.
1051+
let constructor_args = constructor_args.into_val(self).to_object();
1052+
let prev_auth_manager = self.env_impl.snapshot_auth_manager().unwrap();
10481053
self.env_impl
1049-
.register_test_contract_with_constructor(
1050-
contract_id.to_object(),
1051-
Rc::new(InternalContractFunctionSet(contract)),
1052-
constructor_args.into_val(self).to_object(),
1053-
)
1054+
.switch_to_recording_auth_inherited_from_snapshot(&prev_auth_manager)
10541055
.unwrap();
1056+
let register_result = self.env_impl.register_test_contract_with_constructor(
1057+
contract_id.to_object(),
1058+
Rc::new(InternalContractFunctionSet(contract)),
1059+
constructor_args,
1060+
);
1061+
self.env_impl.set_auth_manager(prev_auth_manager).unwrap();
1062+
register_result.unwrap();
10551063
contract_id
10561064
}
10571065

soroban-sdk/src/tests/auth.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod auth_05_register_at_constructor;
2+
mod auth_06_register_native_constructor;
23
mod auth_10_one;
34
mod auth_15_one_repeat;
45
mod auth_17_no_consume_requirement;
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//! Demonstrates that register and register_at switch to recording auth for
2+
//! native contract constructors.
3+
//!
4+
//! A native contract whose constructor calls `require_auth` must succeed when
5+
//! registered with `register` or `register_at`, the same as the Wasm paths.
6+
//! Without switching to recording auth the constructor runs under the default
7+
//! enforcing auth and `require_auth` fails.
8+
9+
use crate as soroban_sdk;
10+
11+
use soroban_sdk::{contract, contractimpl, testutils::Address as _, Address, Env};
12+
13+
#[contract]
14+
pub struct Contract;
15+
16+
#[contractimpl]
17+
impl Contract {
18+
pub fn __constructor(env: Env, admin: Address) {
19+
admin.require_auth();
20+
env.storage().instance().set(&"admin", &admin);
21+
}
22+
}
23+
24+
#[contract]
25+
pub struct Probe;
26+
27+
#[contractimpl]
28+
impl Probe {
29+
pub fn need_auth(_env: Env, address: Address) {
30+
address.require_auth();
31+
}
32+
}
33+
34+
// Auth is intentionally not mocked in these tests.
35+
36+
#[test]
37+
fn register() {
38+
let e = Env::default();
39+
40+
let admin = Address::generate(&e);
41+
e.register(Contract, (&admin,));
42+
}
43+
44+
#[test]
45+
fn register_at() {
46+
let e = Env::default();
47+
48+
let admin = Address::generate(&e);
49+
let contract_id = Address::generate(&e);
50+
e.register_at(&contract_id, Contract, (&admin,));
51+
}
52+
53+
// If registration fails while the constructor is running, the previous auth
54+
// manager must be restored rather than left in recording mode. Otherwise later
55+
// require_auth calls would be silently auto-authorized.
56+
#[test]
57+
fn register_restores_auth_before_panics() {
58+
let e = Env::default();
59+
60+
// A native contract with a function that requires auth, used to probe
61+
// whether the environment is enforcing authorization.
62+
let probe = e.register(Probe, ());
63+
let probe_client = ProbeClient::new(&e, &probe);
64+
let user = Address::generate(&e);
65+
66+
// Before the failed registration an unmocked require_auth is enforced.
67+
let pre = probe_client.try_need_auth(&user);
68+
assert!(pre.is_err());
69+
70+
// Registering the contract with missing constructor arguments fails while
71+
// constructing. Catch the failure inside a contract frame so it does not
72+
// abort the test.
73+
let another = e.register(Probe, ());
74+
let register_result = e.try_as_contract::<_, soroban_sdk::Error>(&another, || {
75+
e.register(Contract, ());
76+
});
77+
assert!(register_result.is_err());
78+
79+
// The previous auth manager must have been restored: require_auth is still
80+
// enforced after the failed registration.
81+
let post = probe_client.try_need_auth(&user);
82+
assert!(post.is_err());
83+
assert_eq!(pre, post);
84+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"generators": {
3+
"address": 2,
4+
"nonce": 0,
5+
"mux_id": 0
6+
},
7+
"auth": [
8+
[
9+
[
10+
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
11+
{
12+
"function": {
13+
"contract_fn": {
14+
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
15+
"function_name": "__constructor",
16+
"args": [
17+
{
18+
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
19+
}
20+
]
21+
}
22+
},
23+
"sub_invocations": []
24+
}
25+
]
26+
]
27+
],
28+
"ledger": {
29+
"protocol_version": 27,
30+
"sequence_number": 0,
31+
"timestamp": 0,
32+
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
33+
"base_reserve": 0,
34+
"min_persistent_entry_ttl": 4096,
35+
"min_temp_entry_ttl": 16,
36+
"max_entry_ttl": 6312000,
37+
"ledger_entries": [
38+
{
39+
"entry": {
40+
"last_modified_ledger_seq": 0,
41+
"data": {
42+
"contract_data": {
43+
"ext": "v0",
44+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
45+
"key": {
46+
"ledger_key_nonce": {
47+
"nonce": "801925984706572462"
48+
}
49+
},
50+
"durability": "temporary",
51+
"val": "void"
52+
}
53+
},
54+
"ext": "v0"
55+
},
56+
"live_until": 6311999
57+
},
58+
{
59+
"entry": {
60+
"last_modified_ledger_seq": 0,
61+
"data": {
62+
"contract_data": {
63+
"ext": "v0",
64+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
65+
"key": "ledger_key_contract_instance",
66+
"durability": "persistent",
67+
"val": {
68+
"contract_instance": {
69+
"executable": {
70+
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
71+
},
72+
"storage": [
73+
{
74+
"key": {
75+
"string": "admin"
76+
},
77+
"val": {
78+
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
79+
}
80+
}
81+
]
82+
}
83+
}
84+
}
85+
},
86+
"ext": "v0"
87+
},
88+
"live_until": 4095
89+
},
90+
{
91+
"entry": {
92+
"last_modified_ledger_seq": 0,
93+
"data": {
94+
"contract_code": {
95+
"ext": "v0",
96+
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
97+
"code": ""
98+
}
99+
},
100+
"ext": "v0"
101+
},
102+
"live_until": 4095
103+
}
104+
]
105+
},
106+
"events": []
107+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
{
2+
"generators": {
3+
"address": 2,
4+
"nonce": 0,
5+
"mux_id": 0
6+
},
7+
"auth": [
8+
[
9+
[
10+
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
11+
{
12+
"function": {
13+
"contract_fn": {
14+
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
15+
"function_name": "__constructor",
16+
"args": [
17+
{
18+
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
19+
}
20+
]
21+
}
22+
},
23+
"sub_invocations": []
24+
}
25+
]
26+
]
27+
],
28+
"ledger": {
29+
"protocol_version": 27,
30+
"sequence_number": 0,
31+
"timestamp": 0,
32+
"network_id": "0000000000000000000000000000000000000000000000000000000000000000",
33+
"base_reserve": 0,
34+
"min_persistent_entry_ttl": 4096,
35+
"min_temp_entry_ttl": 16,
36+
"max_entry_ttl": 6312000,
37+
"ledger_entries": [
38+
{
39+
"entry": {
40+
"last_modified_ledger_seq": 0,
41+
"data": {
42+
"contract_data": {
43+
"ext": "v0",
44+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
45+
"key": {
46+
"ledger_key_nonce": {
47+
"nonce": "801925984706572462"
48+
}
49+
},
50+
"durability": "temporary",
51+
"val": "void"
52+
}
53+
},
54+
"ext": "v0"
55+
},
56+
"live_until": 6311999
57+
},
58+
{
59+
"entry": {
60+
"last_modified_ledger_seq": 0,
61+
"data": {
62+
"contract_data": {
63+
"ext": "v0",
64+
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
65+
"key": "ledger_key_contract_instance",
66+
"durability": "persistent",
67+
"val": {
68+
"contract_instance": {
69+
"executable": {
70+
"wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
71+
},
72+
"storage": [
73+
{
74+
"key": {
75+
"string": "admin"
76+
},
77+
"val": {
78+
"address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM"
79+
}
80+
}
81+
]
82+
}
83+
}
84+
}
85+
},
86+
"ext": "v0"
87+
},
88+
"live_until": 4095
89+
},
90+
{
91+
"entry": {
92+
"last_modified_ledger_seq": 0,
93+
"data": {
94+
"contract_code": {
95+
"ext": "v0",
96+
"hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
97+
"code": ""
98+
}
99+
},
100+
"ext": "v0"
101+
},
102+
"live_until": 4095
103+
}
104+
]
105+
},
106+
"events": []
107+
}

0 commit comments

Comments
 (0)