Skip to content

Commit

Permalink
Add tests for beacon randomness precompile.
Browse files Browse the repository at this point in the history
  • Loading branch information
anorth committed Aug 27, 2024
1 parent 3bb132e commit a68e990
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 15 deletions.
1 change: 0 additions & 1 deletion actors/evm/src/interpreter/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ impl<RT: Runtime> Precompiles<RT> {
None, // 0xfe00..04 get_actor_type DISABLED
Some(call_actor_id::<RT>), // 0xfe00..05
Some(get_randomness::<RT>), // 0xfe00..06

]);

/// EVM specific precompiles
Expand Down
38 changes: 38 additions & 0 deletions actors/evm/tests/precompile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,44 @@ fn test_resolve_delegated() {
rt.reset();
}

#[test]
fn test_precompile_randomness() {
let (init, body) = PrecompileTest::test_runner_assembly();
let rt =
util::construct_and_verify(asm::new_contract("precompile-tester", &init, &body).unwrap());
let rand_epoch = 100;
let rand_epoch_u256 = U256::from(rand_epoch);
{
// Underlying syscall succeeds.
let result = U256::from(0xdeadbeefu32).to_bytes();
let test = PrecompileTest {
precompile_address: NativePrecompile::GetRandomness.eth_address(),
output_size: 32,
expected_exit_code: PrecompileExit::Success,
gas_avaliable: 10_000_000_000,
call_op: util::PrecompileCallOpcode::StaticCall,
input: rand_epoch_u256.to_bytes().to_vec(),
expected_return: result.to_vec(),
};
rt.expect_get_beacon_randomness(rand_epoch, result, ExitCode::OK);
test.run_test(&rt);
}
{
// Underlying syscall fails.
let test = PrecompileTest {
precompile_address: NativePrecompile::GetRandomness.eth_address(),
output_size: 32,
expected_exit_code: PrecompileExit::Reverted, // Precompile reverts due to syscall failure
gas_avaliable: 10_000_000_000,
call_op: util::PrecompileCallOpcode::StaticCall,
input: rand_epoch_u256.to_bytes().to_vec(),
expected_return: vec![],
};
rt.expect_get_beacon_randomness(rand_epoch, [0u8; 32], ExitCode::USR_ILLEGAL_ARGUMENT);
test.run_test(&rt);
}
}

#[test]
fn test_precompile_transfer() {
let (init, body) = util::PrecompileTest::test_runner_assembly();
Expand Down
3 changes: 2 additions & 1 deletion actors/evm/tests/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ pub enum NativePrecompile {
ResolveAddress = 1,
LookupDelegatedAddress = 2,
CallActor = 3,
GetActorType = 4,
GetActorTypeDISABLED = 4,
CallActorId = 5,
GetRandomness = 6,
}

#[allow(dead_code)]
Expand Down
8 changes: 4 additions & 4 deletions runtime/src/runtime/fvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,8 @@ where
) -> Result<[u8; RANDOMNESS_LENGTH], ActorError> {
let digest = fvm::rand::get_chain_randomness(rand_epoch).map_err(|e| {
match e {
ErrorNumber::LimitExceeded => {
actor_error!(illegal_argument; "randomness lookback exceeded: {}", e)
ErrorNumber::LimitExceeded | ErrorNumber::IllegalArgument => {
actor_error!(illegal_argument; "invalid lookback epoch: {}", e)
}
e => actor_error!(assertion_failed; "get chain randomness failed with an unexpected error: {}", e),
}
Expand Down Expand Up @@ -271,8 +271,8 @@ where
) -> Result<[u8; RANDOMNESS_LENGTH], ActorError> {
fvm::rand::get_beacon_randomness(rand_epoch).map_err(|e| {
match e {
ErrorNumber::LimitExceeded => {
actor_error!(illegal_argument; "randomness lookback exceeded: {}", e)
ErrorNumber::LimitExceeded | ErrorNumber::IllegalArgument => {
actor_error!(illegal_argument; "invalid lookback epoch: {}", e)
}
e => actor_error!(assertion_failed; "get beacon randomness failed with an unexpected error: {}", e),
}
Expand Down
24 changes: 15 additions & 9 deletions runtime/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,7 @@ pub struct ExpectRandomness {
pub struct ExpectGetBeacon {
epoch: ChainEpoch,
out: [u8; RANDOMNESS_LENGTH],
exit_code: ExitCode,
}

#[derive(Debug)]
Expand Down Expand Up @@ -761,8 +762,13 @@ impl MockRuntime {
}

#[allow(dead_code)]
pub fn expect_get_beacon_randomness(&self, epoch: ChainEpoch, out: [u8; RANDOMNESS_LENGTH]) {
let a = ExpectGetBeacon { epoch, out };
pub fn expect_get_beacon_randomness(
&self,
epoch: ChainEpoch,
out: [u8; RANDOMNESS_LENGTH],
exit_code: ExitCode,
) {
let a = ExpectGetBeacon { epoch, out, exit_code };
self.expectations.borrow_mut().expect_get_beacon_randomness.push_back(a);
}

Expand Down Expand Up @@ -1035,7 +1041,6 @@ impl Runtime for MockRuntime {
.pop_front()
.expect("unexpected call to get_randomness_from_tickets");

assert!(epoch <= *self.epoch.borrow(), "attempt to get randomness from future");
assert_eq!(
expected.tag, tag,
"unexpected domain separation tag, expected: {:?}, actual: {:?}",
Expand Down Expand Up @@ -1068,7 +1073,6 @@ impl Runtime for MockRuntime {
.pop_front()
.expect("unexpected call to get_randomness_from_beacon");

assert!(epoch <= *self.epoch.borrow(), "attempt to get randomness from future");
assert_eq!(
expected.tag, tag,
"unexpected domain separation tag, expected: {:?}, actual: {:?}",
Expand All @@ -1092,20 +1096,22 @@ impl Runtime for MockRuntime {
&self,
epoch: ChainEpoch,
) -> Result<[u8; RANDOMNESS_LENGTH], ActorError> {
let expected = self
let exp = self
.expectations
.borrow_mut()
.expect_get_beacon_randomness
.pop_front()
.expect("unexpected call to get_randomness_from_beacon");

assert!(epoch <= *self.epoch.borrow(), "attempt to get randomness from future");
assert_eq!(
expected.epoch, epoch,
exp.epoch, epoch,
"unexpected epoch, expected: {:?}, actual: {:?}",
expected.epoch, epoch
exp.epoch, epoch
);
Ok(expected.out)
if exp.exit_code != ExitCode::OK {
return Err(ActorError::unchecked(exp.exit_code, "Expected Failure".to_string()));
}
Ok(exp.out)
}

fn create<T: Serialize>(&self, obj: &T) -> Result<(), ActorError> {
Expand Down

0 comments on commit a68e990

Please sign in to comment.