Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(runtime): use correct random value for random seed #3096

Merged
merged 5 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions chain/chain/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,7 @@ impl<'a> ChainUpdate<'a> {
prev_block.header().gas_price(),
prev_chunk.header.inner.gas_limit,
&challenges_result,
*block.header().random_value(),
true,
)
.unwrap();
Expand Down Expand Up @@ -2737,6 +2738,7 @@ impl<'a> ChainUpdate<'a> {
prev_block.header().gas_price(),
chunk.header.inner.gas_limit,
&block.header().challenges_result(),
*block.header().random_value(),
)
.map_err(|e| ErrorKind::Other(e.to_string()))?;

Expand Down Expand Up @@ -2802,6 +2804,7 @@ impl<'a> ChainUpdate<'a> {
block.header().gas_price(),
new_extra.gas_limit,
&block.header().challenges_result(),
*block.header().random_value(),
)
.map_err(|e| ErrorKind::Other(e.to_string()))?;

Expand Down Expand Up @@ -3398,6 +3401,7 @@ impl<'a> ChainUpdate<'a> {
block_header.gas_price(),
chunk.header.inner.gas_limit,
&block_header.challenges_result(),
*block_header.random_value(),
)?;

let (outcome_root, outcome_proofs) =
Expand Down Expand Up @@ -3479,6 +3483,7 @@ impl<'a> ChainUpdate<'a> {
block_header.gas_price(),
chunk_extra.gas_limit,
&block_header.challenges_result(),
*block_header.random_value(),
)?;

