1
- use std:: cmp:: max;
2
1
use std:: collections:: { HashMap , HashSet } ;
3
2
use std:: convert:: { TryFrom , TryInto } ;
4
3
use std:: fs:: File ;
@@ -30,12 +29,11 @@ use near_primitives::views::{
30
29
AccessKeyInfoView , CallResult , QueryError , QueryResponse , ViewStateResult ,
31
30
} ;
32
31
use near_store:: {
33
- get_access_key_raw, get_account, set_account, StorageError , Store , StoreUpdate , Trie ,
34
- TrieUpdate , WrappedTrieChanges , COL_STATE ,
32
+ get_access_key_raw, Store , StoreUpdate , Trie , TrieUpdate , WrappedTrieChanges , COL_STATE ,
35
33
} ;
36
34
use node_runtime:: adapter:: ViewRuntimeAdapter ;
37
35
use node_runtime:: state_viewer:: TrieViewer ;
38
- use node_runtime:: { ApplyState , Runtime , StateRecord } ;
36
+ use node_runtime:: { ApplyState , Runtime , StateRecord , ValidatorAccountsUpdate } ;
39
37
40
38
use crate :: config:: GenesisConfig ;
41
39
use crate :: shard_tracker:: { account_id_to_shard_id, ShardTracker } ;
@@ -126,68 +124,6 @@ impl NightshadeRuntime {
126
124
}
127
125
}
128
126
129
- /// Iterates over validator accounts in the given shard and updates their accounts to return stake
130
- /// and allocate rewards.
131
- fn update_validator_accounts (
132
- & self ,
133
- shard_id : ShardId ,
134
- block_hash : & CryptoHash ,
135
- last_validator_proposals : & [ ValidatorStake ] ,
136
- state_update : & mut TrieUpdate ,
137
- ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
138
- let mut epoch_manager = self . epoch_manager . write ( ) . expect ( POISONED_LOCK_ERR ) ;
139
- let ( stake_info, validator_reward) = epoch_manager. compute_stake_return_info ( block_hash) ?;
140
- let account_to_stake =
141
- last_validator_proposals. iter ( ) . fold ( HashMap :: new ( ) , |mut acc, v| {
142
- acc. insert ( v. account_id . clone ( ) , v. amount ) ;
143
- acc
144
- } ) ;
145
-
146
- for ( account_id, max_of_stakes) in stake_info {
147
- if self . account_id_to_shard_id ( & account_id) == shard_id {
148
- let account: Option < Account > = get_account ( state_update, & account_id) ?;
149
- if let Some ( mut account) = account {
150
- if let Some ( reward) = validator_reward. get ( & account_id) {
151
- debug ! ( target: "runtime" , "account {} adding reward {} to stake {}" , account_id, reward, account. locked) ;
152
- account. locked += * reward;
153
- }
154
-
155
- debug ! ( target: "runtime" ,
156
- "account {} stake {} max_of_stakes: {}" ,
157
- account_id, account. locked, max_of_stakes
158
- ) ;
159
- assert ! (
160
- account. locked >= max_of_stakes,
161
- "FATAL: staking invariant does not hold. Account stake {} is less than maximum of stakes {} in the past three epochs" ,
162
- account. locked,
163
- max_of_stakes
164
- ) ;
165
- let last_stake = * account_to_stake. get ( & account_id) . unwrap_or ( & 0 ) ;
166
- let return_stake = account. locked - max ( max_of_stakes, last_stake) ;
167
- debug ! ( target: "runtime" , "account {} return stake {}" , account_id, return_stake) ;
168
- account. locked -= return_stake;
169
- account. amount += return_stake;
170
-
171
- set_account ( state_update, & account_id, & account) ;
172
- }
173
- }
174
- }
175
- if self . account_id_to_shard_id ( & self . genesis_config . protocol_treasury_account ) == shard_id {
176
- let mut protocol_treasury_account =
177
- get_account ( state_update, & self . genesis_config . protocol_treasury_account ) ?. unwrap ( ) ;
178
- protocol_treasury_account. amount +=
179
- * validator_reward. get ( & self . genesis_config . protocol_treasury_account ) . unwrap ( ) ;
180
- set_account (
181
- state_update,
182
- & self . genesis_config . protocol_treasury_account ,
183
- & protocol_treasury_account,
184
- ) ;
185
- }
186
- state_update. commit ( ) ;
187
-
188
- Ok ( ( ) )
189
- }
190
-
191
127
fn genesis_state_from_dump ( & self ) -> ( StoreUpdate , Vec < StateRoot > ) {
192
128
let store_update = self . store . store_update ( ) ;
193
129
let mut state_file = self . home_dir . clone ( ) ;
@@ -603,33 +539,45 @@ impl RuntimeAdapter for NightshadeRuntime {
603
539
} else {
604
540
self . trie . clone ( )
605
541
} ;
606
- let mut state_update = TrieUpdate :: new ( trie. clone ( ) , state_root. hash ) ;
607
- let should_update_account = {
542
+ let validator_accounts_update = {
608
543
let mut epoch_manager = self . epoch_manager . write ( ) . expect ( POISONED_LOCK_ERR ) ;
609
544
debug ! ( target: "runtime" ,
610
545
"block index: {}, is next_block_epoch_start {}" ,
611
546
block_index,
612
547
epoch_manager. is_next_block_epoch_start( prev_block_hash) . unwrap( )
613
548
) ;
614
- epoch_manager. is_next_block_epoch_start ( prev_block_hash) ?
549
+ if epoch_manager. is_next_block_epoch_start ( prev_block_hash) ? {
550
+ let ( stake_info, validator_reward) =
551
+ epoch_manager. compute_stake_return_info ( prev_block_hash) ?;
552
+ let stake_info = stake_info
553
+ . into_iter ( )
554
+ . filter ( |( account_id, _) | self . account_id_to_shard_id ( account_id) == shard_id)
555
+ . collect ( ) ;
556
+ let validator_rewards = validator_reward
557
+ . into_iter ( )
558
+ . filter ( |( account_id, _) | self . account_id_to_shard_id ( account_id) == shard_id)
559
+ . collect ( ) ;
560
+ let last_proposals = last_validator_proposals
561
+ . iter ( )
562
+ . filter ( |v| self . account_id_to_shard_id ( & v. account_id ) == shard_id)
563
+ . fold ( HashMap :: new ( ) , |mut acc, v| {
564
+ acc. insert ( v. account_id . clone ( ) , v. amount ) ;
565
+ acc
566
+ } ) ;
567
+ Some ( ValidatorAccountsUpdate {
568
+ stake_info,
569
+ validator_rewards,
570
+ last_proposals,
571
+ protocol_treasury_account_id : Some (
572
+ self . genesis_config . protocol_treasury_account . clone ( ) ,
573
+ )
574
+ . filter ( |account_id| self . account_id_to_shard_id ( account_id) == shard_id) ,
575
+ } )
576
+ } else {
577
+ None
578
+ }
615
579
} ;
616
580
617
- // If we are starting to apply 1st block in the new epoch.
618
- if should_update_account {
619
- self . update_validator_accounts (
620
- shard_id,
621
- prev_block_hash,
622
- last_validator_proposals,
623
- & mut state_update,
624
- )
625
- . map_err ( |e| {
626
- if let Some ( e) = e. downcast_ref :: < StorageError > ( ) {
627
- panic ! ( e. to_string( ) )
628
- }
629
- Error :: from ( ErrorKind :: ValidatorError ( e. to_string ( ) ) )
630
- } ) ?;
631
- }
632
-
633
581
let apply_state = ApplyState {
634
582
block_index,
635
583
epoch_length : self . genesis_config . epoch_length ,
@@ -639,7 +587,14 @@ impl RuntimeAdapter for NightshadeRuntime {
639
587
640
588
let apply_result = self
641
589
. runtime
642
- . apply ( state_update, & apply_state, & receipts, & transactions)
590
+ . apply (
591
+ trie. clone ( ) ,
592
+ state_root. hash ,
593
+ & validator_accounts_update,
594
+ & apply_state,
595
+ & receipts,
596
+ & transactions,
597
+ )
643
598
. map_err ( |e| match e {
644
599
RuntimeError :: InvalidTxError ( _) => ErrorKind :: InvalidTransactions ,
645
600
RuntimeError :: BalanceMismatch ( e) => panic ! ( "{}" , e) ,
0 commit comments