Skip to content

Commit f165420

Browse files
authored
feat: port v7 from release (#6884)
# Description of change Ported the built `v7` binaries and the necessary code changes from `v1.1.0`. Moved all previous `v7` changes to `v8` and updated the version to `v1.2.0-alpha`.
1 parent 72833a9 commit f165420

29 files changed

+1276
-214
lines changed

Cargo.lock

Lines changed: 157 additions & 157 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 & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ members = [
170170

171171
[workspace.package]
172172
# This version string will be inherited by iota-core, iota-faucet, iota-node, iota-tools, iota-sdk, iota-move-build, and iota crates.
173-
version = "1.1.0-alpha"
173+
version = "1.2.0-alpha"
174174

175175
[profile.release]
176176
# debug = 1 means line charts only, which is minimum needed for good stack traces

crates/iota-framework-snapshot/manifest.json

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,37 @@
180180
]
181181
},
182182
"7": {
183-
"git_revision": "a9d93ac5f371",
183+
"git_revision": "58b8c8221b60",
184+
"packages": [
185+
{
186+
"name": "MoveStdlib",
187+
"path": "crates/iota-framework/packages/move-stdlib",
188+
"id": "0x0000000000000000000000000000000000000000000000000000000000000001"
189+
},
190+
{
191+
"name": "Iota",
192+
"path": "crates/iota-framework/packages/iota-framework",
193+
"id": "0x0000000000000000000000000000000000000000000000000000000000000002"
194+
},
195+
{
196+
"name": "IotaSystem",
197+
"path": "crates/iota-framework/packages/iota-system",
198+
"id": "0x0000000000000000000000000000000000000000000000000000000000000003"
199+
},
200+
{
201+
"name": "Bridge",
202+
"path": "crates/iota-framework/packages/bridge",
203+
"id": "0x000000000000000000000000000000000000000000000000000000000000000b"
204+
},
205+
{
206+
"name": "Stardust",
207+
"path": "crates/iota-framework/packages/stardust",
208+
"id": "0x000000000000000000000000000000000000000000000000000000000000107a"
209+
}
210+
]
211+
},
212+
"8": {
213+
"git_revision": "32aced12b2d6",
184214
"packages": [
185215
{
186216
"name": "MoveStdlib",

crates/iota-framework/packages/iota-system/sources/staking_pool.move

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,19 @@ public(package) fun request_withdraw_stake(
134134
// stake is inactive
135135
if (staked_iota.stake_activation_epoch > ctx.epoch()) {
136136
let principal = unwrap_staked_iota(staked_iota);
137-
138-
// Stake for preactive validators is always processed immediately and not added to the pending stake.
139-
if (!pool.is_preactive()) {
140-
pool.pending_stake = pool.pending_stake - principal.value();
137+
let withdraw_amount = principal.value();
138+
139+
if (pool.is_preactive()) {
140+
// Stake for preactive validators is always processed immediately and not added to the pending stake.
141+
// The exchange rate of a preactive pool is always 1:1, so we can subtract the withdraw_amount
142+
// from both iota_balance and pool_token_balance.
143+
pool.iota_balance = pool.iota_balance - withdraw_amount;
144+
pool.pool_token_balance = pool.pool_token_balance - withdraw_amount;
145+
check_balance_invariants(pool, ctx.epoch());
146+
} else {
147+
// The stake for active validators is only updated at epoch boundaries,
148+
// so we can remove it from the pending_stake here.
149+
pool.pending_stake = pool.pending_stake - withdraw_amount;
141150
};
142151

143152
return principal
@@ -162,9 +171,6 @@ public(package) fun request_withdraw_stake(
162171
pool.pending_pool_token_withdraw =
163172
pool.pending_pool_token_withdraw + pool_token_withdraw_amount;
164173

165-
// If the pool is inactive, we immediately process the withdrawal.
166-
if (is_inactive(pool)) process_pending_stake_withdraw(pool);
167-
168174
// TODO: implement withdraw bonding period here.
169175
principal_withdraw.join(rewards_withdraw);
170176
principal_withdraw
@@ -235,8 +241,8 @@ public(package) fun process_pending_stakes_and_withdraws(
235241
}
236242

237243
/// Called at epoch boundaries to process pending stake withdraws requested during the epoch.
238-
/// Also called immediately upon withdrawal if the pool is inactive.
239-
fun process_pending_stake_withdraw(pool: &mut StakingPoolV1) {
244+
/// Also called immediately upon withdrawal if the pool is inactive or if the pool is preactive.
245+
public(package) fun process_pending_stake_withdraw(pool: &mut StakingPoolV1) {
240246
pool.iota_balance = pool.iota_balance - pool.pending_total_iota_withdraw;
241247
pool.pool_token_balance = pool.pool_token_balance - pool.pending_pool_token_withdraw;
242248
pool.pending_total_iota_withdraw = 0;

crates/iota-framework/packages/iota-system/sources/validator.move

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,10 @@ public(package) fun request_withdraw_stake(
342342
let principal_amount = staked_iota.staked_iota_amount();
343343
let stake_activation_epoch = staked_iota.stake_activation_epoch();
344344
let withdrawn_stake = self.staking_pool.request_withdraw_stake(staked_iota, ctx);
345+
// Process withdraw right away if staking pool is preactive or inactive
346+
if (self.staking_pool.is_preactive() || self.staking_pool.is_inactive()) {
347+
self.staking_pool.process_pending_stake_withdraw();
348+
};
345349
let withdraw_amount = withdrawn_stake.value();
346350
let reward_amount = withdraw_amount - principal_amount;
347351
self.next_epoch_stake = self.next_epoch_stake - withdraw_amount;
@@ -494,6 +498,10 @@ public fun total_stake(self: &ValidatorV1): u64 {
494498
stake_amount(self)
495499
}
496500

501+
public(package) fun next_epoch_stake(self: &ValidatorV1): u64 {
502+
self.next_epoch_stake
503+
}
504+
497505
/// Return the voting power of this validator.
498506
public fun voting_power(self: &ValidatorV1): u64 {
499507
self.voting_power

crates/iota-framework/packages/iota-system/sources/validator_set.move

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ const EValidatorAlreadyRemoved: u64 = 11;
159159
const ENotAPendingValidator: u64 = 12;
160160
const EValidatorSetEmpty: u64 = 13;
161161
const ENotACommitteeValidator: u64 = 14;
162+
const EInvalidStakeAmount: u64 = 15;
162163

163164
const EInvalidCap: u64 = 101;
164165

@@ -342,6 +343,7 @@ public(package) fun request_add_validator(
342343
EDuplicateValidator,
343344
);
344345
assert!(validator.is_preactive(), EValidatorNotCandidate);
346+
assert!(validator.total_stake_amount() == validator.next_epoch_stake(), EInvalidStakeAmount);
345347
assert!(validator.total_stake_amount() >= min_joining_stake_amount, EMinJoiningStakeNotReached);
346348

347349
self.pending_active_validators.push_back(validator);

crates/iota-framework/packages/iota-system/tests/delegation_tests.move

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use iota_system::governance_test_utils::{
1616
advance_epoch_with_max_committee_members_count,
1717
advance_epoch_with_balanced_reward_amounts,
1818
assert_validator_total_stake_amounts,
19+
assert_validator_candidate_total_stake_amounts,
1920
create_validator_for_testing,
2021
create_iota_system_state_for_testing,
2122
stake_with,
@@ -563,6 +564,130 @@ fun test_add_preactive_remove_pending_failure() {
563564
scenario_val.end();
564565
}
565566

567+
#[test]
568+
fun test_add_preactive_remove_preactive_check_total_stake_amount() {
569+
set_up_iota_system_state();
570+
let mut scenario_val = test_scenario::begin(VALIDATOR_ADDR_1);
571+
let scenario = &mut scenario_val;
572+
573+
add_validator_candidate(
574+
NEW_VALIDATOR_ADDR,
575+
b"name5",
576+
b"/ip4/127.0.0.1/udp/85",
577+
NEW_VALIDATOR_PUBKEY,
578+
NEW_VALIDATOR_POP,
579+
scenario,
580+
);
581+
582+
// Delegate 100 NANOS to the preactive validator
583+
stake_with(STAKER_ADDR_1, NEW_VALIDATOR_ADDR, 100, scenario);
584+
585+
// Advance epoch with some rewards
586+
advance_epoch_with_balanced_reward_amounts(0, 400, scenario);
587+
588+
// The preactive validator should have 100 NANOS total stake
589+
assert_validator_candidate_total_stake_amounts(
590+
vector[NEW_VALIDATOR_ADDR],
591+
vector[100 * NANOS_PER_IOTA],
592+
scenario,
593+
);
594+
595+
// Unstake from the preactive validator. There should be no rewards earned.
596+
unstake(STAKER_ADDR_1, 0, scenario);
597+
assert_eq(total_iota_balance(STAKER_ADDR_1, scenario), 100 * NANOS_PER_IOTA);
598+
599+
// The preactive validator should have no stake since it got unstaked
600+
assert_validator_candidate_total_stake_amounts(
601+
vector[NEW_VALIDATOR_ADDR],
602+
vector[0 * NANOS_PER_IOTA],
603+
scenario,
604+
);
605+
606+
// Advance epoch
607+
advance_epoch_with_balanced_reward_amounts(0, 0, scenario);
608+
609+
// The preactive validator should still have no stake
610+
assert_validator_candidate_total_stake_amounts(
611+
vector[NEW_VALIDATOR_ADDR],
612+
vector[0 * NANOS_PER_IOTA],
613+
scenario,
614+
);
615+
616+
// Join validators -> Pending
617+
add_validator(NEW_VALIDATOR_ADDR, scenario);
618+
619+
// Transition validator from Pending -> Active
620+
advance_epoch(scenario);
621+
622+
// Transition validator from Active -> Active
623+
advance_epoch(scenario);
624+
625+
assert_validator_total_stake_amounts(
626+
vector[NEW_VALIDATOR_ADDR],
627+
vector[0 * NANOS_PER_IOTA],
628+
scenario,
629+
);
630+
631+
scenario_val.end();
632+
}
633+
634+
#[test]
635+
fun test_add_preactive_remove_preactive_check_total_stake_amount_same_epoch() {
636+
set_up_iota_system_state();
637+
let mut scenario_val = test_scenario::begin(VALIDATOR_ADDR_1);
638+
let scenario = &mut scenario_val;
639+
640+
add_validator_candidate(
641+
NEW_VALIDATOR_ADDR,
642+
b"name5",
643+
b"/ip4/127.0.0.1/udp/85",
644+
NEW_VALIDATOR_PUBKEY,
645+
NEW_VALIDATOR_POP,
646+
scenario,
647+
);
648+
649+
// Delegate 100 NANOS to the preactive validator
650+
stake_with(STAKER_ADDR_1, NEW_VALIDATOR_ADDR, 100, scenario);
651+
652+
// The preactive validator should have 100 NANOS total stake
653+
assert_validator_candidate_total_stake_amounts(
654+
vector[NEW_VALIDATOR_ADDR],
655+
vector[100 * NANOS_PER_IOTA],
656+
scenario,
657+
);
658+
659+
// Unstake from the preactive validator. There should be no rewards earned.
660+
unstake(STAKER_ADDR_1, 0, scenario);
661+
assert_eq(total_iota_balance(STAKER_ADDR_1, scenario), 100 * NANOS_PER_IOTA);
662+
663+
// Advance epoch
664+
advance_epoch_with_balanced_reward_amounts(0, 0, scenario);
665+
666+
// The preactive validator should have no stake since it got unstaked
667+
assert_validator_candidate_total_stake_amounts(
668+
vector[NEW_VALIDATOR_ADDR],
669+
vector[0 * NANOS_PER_IOTA],
670+
scenario,
671+
);
672+
673+
// Join validators -> Pending
674+
add_validator(NEW_VALIDATOR_ADDR, scenario);
675+
676+
// Transition validator from Pending -> Active
677+
advance_epoch(scenario);
678+
679+
// Transition validator from Active -> Active
680+
advance_epoch(scenario);
681+
682+
assert_validator_total_stake_amounts(
683+
vector[NEW_VALIDATOR_ADDR],
684+
vector[0 * NANOS_PER_IOTA],
685+
scenario,
686+
);
687+
688+
scenario_val.end();
689+
}
690+
566691
#[test]
567692
#[expected_failure(abort_code = validator_set::ENotAValidator)]
568693
fun test_add_pending_failure() {

crates/iota-framework/packages/iota-system/tests/governance_test_utils.move

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,6 @@ public fun assert_validator_self_stake_amounts(
559559
while (i < validator_addrs.length()) {
560560
let validator_addr = validator_addrs[i];
561561
let amount = stake_amounts[i];
562-
563562
scenario.next_tx(validator_addr);
564563
let mut system_state = scenario.take_shared<IotaSystemState>();
565564
let stake_plus_rewards = stake_plus_current_rewards_for_validator(
@@ -582,11 +581,10 @@ public fun assert_validator_total_stake_amounts(
582581
while (i < validator_addrs.length()) {
583582
let validator_addr = validator_addrs[i];
584583
let amount = stake_amounts[i];
585-
586584
scenario.next_tx(validator_addr);
587585
let mut system_state = scenario.take_shared<IotaSystemState>();
588586
let validator_amount = system_state.validator_stake_amount(validator_addr);
589-
assert!(validator_amount == amount, validator_amount);
587+
assert_eq(validator_amount, amount);
590588
test_scenario::return_shared(system_state);
591589
i = i + 1;
592590
};
@@ -611,6 +609,27 @@ public fun assert_validator_non_self_stake_amounts(
611609
};
612610
}
613611

612+
public fun assert_validator_candidate_total_stake_amounts(
613+
validator_addrs: vector<address>,
614+
stake_amounts: vector<u64>,
615+
scenario: &mut Scenario,
616+
) {
617+
let mut i = 0;
618+
while (i < validator_addrs.length()) {
619+
let validator_addr = validator_addrs[i];
620+
let amount = stake_amounts[i];
621+
scenario.next_tx(validator_addr);
622+
let mut system_state = scenario.take_shared<IotaSystemState>();
623+
let validator_amount = system_state
624+
.validators()
625+
.get_candidate_validator_ref(validator_addr)
626+
.total_stake_amount();
627+
assert_eq(validator_amount, amount);
628+
test_scenario::return_shared(system_state);
629+
i = i + 1;
630+
};
631+
}
632+
614633
/// Return the rewards for the validator at `addr` in terms of IOTA.
615634
public fun stake_plus_current_rewards_for_validator(
616635
addr: address,
178 Bytes
Binary file not shown.

crates/iota-framework/published_api.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ process_pending_stakes_and_withdraws
4747
public(package) fun
4848
0x3::staking_pool
4949
process_pending_stake_withdraw
50-
fun
50+
public(package) fun
5151
0x3::staking_pool
5252
process_pending_stake
5353
public(package) fun
@@ -253,6 +253,9 @@ stake_amount
253253
total_stake
254254
public fun
255255
0x3::validator
256+
next_epoch_stake
257+
public(package) fun
258+
0x3::validator
256259
voting_power
257260
public fun
258261
0x3::validator

crates/iota-graphql-e2e-tests/tests/call/simple.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,11 @@ task 15, lines 64-69:
117117
Headers: {
118118
"content-type": "application/json",
119119
"content-length": "157",
120-
"x-iota-rpc-version": "1.1.0-testing-no-sha",
120+
"x-iota-rpc-version": "1.2.0-testing-no-sha",
121121
"vary": "origin, access-control-request-method, access-control-request-headers",
122122
"access-control-allow-origin": "*",
123123
}
124-
Service version: 1.1.0-testing-no-sha
124+
Service version: 1.2.0-testing-no-sha
125125
Response: {
126126
"data": {
127127
"checkpoint": {
@@ -378,7 +378,7 @@ Response: {
378378
"data": {
379379
"serviceConfig": {
380380
"availableVersions": [
381-
"1.1"
381+
"1.2"
382382
]
383383
}
384384
}

crates/iota-open-rpc/spec/openrpc.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"name": "Apache-2.0",
1313
"url": "https://raw.githubusercontent.com/iotaledger/iota/main/LICENSE"
1414
},
15-
"version": "1.1.0-alpha"
15+
"version": "1.2.0-alpha"
1616
},
1717
"methods": [
1818
{
@@ -1301,7 +1301,7 @@
13011301
"name": "Result",
13021302
"value": {
13031303
"minSupportedProtocolVersion": "1",
1304-
"maxSupportedProtocolVersion": "7",
1304+
"maxSupportedProtocolVersion": "8",
13051305
"protocolVersion": "6",
13061306
"featureFlags": {
13071307
"accept_zklogin_in_multisig": false,

0 commit comments

Comments
 (0)