self.chain_store_update.save_trie_changes(apply_result.trie_changes);
Expand Down
2 changes: 2 additions & 0 deletions chain/chain/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ impl RuntimeAdapter for KeyValueRuntime {
gas_price: Balance,
_gas_limit: Gas,
_challenges: &ChallengesResult,
_random_seed: CryptoHash,
generate_storage_proof: bool,
) -> Result<ApplyTransactionResult, Error> {
assert!(!generate_storage_proof);
Expand Down Expand Up @@ -677,6 +678,7 @@ impl RuntimeAdapter for KeyValueRuntime {
_gas_price: Balance,
_gas_limit: Gas,
_challenges: &ChallengesResult,
_random_value: CryptoHash,
) -> Result<ApplyTransactionResult, Error> {
unimplemented!();
}
Expand Down
4 changes: 4 additions & 0 deletions chain/chain/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ pub trait RuntimeAdapter: Send + Sync {
gas_price: Balance,
gas_limit: Gas,
challenges_result: &ChallengesResult,
random_seed: CryptoHash,
) -> Result<ApplyTransactionResult, Error> {
self.apply_transactions_with_optional_storage_proof(
shard_id,
Expand All @@ -450,6 +451,7 @@ pub trait RuntimeAdapter: Send + Sync {
gas_price,
gas_limit,
challenges_result,
random_seed,
false,
)
}
Expand All @@ -468,6 +470,7 @@ pub trait RuntimeAdapter: Send + Sync {
gas_price: Balance,
gas_limit: Gas,
challenges_result: &ChallengesResult,
random_seed: CryptoHash,
generate_storage_proof: bool,
) -> Result<ApplyTransactionResult, Error>;

Expand All @@ -486,6 +489,7 @@ pub trait RuntimeAdapter: Send + Sync {
gas_price: Balance,
gas_limit: Gas,
challenges_result: &ChallengesResult,
random_value: CryptoHash,
) -> Result<ApplyTransactionResult, Error>;

/// Query runtime with given `path` and `data`.
Expand Down
1 change: 1 addition & 0 deletions chain/chain/src/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ fn validate_chunk_state_challenge(
prev_block_header.gas_price(),
chunk_state.prev_chunk.header.inner.gas_limit,
&ChallengesResult::default(),
*block_header.random_value(),
)
.map_err(|_| Error::from(ErrorKind::MaliciousChallenge))?;
let outcome_root = ApplyTransactionResult::compute_outcomes_proof(&result.outcomes).0;
Expand Down
4 changes: 3 additions & 1 deletion core/primitives/src/version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub const DB_VERSION: DbVersion = 5;
pub type ProtocolVersion = u32;

/// Current latest version of the protocol.
pub const PROTOCOL_VERSION: ProtocolVersion = 32;
pub const PROTOCOL_VERSION: ProtocolVersion = 33;

pub const FIRST_BACKWARD_COMPATIBLE_PROTOCOL_VERSION: ProtocolVersion = 29;

Expand All @@ -29,3 +29,5 @@ pub const MIN_PROTOCOL_VERSION_NEP_92: ProtocolVersion = 31;
/// Minimum gas price proposed in NEP 92 (fixed) and the associated protocol version
pub const MIN_GAS_PRICE_NEP_92_FIX: Balance = 100_000_000;
pub const MIN_PROTOCOL_VERSION_NEP_92_FIX: ProtocolVersion = 32;

pub const CORRECT_RANDOM_VALUE_PROTOCOL_VERSION: ProtocolVersion = 33;
2 changes: 1 addition & 1 deletion neard/res/genesis_config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"protocol_version": 32,
"protocol_version": 33,
"genesis_time": "1970-01-01T00:00:00.000000000Z",
"chain_id": "sample",
"genesis_height": 0,
Expand Down
9 changes: 9 additions & 0 deletions neard/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ impl NightshadeRuntime {
gas_price: Balance,
gas_limit: Gas,
challenges_result: &ChallengesResult,
random_seed: CryptoHash,
) -> Result<ApplyTransactionResult, Error> {
let validator_accounts_update = {
let mut epoch_manager = self.epoch_manager.as_ref().write().expect(POISONED_LOCK_ERR);
Expand Down Expand Up @@ -394,6 +395,7 @@ impl NightshadeRuntime {

let epoch_height = self.get_epoch_height_from_prev_block(prev_block_hash)?;
let epoch_id = self.get_epoch_id_from_prev_block(prev_block_hash)?;
let current_protocol_version = self.get_epoch_protocol_version(&epoch_id)?;

let apply_state = ApplyState {
block_index: block_height,
Expand All @@ -403,6 +405,8 @@ impl NightshadeRuntime {
gas_price,
block_timestamp,
gas_limit: Some(gas_limit),
random_seed,
current_protocol_version,
};

let apply_result = self
Expand Down Expand Up @@ -949,6 +953,7 @@ impl RuntimeAdapter for NightshadeRuntime {
gas_price: Balance,
gas_limit: Gas,
challenges: &ChallengesResult,
random_seed: CryptoHash,
generate_storage_proof: bool,
) -> Result<ApplyTransactionResult, Error> {
let trie = self.get_trie_for_shard(shard_id);
Expand All @@ -967,6 +972,7 @@ impl RuntimeAdapter for NightshadeRuntime {
gas_price,
gas_limit,
challenges,
random_seed,
) {
Ok(result) => Ok(result),
Err(e) => match e.kind() {
Expand All @@ -993,6 +999,7 @@ impl RuntimeAdapter for NightshadeRuntime {
gas_price: Balance,
gas_limit: Gas,
challenges: &ChallengesResult,
random_value: CryptoHash,
) -> Result<ApplyTransactionResult, Error> {
let trie = Trie::from_recorded_storage(partial_storage);
self.process_state_update(
Expand All @@ -1009,6 +1016,7 @@ impl RuntimeAdapter for NightshadeRuntime {
gas_price,
gas_limit,
challenges,
random_value,
)
}

Expand Down Expand Up @@ -1414,6 +1422,7 @@ mod test {
gas_price,
gas_limit,
challenges,
CryptoHash::default(),
)
.unwrap();
let mut store_update = self.store.store_update();
Expand Down
26 changes: 21 additions & 5 deletions pytest/tests/sanity/upgradable.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

import branches
import cluster
from utils import wait_for_blocks_or_timeout
from transaction import sign_payment_tx
from utils import wait_for_blocks_or_timeout, load_binary_file
from transaction import sign_deploy_contract_tx, sign_function_call_tx


def main():
Expand Down Expand Up @@ -64,10 +64,20 @@ def main():

time.sleep(2)

# send a transaction to make sure that the execution result is consistent across nodes.
# deploy a contract
status = nodes[0].get_status()
tx = sign_payment_tx(nodes[0].signer_key, 'test1', 100, 1,
base58.b58decode(status['sync_info']['latest_block_hash'].encode('utf8')))
hash = status['sync_info']['latest_block_hash']
tx = sign_deploy_contract_tx(
nodes[0].signer_key,
load_binary_file(
'../runtime/near-vm-runner/tests/res/test_contract_rs.wasm'), 1, base58.b58decode(hash.encode('utf8')))
res = nodes[0].send_tx_and_wait(tx, timeout=20)
assert 'error' not in res, res

# write some random value
tx = sign_function_call_tx(nodes[0].signer_key, nodes[0].signer_key.account_id,
'write_random_value', [], 100000000000, 0, 2,
base58.b58decode(hash.encode('utf8')))
res = nodes[0].send_tx_and_wait(tx, timeout=20)
assert 'error' not in res, res

Expand All @@ -92,6 +102,12 @@ def main():
assert gas_price < 1000000000, gas_price
assert gas_price > 100000000, gas_price

# write some random value again
tx = sign_function_call_tx(nodes[0].signer_key, nodes[0].signer_key.account_id,
'write_random_value', [], 100000000000, 0, 3,
base58.b58decode(hash.encode('utf8')))
res = nodes[0].send_tx_and_wait(tx, timeout=20)
assert 'error' not in res, res

if __name__ == "__main__":
main()
Binary file modified runtime/near-vm-runner/tests/res/test_contract_rs.wasm
Binary file not shown.
9 changes: 9 additions & 0 deletions runtime/near-vm-runner/tests/test-contract-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ pub unsafe fn write_block_height() {
storage_write(key.len() as _, key.as_ptr() as _, value.len() as _, value.as_ptr() as _, 0);
}

#[no_mangle]
pub unsafe fn write_random_value() {
random_seed(0);
let data = [0u8; 32];
read_register(0, data.as_ptr() as u64);
let value = b"hello";
storage_write(data.len() as _, data.as_ptr() as _, value.len() as _, value.as_ptr() as _, 1);
}

#[no_mangle]
pub unsafe fn read_value() {
input(0);
Expand Down
2 changes: 1 addition & 1 deletion runtime/near-vm-runner/tests/test_rs_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def_test_ext!(ext_block_index, b"ext_block_index", &10u64.to_le_bytes());
def_test_ext!(ext_block_timestamp, b"ext_block_timestamp", &42u64.to_le_bytes());
def_test_ext!(ext_storage_usage, b"ext_storage_usage", &12u64.to_le_bytes());
// TODO: mock used_gas
def_test_ext!(ext_used_gas, b"ext_used_gas", &[184, 50, 70, 79, 4, 0, 0, 0]);
def_test_ext!(ext_used_gas, b"ext_used_gas", &[132, 156, 14, 81, 4, 0, 0, 0]);
def_test_ext!(
ext_sha256,
b"ext_sha256",
Expand Down
2 changes: 2 additions & 0 deletions runtime/runtime-params-estimator/src/testbed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ impl RuntimeTestbed {
gas_price: 0,
block_timestamp: 0,
gas_limit: None,
random_seed: Default::default(),
current_protocol_version: 0,
};
Self {
workdir,
Expand Down
2 changes: 2 additions & 0 deletions runtime/runtime-standalone/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,10 @@ impl RuntimeStandalone {
block_timestamp: self.cur_block.block_timestamp,
gas_limit: None,
// not used
random_seed: Default::default(),
last_block_hash: CryptoHash::default(),
epoch_id: EpochId::default(),
current_protocol_version: 0,
};

let apply_result = self.runtime.apply(
Expand Down
8 changes: 7 additions & 1 deletion runtime/runtime/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::ext::RuntimeExt;
use crate::{ActionResult, ApplyState};
use near_crypto::PublicKey;
use near_primitives::errors::{ActionError, ActionErrorKind, ExternalError, RuntimeError};
use near_primitives::version::CORRECT_RANDOM_VALUE_PROTOCOL_VERSION;
use near_runtime_configs::AccountCreationConfig;
use near_vm_errors::{CompilationError, FunctionCallError};
use near_vm_runner::VMError;
Expand Down Expand Up @@ -144,7 +145,12 @@ pub(crate) fn action_function_call(
storage_usage: account.storage_usage,
attached_deposit: function_call.deposit,
prepaid_gas: function_call.gas,
random_seed: action_hash.as_ref().to_vec(),
random_seed: if apply_state.current_protocol_version < CORRECT_RANDOM_VALUE_PROTOCOL_VERSION
{
action_hash.as_ref().to_vec()
} else {
apply_state.random_seed.as_ref().to_vec()
bowenwang1996 marked this conversation as resolved.
Show resolved Hide resolved
},
is_view: false,
output_data_receivers,
};
Expand Down
13 changes: 10 additions & 3 deletions runtime/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::config::{
};
use crate::verifier::validate_receipt;
pub use crate::verifier::{validate_transaction, verify_and_charge_transaction};
use near_primitives::version::ProtocolVersion;
use std::rc::Rc;

mod actions;
Expand Down Expand Up @@ -70,6 +71,10 @@ pub struct ApplyState {
/// Gas limit for a given chunk.
/// If None is given, assumes there is no gas limit.
pub gas_limit: Option<Gas>,
/// Current random seed (from current block vrf output).
pub random_seed: CryptoHash,
/// Current Protocol version when we apply the state transition
pub current_protocol_version: ProtocolVersion,
}

/// Contains information to update validators accounts at the first block of a new epoch.
Expand Down Expand Up @@ -284,7 +289,7 @@ impl Runtime {
receipt: &Receipt,
action_receipt: &ActionReceipt,
promise_results: &[PromiseResult],
action_hash: CryptoHash,
action_hash: &CryptoHash,
is_last_action: bool,
epoch_info_provider: &dyn EpochInfoProvider,
) -> Result<ActionResult, RuntimeError> {
Expand Down Expand Up @@ -337,7 +342,7 @@ impl Runtime {
&mut result,
account_id,
function_call,
&action_hash,
action_hash,
&self.config,
is_last_action,
epoch_info_provider,
Expand Down Expand Up @@ -469,7 +474,7 @@ impl Runtime {
receipt,
action_receipt,
&promise_results,
create_nonce_with_nonce(
&create_nonce_with_nonce(
&receipt.receipt_id,
u64::max_value() - action_index as u64,
),
Expand Down Expand Up @@ -1448,6 +1453,8 @@ mod tests {
gas_price: GAS_PRICE,
block_timestamp: 100,
gas_limit: Some(gas_limit),
random_seed: Default::default(),
current_protocol_version: 0,
};

(runtime, tries, root, apply_state, signer, MockEpochInfoProvider::default())
Expand Down
2 changes: 2 additions & 0 deletions runtime/runtime/tests/runtime_group_tools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ impl StandaloneRuntime {
gas_price: 100,
block_timestamp: 0,
gas_limit: None,
random_seed: Default::default(),
current_protocol_version: 0,
};

Self {
Expand Down
1 change: 1 addition & 0 deletions test-utils/state-viewer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ fn apply_block_at_height(
prev_block.header().gas_price(),
chunk.header.inner.gas_limit,
&block.header().challenges_result(),
*block.header().random_value(),
)
.unwrap();
let (outcome_root, _) = ApplyTransactionResult::compute_outcomes_proof(&apply_result.outcomes);
Expand Down
2 changes: 2 additions & 0 deletions test-utils/testlib/src/user/runtime_user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ impl RuntimeUser {
epoch_height: 0,
gas_price: MIN_GAS_PRICE,
gas_limit: None,
random_seed: Default::default(),
epoch_id: Default::default(),
current_protocol_version: 0,
}
}

Expand Down