mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-22 18:27:58 +00:00
Add a common crate (#75)
* Add a barebones common crate * Refactor some code into the common crate * Add a `ResolverApi` interface. This commit adds a `ResolverApi` trait to the `format` crate that can be implemented by any type that can act as a resolver. A resolver is able to provide information on the chain state. This chain state could be fresh or it could be cached (which is something that we will do in a future PR). This cleans up our crate graph so that `format` is not depending on the node interactions crate for the `EthereumNode` trait. * Cleanup the blocking executor
This commit is contained in:
+29
-60
@@ -11,9 +11,10 @@ use alloy_primitives::{FixedBytes, utils::parse_units};
|
||||
use semver::VersionReq;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
use revive_dt_common::macros::define_wrapper_type;
|
||||
|
||||
use crate::{define_wrapper_type, metadata::ContractInstance};
|
||||
use crate::metadata::ContractInstance;
|
||||
use crate::traits::ResolverApi;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
||||
pub struct Input {
|
||||
@@ -84,7 +85,7 @@ pub enum Method {
|
||||
|
||||
define_wrapper_type!(
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
EtherValue(U256);
|
||||
pub struct EtherValue(U256);
|
||||
);
|
||||
|
||||
impl Serialize for EtherValue {
|
||||
@@ -154,7 +155,7 @@ impl Calldata {
|
||||
pub fn calldata(
|
||||
&self,
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<Vec<u8>> {
|
||||
let mut buffer = Vec::<u8>::with_capacity(self.size_requirement());
|
||||
self.calldata_into_slice(&mut buffer, deployed_contracts, chain_state_provider)?;
|
||||
@@ -165,7 +166,7 @@ impl Calldata {
|
||||
&self,
|
||||
buffer: &mut Vec<u8>,
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<()> {
|
||||
match self {
|
||||
Calldata::Single(bytes) => {
|
||||
@@ -200,7 +201,7 @@ impl Calldata {
|
||||
&self,
|
||||
other: &[u8],
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<bool> {
|
||||
match self {
|
||||
Calldata::Single(calldata) => Ok(calldata == other),
|
||||
@@ -249,7 +250,7 @@ impl Input {
|
||||
pub fn encoded_input(
|
||||
&self,
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<Bytes> {
|
||||
match self.method {
|
||||
Method::Deployer | Method::Fallback => {
|
||||
@@ -316,7 +317,7 @@ impl Input {
|
||||
pub fn legacy_transaction(
|
||||
&self,
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<TransactionRequest> {
|
||||
let input_data = self.encoded_input(deployed_contracts, chain_state_provider)?;
|
||||
let transaction_request = TransactionRequest::default().from(self.caller).value(
|
||||
@@ -363,7 +364,7 @@ pub const fn default_caller() -> Address {
|
||||
fn resolve_argument(
|
||||
value: &str,
|
||||
deployed_contracts: &HashMap<ContractInstance, (Address, JsonAbi)>,
|
||||
chain_state_provider: &impl EthereumNode,
|
||||
chain_state_provider: &impl ResolverApi,
|
||||
) -> anyhow::Result<U256> {
|
||||
if let Some(instance) = value.strip_suffix(".address") {
|
||||
Ok(U256::from_be_slice(
|
||||
@@ -432,31 +433,9 @@ mod tests {
|
||||
use alloy_sol_types::SolValue;
|
||||
use std::collections::HashMap;
|
||||
|
||||
struct DummyEthereumNode;
|
||||
|
||||
impl EthereumNode for DummyEthereumNode {
|
||||
fn execute_transaction(
|
||||
&self,
|
||||
_: TransactionRequest,
|
||||
) -> anyhow::Result<alloy::rpc::types::TransactionReceipt> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn trace_transaction(
|
||||
&self,
|
||||
_: &alloy::rpc::types::TransactionReceipt,
|
||||
_: alloy::rpc::types::trace::geth::GethDebugTracingOptions,
|
||||
) -> anyhow::Result<alloy::rpc::types::trace::geth::GethTrace> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn state_diff(
|
||||
&self,
|
||||
_: &alloy::rpc::types::TransactionReceipt,
|
||||
) -> anyhow::Result<alloy::rpc::types::trace::geth::DiffMode> {
|
||||
unimplemented!()
|
||||
}
|
||||
struct MockResolver;
|
||||
|
||||
impl ResolverApi for MockResolver {
|
||||
fn chain_id(&self) -> anyhow::Result<alloy_primitives::ChainId> {
|
||||
Ok(0x123)
|
||||
}
|
||||
@@ -528,7 +507,7 @@ mod tests {
|
||||
(Address::ZERO, parsed_abi),
|
||||
);
|
||||
|
||||
let encoded = input.encoded_input(&contracts, &DummyEthereumNode).unwrap();
|
||||
let encoded = input.encoded_input(&contracts, &MockResolver).unwrap();
|
||||
assert!(encoded.0.starts_with(&selector));
|
||||
|
||||
type T = (u64,);
|
||||
@@ -572,7 +551,7 @@ mod tests {
|
||||
(Address::ZERO, parsed_abi),
|
||||
);
|
||||
|
||||
let encoded = input.encoded_input(&contracts, &DummyEthereumNode).unwrap();
|
||||
let encoded = input.encoded_input(&contracts, &MockResolver).unwrap();
|
||||
assert!(encoded.0.starts_with(&selector));
|
||||
|
||||
type T = (alloy_primitives::Address,);
|
||||
@@ -619,7 +598,7 @@ mod tests {
|
||||
(Address::ZERO, parsed_abi),
|
||||
);
|
||||
|
||||
let encoded = input.encoded_input(&contracts, &DummyEthereumNode).unwrap();
|
||||
let encoded = input.encoded_input(&contracts, &MockResolver).unwrap();
|
||||
assert!(encoded.0.starts_with(&selector));
|
||||
|
||||
type T = (alloy_primitives::Address,);
|
||||
@@ -636,11 +615,11 @@ mod tests {
|
||||
let input = "$CHAIN_ID";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(resolved, U256::from(DummyEthereumNode.chain_id().unwrap()))
|
||||
assert_eq!(resolved, U256::from(MockResolver.chain_id().unwrap()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -649,17 +628,13 @@ mod tests {
|
||||
let input = "$GAS_LIMIT";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
U256::from(
|
||||
DummyEthereumNode
|
||||
.block_gas_limit(Default::default())
|
||||
.unwrap()
|
||||
)
|
||||
U256::from(MockResolver.block_gas_limit(Default::default()).unwrap())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -669,14 +644,14 @@ mod tests {
|
||||
let input = "$COINBASE";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
U256::from_be_slice(
|
||||
DummyEthereumNode
|
||||
MockResolver
|
||||
.block_coinbase(Default::default())
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
@@ -690,15 +665,13 @@ mod tests {
|
||||
let input = "$DIFFICULTY";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
DummyEthereumNode
|
||||
.block_difficulty(Default::default())
|
||||
.unwrap()
|
||||
MockResolver.block_difficulty(Default::default()).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -708,13 +681,13 @@ mod tests {
|
||||
let input = "$BLOCK_HASH";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
U256::from_be_bytes(DummyEthereumNode.block_hash(Default::default()).unwrap().0)
|
||||
U256::from_be_bytes(MockResolver.block_hash(Default::default()).unwrap().0)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -724,13 +697,13 @@ mod tests {
|
||||
let input = "$BLOCK_NUMBER";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
U256::from(DummyEthereumNode.last_block_number().unwrap())
|
||||
U256::from(MockResolver.last_block_number().unwrap())
|
||||
)
|
||||
}
|
||||
|
||||
@@ -740,17 +713,13 @@ mod tests {
|
||||
let input = "$BLOCK_TIMESTAMP";
|
||||
|
||||
// Act
|
||||
let resolved = resolve_argument(input, &Default::default(), &DummyEthereumNode);
|
||||
let resolved = resolve_argument(input, &Default::default(), &MockResolver);
|
||||
|
||||
// Assert
|
||||
let resolved = resolved.expect("Failed to resolve argument");
|
||||
assert_eq!(
|
||||
resolved,
|
||||
U256::from(
|
||||
DummyEthereumNode
|
||||
.block_timestamp(Default::default())
|
||||
.unwrap()
|
||||
)
|
||||
U256::from(MockResolver.block_timestamp(Default::default()).unwrap())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user