Skip to content
10 changes: 1 addition & 9 deletions chain/chain/src/resharding/flat_storage_resharder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ use near_primitives::trie_key::col::{self};
use near_primitives::trie_key::trie_key_parsers::{
parse_account_id_from_access_key_key, parse_account_id_from_account_key,
parse_account_id_from_contract_code_key, parse_account_id_from_contract_data_key,
parse_account_id_from_gas_key_key, parse_account_id_from_received_data_key,
parse_account_id_from_trie_key_with_separator,
parse_account_id_from_received_data_key, parse_account_id_from_trie_key_with_separator,
};
use near_primitives::types::{AccountId, BlockHeight};
use near_store::adapter::StoreAdapter;
Expand Down Expand Up @@ -842,13 +841,6 @@ fn shard_split_handle_key_value(
store_update,
parse_account_id_from_access_key_key,
)?,
col::GAS_KEY => copy_kv_to_child(
&split_params,
key,
value,
store_update,
parse_account_id_from_gas_key_key,
)?,
col::RECEIVED_DATA => copy_kv_to_child(
&split_params,
key,
Expand Down
59 changes: 31 additions & 28 deletions chain/chain/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,16 @@ use near_store::flat::FlatStorageManager;
use near_store::trie::{FindSplitError, find_trie_split, total_mem_usage};
use near_store::{
ApplyStatePartResult, COLD_HEAD_KEY, DBCol, ShardTries, StateSnapshotConfig, Store, Trie,
TrieConfig, TrieUpdate, WrappedTrieChanges, get_access_key, get_account, set_access_key,
set_account,
TrieConfig, TrieUpdate, WrappedTrieChanges, get_account, set_account,
};
use near_vm_runner::ContractCode;
use near_vm_runner::{ContractRuntimeCache, precompile_contract};
use node_runtime::adapter::ViewRuntimeAdapter;
use node_runtime::config::tx_cost;
use node_runtime::state_viewer::{TrieViewer, ViewApplyState};
use node_runtime::{
ApplyState, Runtime, SignedValidPeriodTransactions, ValidatorAccountsUpdate,
get_signer_and_access_key, validate_transaction, verify_and_charge_tx_ephemeral,
ApplyState, Runtime, SignedValidPeriodTransactions, ValidatorAccountsUpdate, get_key_state,
get_signer_and_key_state, set_key_state, validate_transaction, verify_and_charge_tx_ephemeral,
};
use std::collections::{HashMap, HashSet};
use std::sync::Arc;
Expand Down Expand Up @@ -652,11 +651,11 @@ impl RuntimeAdapter for NightshadeRuntime {
let shard_uid = shard_layout
.account_id_to_shard_uid(validated_tx.to_signed_tx().transaction.signer_id());
let trie = self.tries.get_trie_for_shard(shard_uid, state_root);
let (mut signer, mut access_key) = get_signer_and_access_key(&trie, &validated_tx)?;
let (mut signer, mut key_state) = get_signer_and_key_state(&trie, &validated_tx)?;
verify_and_charge_tx_ephemeral(
runtime_config,
&mut signer,
&mut access_key,
&mut key_state,
validated_tx.to_tx(),
&cost,
// here we do not know which block the transaction will be included
Expand Down Expand Up @@ -814,7 +813,7 @@ impl RuntimeAdapter for NightshadeRuntime {
}
}

let mut signer_access_key = None;
let mut signer_key_state = None;

// Take a single transaction from this transaction group
while let Some(tx_peek) = transaction_group_iter.peek_next() {
Expand Down Expand Up @@ -858,24 +857,28 @@ impl RuntimeAdapter for NightshadeRuntime {
}

let signer_id = validated_tx.signer_id();
let (signer, access_key) =
if let Some((id, signer, key, _)) = &mut signer_access_key {
debug_assert_eq!(signer_id, id);
(signer, key)
} else {
let signer = get_account(&state_update, signer_id);
let signer = signer.transpose().and_then(|v| v.ok());
let access_key =
get_access_key(&state_update, signer_id, validated_tx.public_key());
let access_key = access_key.transpose().and_then(|v| v.ok());
let inserted = signer_access_key.insert((
signer_id.clone(),
signer.ok_or(Error::InvalidTransactions)?,
access_key.ok_or(Error::InvalidTransactions)?,
validated_tx.public_key().clone(),
));
(&mut inserted.1, &mut inserted.2)
};
let (signer, key_state) = if let Some((id, signer, key, _)) = &mut signer_key_state
{
debug_assert_eq!(signer_id, id);
(signer, key)
} else {
let signer = get_account(&state_update, signer_id);
let signer = signer.transpose().and_then(|v| v.ok());
let key_state = get_key_state(
&state_update,
signer_id,
validated_tx.public_key(),
validated_tx.nonce().nonce_index(),
);
let key_state = key_state.transpose().and_then(|v| v.ok());
let inserted = signer_key_state.insert((
signer_id.clone(),
signer.ok_or(Error::InvalidTransactions)?,
key_state.ok_or(Error::InvalidTransactions)?,
validated_tx.public_key().clone(),
));
(&mut inserted.1, &mut inserted.2)
};

let verify_result =
tx_cost(runtime_config, &validated_tx.to_tx(), prev_block.next_gas_price)
Expand All @@ -884,7 +887,7 @@ impl RuntimeAdapter for NightshadeRuntime {
verify_and_charge_tx_ephemeral(
runtime_config,
signer,
access_key,
key_state,
validated_tx.to_tx(),
&cost,
Some(next_block_height),
Expand All @@ -907,9 +910,9 @@ impl RuntimeAdapter for NightshadeRuntime {
}
}

if let Some((signer_id, account, access_key, public_key)) = signer_access_key {
if let Some((signer_id, account, key_state, public_key)) = signer_key_state {
set_account(&mut state_update.trie_update, signer_id.clone(), &account);
set_access_key(&mut state_update.trie_update, signer_id, public_key, &access_key);
set_key_state(&mut state_update.trie_update, signer_id, public_key, &key_state);
}
}

Expand Down
6 changes: 3 additions & 3 deletions chain/chain/src/runtime/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1665,7 +1665,7 @@ fn test_prepare_transactions_duplicate_nonces() {
let group = iter.next().unwrap();
let first_tx = group.peek_next().unwrap();
let duplicate_nonce_tx = SignedTransaction::send_money(
first_tx.nonce(),
first_tx.nonce().nonce(),
first_tx.signer_id().clone(),
first_tx.receiver_id().clone(),
&InMemorySigner::test_signer(&first_tx.signer_id()),
Expand All @@ -1689,12 +1689,12 @@ fn test_prepare_transactions_duplicate_nonces() {
// Collect (public key, nonce) pairs to check for duplicates.
let mut pk_nonce_set = HashSet::new();
for tx in &txs.transactions {
let pk_nonce = (tx.public_key(), tx.nonce());
let pk_nonce = (tx.public_key(), tx.nonce().nonce());
assert!(
pk_nonce_set.insert(pk_nonce),
"Duplicate transaction with public key {:?} and nonce {} found in prepared transactions",
tx.public_key(),
tx.nonce()
tx.nonce().nonce(),
);
}
}
Expand Down
23 changes: 0 additions & 23 deletions chain/chain/src/store/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,19 +702,6 @@ impl ChainStore {
}
changes
}
StateChangesRequest::SingleGasKeyChanges { keys } => {
let mut changes = StateChanges::new();
for key in keys {
let data_key = trie_key_parsers::get_raw_prefix_for_gas_key(
&key.account_id,
&key.public_key,
);
let storage_key = KeyForStateChanges::from_raw_key(block_hash, &data_key);
let changes_per_key_prefix = storage_key.find_iter(&store);
changes.extend(StateChanges::from_gas_key_changes(changes_per_key_prefix)?);
}
changes
}
StateChangesRequest::AllAccessKeyChanges { account_ids } => {
let mut changes = StateChanges::new();
for account_id in account_ids {
Expand All @@ -725,16 +712,6 @@ impl ChainStore {
}
changes
}
StateChangesRequest::AllGasKeyChanges { account_ids } => {
let mut changes = StateChanges::new();
for account_id in account_ids {
let data_key = trie_key_parsers::get_raw_prefix_for_gas_keys(account_id);
let storage_key = KeyForStateChanges::from_raw_key(block_hash, &data_key);
let changes_per_key_prefix = storage_key.find_iter(&store);
changes.extend(StateChanges::from_gas_key_changes(changes_per_key_prefix)?);
}
changes
}
StateChangesRequest::ContractCodeChanges { account_ids } => {
let mut changes = StateChanges::new();
for account_id in account_ids {
Expand Down
22 changes: 12 additions & 10 deletions chain/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,16 +481,18 @@ impl Client {
.to_transactions()
.into_iter()
.cloned()
.filter_map(|signed_tx| match ValidatedTransaction::new(&config, signed_tx) {
Ok(validated_tx) => Some(validated_tx),
Err((err, signed_tx)) => {
tracing::debug!(
target: "client",
?signed_tx,
?err,
"validating signed tx failed with error"
);
None
.filter_map(|signed_tx| {
match ValidatedTransaction::new(&config, signed_tx, protocol_version) {
Ok(validated_tx) => Some(validated_tx),
Err((err, signed_tx)) => {
tracing::debug!(
target: "client",
?signed_tx,
?err,
"validating signed tx failed with error"
);
None
}
}
})
.collect::<Vec<_>>();
Expand Down
40 changes: 27 additions & 13 deletions chain/pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use near_o11y::metrics::prometheus::core::{AtomicI64, GenericGauge};
use near_primitives::epoch_info::RngSeed;
use near_primitives::hash::{CryptoHash, hash};
use near_primitives::transaction::{SignedTransaction, ValidatedTransaction};
use near_primitives::types::AccountId;
use near_primitives::types::{AccountId, NonceIndex};
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, HashMap, HashSet, VecDeque};
use std::ops::Bound;
Expand Down Expand Up @@ -69,10 +69,17 @@ impl TransactionPool {
}
}

fn key(&self, account_id: &AccountId, public_key: &PublicKey) -> PoolKey {
fn key(
&self,
account_id: &AccountId,
public_key: &PublicKey,
nonce_index: Option<NonceIndex>,
) -> PoolKey {
let mut v = borsh::to_vec(&public_key).unwrap();
let nonce_index_encoded = borsh::to_vec(&nonce_index).unwrap();
v.extend_from_slice(&self.key_seed);
v.extend_from_slice(account_id.as_bytes());
v.extend_from_slice(&nonce_index_encoded);
hash(&v)
}

Expand Down Expand Up @@ -109,7 +116,7 @@ impl TransactionPool {
let signer_id = validated_tx.signer_id();
let signer_public_key = validated_tx.public_key();
self.transactions
.entry(self.key(signer_id, signer_public_key))
.entry(self.key(signer_id, signer_public_key, validated_tx.nonce().nonce_index()))
.or_insert_with(Vec::new)
.push(validated_tx);

Expand Down Expand Up @@ -140,7 +147,11 @@ impl TransactionPool {
let signer_id = signed_tx.transaction.signer_id();
let signer_public_key = signed_tx.transaction.public_key();
grouped_transactions
.entry(self.key(signer_id, signer_public_key))
.entry(self.key(
signer_id,
signer_public_key,
signed_tx.transaction.nonce().nonce_index(),
))
.or_insert_with(HashSet::new)
.insert(signed_tx.get_hash());
}
Expand Down Expand Up @@ -233,7 +244,7 @@ impl<'a> TransactionGroupIterator for PoolIteratorWrapper<'a> {
self.pool.last_used_key = key;
let mut validated_txs =
self.pool.transactions.remove(&key).expect("just checked existence");
validated_txs.sort_by_key(|vt| std::cmp::Reverse(vt.nonce()));
validated_txs.sort_by_key(|vt| std::cmp::Reverse(vt.nonce().nonce()));
self.sorted_groups.push_back(TransactionGroup {
key,
transactions: validated_txs,
Expand Down Expand Up @@ -381,7 +392,7 @@ mod tests {
(
prepare_transactions(&mut pool, expected_weight)
.iter()
.map(|tx| tx.transaction.nonce())
.map(|tx| tx.transaction.nonce().nonce())
.collect(),
pool,
)
Expand Down Expand Up @@ -455,8 +466,10 @@ mod tests {
let (mut nonces, mut pool) = process_txs_to_nonces(transactions, 10);
sort_pairs(&mut nonces[..6]);
assert_eq!(nonces, vec![1, 21, 2, 22, 3, 23, 24, 25, 26, 27]);
let nonces: Vec<u64> =
prepare_transactions(&mut pool, 10).iter().map(|tx| tx.transaction.nonce()).collect();
let nonces: Vec<u64> = prepare_transactions(&mut pool, 10)
.iter()
.map(|tx| tx.transaction.nonce().nonce())
.collect();
assert_eq!(nonces, vec![28, 29, 30, 31]);
}

Expand Down Expand Up @@ -502,9 +515,9 @@ mod tests {
assert_eq!(pool.len(), txs_to_check.len());

let mut pool_txs = prepare_transactions(&mut pool, txs_to_check.len() as u32);
pool_txs.sort_by_key(|tx| tx.transaction.nonce());
pool_txs.sort_by_key(|tx| tx.transaction.nonce().nonce());
let mut expected_txs = txs_to_check.to_vec();
expected_txs.sort_by_key(|tx| tx.nonce());
expected_txs.sort_by_key(|tx| tx.nonce().nonce());
let expected_txs =
expected_txs.into_iter().map(|vt| vt.into_signed_tx()).collect::<Vec<_>>();

Expand All @@ -524,7 +537,7 @@ mod tests {
let mut pool_iter = pool.pool_iterator();
while let Some(iter) = pool_iter.next() {
while let Some(tx) = iter.next() {
if tx.nonce() & 1 == 1 {
if tx.nonce().nonce() & 1 == 1 {
res.push(tx);
break;
}
Expand All @@ -533,7 +546,7 @@ mod tests {
drop(pool_iter);
assert_eq!(pool.len(), 0);
assert_eq!(pool.transaction_size(), 0);
let mut nonces: Vec<_> = res.into_iter().map(|tx| tx.nonce()).collect();
let mut nonces: Vec<_> = res.into_iter().map(|tx| tx.nonce().nonce()).collect();
sort_pairs(&mut nonces[..4]);
assert_eq!(nonces, vec![1, 21, 3, 23, 25, 27, 29, 31]);
}
Expand Down Expand Up @@ -592,7 +605,8 @@ mod tests {
let txs = prepare_transactions(&mut pool, 5);
assert_eq!(txs.len(), 5);
nonces.sort();
let mut new_nonces = txs.iter().map(|tx| tx.transaction.nonce()).collect::<Vec<_>>();
let mut new_nonces =
txs.iter().map(|tx| tx.transaction.nonce().nonce()).collect::<Vec<_>>();
new_nonces.sort();
assert_ne!(nonces, new_nonces);
}
Expand Down
3 changes: 2 additions & 1 deletion chain/rosetta-rpc/src/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,8 @@ impl From<NearActions> for Vec<crate::models::Operation> {
}
near_primitives::action::Action::AddGasKey(_)
| near_primitives::action::Action::DeleteGasKey(_)
| near_primitives::action::Action::TransferToGasKey(_) => {
| near_primitives::action::Action::TransferToGasKey(_)
| near_primitives::action::Action::TransferFromGasKey(_) => {
// TODO(gas-keys): Implement rosetta adapter, ignored for now.
}
}
Expand Down
Loading
Loading