mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-13 22:11:04 +00:00
Groundwork for dyn traits
This commit is contained in:
Generated
+1
@@ -4584,6 +4584,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"alloy",
|
"alloy",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"revive-dt-format",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -564,3 +564,34 @@ pub enum TestingPlatform {
|
|||||||
/// The kitchensink runtime provides the PolkaVM (PVM) based node implementation.
|
/// The kitchensink runtime provides the PolkaVM (PVM) based node implementation.
|
||||||
Kitchensink,
|
Kitchensink,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An enum of the platform identifiers of all of the platforms supported by this framework.
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Copy,
|
||||||
|
Debug,
|
||||||
|
PartialEq,
|
||||||
|
Eq,
|
||||||
|
PartialOrd,
|
||||||
|
Ord,
|
||||||
|
Hash,
|
||||||
|
Serialize,
|
||||||
|
ValueEnum,
|
||||||
|
EnumString,
|
||||||
|
Display,
|
||||||
|
AsRefStr,
|
||||||
|
IntoStaticStr,
|
||||||
|
)]
|
||||||
|
#[strum(serialize_all = "kebab-case")]
|
||||||
|
pub enum PlatformIdentifier {
|
||||||
|
/// The Go-ethereum reference full node EVM implementation.
|
||||||
|
GethEvm,
|
||||||
|
/// The kitchensink node with the PolkaVM backend.
|
||||||
|
KitchensinkPolkaVM,
|
||||||
|
/// The kitchensink node with the REVM backend.
|
||||||
|
KitchensinkREVM,
|
||||||
|
/// The revive dev node with the PolkaVM backend.
|
||||||
|
ReviveDevNodePolkaVM,
|
||||||
|
/// The revive dev node with the REVM backend.
|
||||||
|
ReviveDevNodeREVM,
|
||||||
|
}
|
||||||
|
|||||||
+11
-1
@@ -4,7 +4,7 @@
|
|||||||
//! provides a helper utility to execute tests.
|
//! provides a helper utility to execute tests.
|
||||||
|
|
||||||
use revive_dt_compiler::{SolidityCompiler, revive_resolc, solc};
|
use revive_dt_compiler::{SolidityCompiler, revive_resolc, solc};
|
||||||
use revive_dt_config::TestingPlatform;
|
use revive_dt_config::{PlatformIdentifier, TestingPlatform};
|
||||||
use revive_dt_format::traits::ResolverApi;
|
use revive_dt_format::traits::ResolverApi;
|
||||||
use revive_dt_node::{Node, geth, kitchensink::KitchensinkNode};
|
use revive_dt_node::{Node, geth, kitchensink::KitchensinkNode};
|
||||||
use revive_dt_node_interaction::EthereumNode;
|
use revive_dt_node_interaction::EthereumNode;
|
||||||
@@ -45,3 +45,13 @@ impl Platform for Kitchensink {
|
|||||||
&TestingPlatform::Kitchensink
|
&TestingPlatform::Kitchensink
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait that describes the interface for the platforms that are supported by the tool.
|
||||||
|
pub trait DynPlatform {
|
||||||
|
/// Returns the identifier of this platform.
|
||||||
|
fn platform_identifier(&self) -> PlatformIdentifier;
|
||||||
|
|
||||||
|
/// Creates a new node for the platform by spawning a new thread, creating the node object,
|
||||||
|
/// initializing it, spawning it, and waiting for it to start up.
|
||||||
|
fn new_node(&self) -> Box<dyn PlatformNode>;
|
||||||
|
}
|
||||||
|
|||||||
+43
-20
@@ -695,7 +695,7 @@ impl<T: AsRef<str>> CalldataToken<T> {
|
|||||||
context
|
context
|
||||||
.transaction_hash()
|
.transaction_hash()
|
||||||
.context("No transaction hash provided to get the transaction gas price")
|
.context("No transaction hash provided to get the transaction gas price")
|
||||||
.map(|tx_hash| resolver.transaction_gas_price(tx_hash))?
|
.map(|tx_hash| resolver.transaction_gas_price(*tx_hash))?
|
||||||
.await
|
.await
|
||||||
.map(U256::from)
|
.map(U256::from)
|
||||||
} else if item == Self::GAS_LIMIT_VARIABLE {
|
} else if item == Self::GAS_LIMIT_VARIABLE {
|
||||||
@@ -799,7 +799,7 @@ mod tests {
|
|||||||
use alloy::{eips::BlockNumberOrTag, json_abi::JsonAbi};
|
use alloy::{eips::BlockNumberOrTag, json_abi::JsonAbi};
|
||||||
use alloy_primitives::{BlockHash, BlockNumber, BlockTimestamp, ChainId, TxHash, address};
|
use alloy_primitives::{BlockHash, BlockNumber, BlockTimestamp, ChainId, TxHash, address};
|
||||||
use alloy_sol_types::SolValue;
|
use alloy_sol_types::SolValue;
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, pin::Pin};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::metadata::ContractIdent;
|
use crate::metadata::ContractIdent;
|
||||||
@@ -807,40 +807,63 @@ mod tests {
|
|||||||
struct MockResolver;
|
struct MockResolver;
|
||||||
|
|
||||||
impl ResolverApi for MockResolver {
|
impl ResolverApi for MockResolver {
|
||||||
async fn chain_id(&self) -> anyhow::Result<ChainId> {
|
fn chain_id(&self) -> Pin<Box<dyn Future<Output = anyhow::Result<ChainId>> + '_>> {
|
||||||
Ok(0x123)
|
Box::pin(async move { Ok(0x123) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_gas_limit(&self, _: BlockNumberOrTag) -> anyhow::Result<u128> {
|
fn block_gas_limit(
|
||||||
Ok(0x1234)
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(0x1234) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_coinbase(&self, _: BlockNumberOrTag) -> anyhow::Result<Address> {
|
fn block_coinbase(
|
||||||
Ok(Address::ZERO)
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<Address>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(Address::ZERO) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_difficulty(&self, _: BlockNumberOrTag) -> anyhow::Result<U256> {
|
fn block_difficulty(
|
||||||
Ok(U256::from(0x12345u128))
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<U256>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(U256::from(0x12345u128)) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_base_fee(&self, _: BlockNumberOrTag) -> anyhow::Result<u64> {
|
fn block_base_fee(
|
||||||
Ok(0x100)
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u64>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(0x100) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_hash(&self, _: BlockNumberOrTag) -> anyhow::Result<BlockHash> {
|
fn block_hash(
|
||||||
Ok([0xEE; 32].into())
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockHash>> + '_>> {
|
||||||
|
Box::pin(async move { Ok([0xEE; 32].into()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_timestamp(&self, _: BlockNumberOrTag) -> anyhow::Result<BlockTimestamp> {
|
fn block_timestamp(
|
||||||
Ok(0x123456)
|
&self,
|
||||||
|
_: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockTimestamp>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(0x123456) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn last_block_number(&self) -> anyhow::Result<BlockNumber> {
|
fn last_block_number(
|
||||||
Ok(0x1234567)
|
&self,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockNumber>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(0x1234567) })
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn transaction_gas_price(&self, _: &TxHash) -> anyhow::Result<u128> {
|
fn transaction_gas_price(
|
||||||
Ok(0x200)
|
&self,
|
||||||
|
_: TxHash,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move { Ok(0x200) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::pin::Pin;
|
||||||
|
|
||||||
use alloy::eips::BlockNumberOrTag;
|
use alloy::eips::BlockNumberOrTag;
|
||||||
use alloy::json_abi::JsonAbi;
|
use alloy::json_abi::JsonAbi;
|
||||||
@@ -12,36 +13,54 @@ use crate::metadata::{ContractIdent, ContractInstance};
|
|||||||
/// crate implements to go from string calldata and into the bytes calldata.
|
/// crate implements to go from string calldata and into the bytes calldata.
|
||||||
pub trait ResolverApi {
|
pub trait ResolverApi {
|
||||||
/// Returns the ID of the chain that the node is on.
|
/// Returns the ID of the chain that the node is on.
|
||||||
fn chain_id(&self) -> impl Future<Output = Result<ChainId>>;
|
fn chain_id(&self) -> Pin<Box<dyn Future<Output = Result<ChainId>> + '_>>;
|
||||||
|
|
||||||
/// Returns the gas price for the specified transaction.
|
/// Returns the gas price for the specified transaction.
|
||||||
fn transaction_gas_price(&self, tx_hash: &TxHash) -> impl Future<Output = Result<u128>>;
|
fn transaction_gas_price(
|
||||||
|
&self,
|
||||||
|
tx_hash: TxHash,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<u128>> + '_>>;
|
||||||
|
|
||||||
// TODO: This is currently a u128 due to Kitchensink needing more than 64 bits for its gas limit
|
// TODO: This is currently a u128 due to Kitchensink needing more than 64 bits for its gas limit
|
||||||
// when we implement the changes to the gas we need to adjust this to be a u64.
|
// when we implement the changes to the gas we need to adjust this to be a u64.
|
||||||
/// Returns the gas limit of the specified block.
|
/// Returns the gas limit of the specified block.
|
||||||
fn block_gas_limit(&self, number: BlockNumberOrTag) -> impl Future<Output = Result<u128>>;
|
fn block_gas_limit(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<u128>> + '_>>;
|
||||||
|
|
||||||
/// Returns the coinbase of the specified block.
|
/// Returns the coinbase of the specified block.
|
||||||
fn block_coinbase(&self, number: BlockNumberOrTag) -> impl Future<Output = Result<Address>>;
|
fn block_coinbase(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<Address>> + '_>>;
|
||||||
|
|
||||||
/// Returns the difficulty of the specified block.
|
/// Returns the difficulty of the specified block.
|
||||||
fn block_difficulty(&self, number: BlockNumberOrTag) -> impl Future<Output = Result<U256>>;
|
fn block_difficulty(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<U256>> + '_>>;
|
||||||
|
|
||||||
/// Returns the base fee of the specified block.
|
/// Returns the base fee of the specified block.
|
||||||
fn block_base_fee(&self, number: BlockNumberOrTag) -> impl Future<Output = Result<u64>>;
|
fn block_base_fee(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<u64>> + '_>>;
|
||||||
|
|
||||||
/// Returns the hash of the specified block.
|
/// Returns the hash of the specified block.
|
||||||
fn block_hash(&self, number: BlockNumberOrTag) -> impl Future<Output = Result<BlockHash>>;
|
fn block_hash(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<BlockHash>> + '_>>;
|
||||||
|
|
||||||
/// Returns the timestamp of the specified block,
|
/// Returns the timestamp of the specified block,
|
||||||
fn block_timestamp(
|
fn block_timestamp(
|
||||||
&self,
|
&self,
|
||||||
number: BlockNumberOrTag,
|
number: BlockNumberOrTag,
|
||||||
) -> impl Future<Output = Result<BlockTimestamp>>;
|
) -> Pin<Box<dyn Future<Output = Result<BlockTimestamp>> + '_>>;
|
||||||
|
|
||||||
/// Returns the number of the last block.
|
/// Returns the number of the last block.
|
||||||
fn last_block_number(&self) -> impl Future<Output = Result<BlockNumber>>;
|
fn last_block_number(&self) -> Pin<Box<dyn Future<Output = Result<BlockNumber>> + '_>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ repository.workspace = true
|
|||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
revive-dt-format = { workspace = true }
|
||||||
|
|
||||||
alloy = { workspace = true }
|
alloy = { workspace = true }
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use alloy::primitives::{Address, StorageKey, U256};
|
|||||||
use alloy::rpc::types::trace::geth::{DiffMode, GethDebugTracingOptions, GethTrace};
|
use alloy::rpc::types::trace::geth::{DiffMode, GethDebugTracingOptions, GethTrace};
|
||||||
use alloy::rpc::types::{EIP1186AccountProofResponse, TransactionReceipt, TransactionRequest};
|
use alloy::rpc::types::{EIP1186AccountProofResponse, TransactionReceipt, TransactionRequest};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use revive_dt_format::traits::ResolverApi;
|
||||||
|
|
||||||
/// An interface for all interactions with Ethereum compatible nodes.
|
/// An interface for all interactions with Ethereum compatible nodes.
|
||||||
pub trait EthereumNode {
|
pub trait EthereumNode {
|
||||||
@@ -32,4 +33,7 @@ pub trait EthereumNode {
|
|||||||
address: Address,
|
address: Address,
|
||||||
keys: Vec<StorageKey>,
|
keys: Vec<StorageKey>,
|
||||||
) -> impl Future<Output = Result<EIP1186AccountProofResponse>>;
|
) -> impl Future<Output = Result<EIP1186AccountProofResponse>>;
|
||||||
|
|
||||||
|
/// Returns the resolver that is to use with this ethereum node.
|
||||||
|
fn resolver(&self) -> impl Future<Output = Result<Box<dyn ResolverApi + '_>>>;
|
||||||
}
|
}
|
||||||
|
|||||||
+261
-81
@@ -5,6 +5,7 @@ use std::{
|
|||||||
io::{BufRead, BufReader, Read, Write},
|
io::{BufRead, BufReader, Read, Write},
|
||||||
ops::ControlFlow,
|
ops::ControlFlow,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
pin::Pin,
|
||||||
process::{Child, Command, Stdio},
|
process::{Child, Command, Stdio},
|
||||||
sync::{
|
sync::{
|
||||||
Arc,
|
Arc,
|
||||||
@@ -438,115 +439,294 @@ impl EthereumNode for GethNode {
|
|||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn resolver(&self) -> impl Future<Output = anyhow::Result<Box<dyn ResolverApi + '_>>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let id = self.id;
|
||||||
|
let provider = self.provider().await?;
|
||||||
|
Ok(Box::new(GethNodeResolver { id, provider }) as Box<dyn ResolverApi>)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct GethNodeResolver<F: TxFiller<Ethereum>, P: Provider<Ethereum>> {
|
||||||
|
id: u32,
|
||||||
|
provider: FillProvider<F, P, Ethereum>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: TxFiller<Ethereum>, P: Provider<Ethereum>> ResolverApi for GethNodeResolver<F, P> {
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn chain_id(
|
||||||
|
&self,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<alloy::primitives::ChainId>> + '_>> {
|
||||||
|
Box::pin(async move { self.provider.get_chain_id().await.map_err(Into::into) })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn transaction_gas_price(
|
||||||
|
&self,
|
||||||
|
tx_hash: TxHash,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_transaction_receipt(tx_hash)
|
||||||
|
.await?
|
||||||
|
.context("Failed to get the transaction receipt")
|
||||||
|
.map(|receipt| receipt.effective_gas_price)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_gas_limit(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.gas_limit as _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_coinbase(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<Address>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.beneficiary)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_difficulty(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<U256>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_base_fee(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u64>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.and_then(|block| {
|
||||||
|
block
|
||||||
|
.header
|
||||||
|
.base_fee_per_gas
|
||||||
|
.context("Failed to get the base fee per gas")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_hash(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockHash>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.hash)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn block_timestamp(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockTimestamp>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.timestamp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
|
fn last_block_number(&self) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockNumber>> + '_>> {
|
||||||
|
Box::pin(async move { self.provider.get_block_number().await.map_err(Into::into) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove
|
||||||
impl ResolverApi for GethNode {
|
impl ResolverApi for GethNode {
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn chain_id(&self) -> anyhow::Result<alloy::primitives::ChainId> {
|
fn chain_id(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<alloy::primitives::ChainId>> + '_>> {
|
||||||
.context("Failed to get the Geth provider")?
|
Box::pin(async move {
|
||||||
.get_chain_id()
|
self.provider()
|
||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.context("Failed to get the Geth provider")?
|
||||||
|
.get_chain_id()
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn transaction_gas_price(&self, tx_hash: &TxHash) -> anyhow::Result<u128> {
|
fn transaction_gas_price(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
tx_hash: TxHash,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
.get_transaction_receipt(*tx_hash)
|
Box::pin(async move {
|
||||||
.await?
|
self.provider()
|
||||||
.context("Failed to get the transaction receipt")
|
.await
|
||||||
.map(|receipt| receipt.effective_gas_price)
|
.context("Failed to get the Geth provider")?
|
||||||
|
.get_transaction_receipt(tx_hash)
|
||||||
|
.await?
|
||||||
|
.context("Failed to get the transaction receipt")
|
||||||
|
.map(|receipt| receipt.effective_gas_price)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_gas_limit(&self, number: BlockNumberOrTag) -> anyhow::Result<u128> {
|
fn block_gas_limit(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.map(|block| block.header.gas_limit as _)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.gas_limit as _)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_coinbase(&self, number: BlockNumberOrTag) -> anyhow::Result<Address> {
|
fn block_coinbase(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<Address>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.map(|block| block.header.beneficiary)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.beneficiary)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_difficulty(&self, number: BlockNumberOrTag) -> anyhow::Result<U256> {
|
fn block_difficulty(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<U256>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_base_fee(&self, number: BlockNumberOrTag) -> anyhow::Result<u64> {
|
fn block_base_fee(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u64>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.and_then(|block| {
|
.get_block_by_number(number)
|
||||||
block
|
.await
|
||||||
.header
|
.context("Failed to get the geth block")?
|
||||||
.base_fee_per_gas
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
.context("Failed to get the base fee per gas")
|
.and_then(|block| {
|
||||||
})
|
block
|
||||||
|
.header
|
||||||
|
.base_fee_per_gas
|
||||||
|
.context("Failed to get the base fee per gas")
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_hash(&self, number: BlockNumberOrTag) -> anyhow::Result<BlockHash> {
|
fn block_hash(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockHash>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.map(|block| block.header.hash)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.hash)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn block_timestamp(&self, number: BlockNumberOrTag) -> anyhow::Result<BlockTimestamp> {
|
fn block_timestamp(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Geth provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockTimestamp>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the geth block")?
|
.await
|
||||||
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
.context("Failed to get the Geth provider")?
|
||||||
.map(|block| block.header.timestamp)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the geth block")?
|
||||||
|
.context("Failed to get the Geth block, perhaps there are no blocks?")
|
||||||
|
.map(|block| block.header.timestamp)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
#[instrument(level = "info", skip_all, fields(geth_node_id = self.id))]
|
||||||
async fn last_block_number(&self) -> anyhow::Result<BlockNumber> {
|
fn last_block_number(&self) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockNumber>> + '_>> {
|
||||||
self.provider()
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the Geth provider")?
|
.await
|
||||||
.get_block_number()
|
.context("Failed to get the Geth provider")?
|
||||||
.await
|
.get_block_number()
|
||||||
.map_err(Into::into)
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+284
-101
@@ -2,6 +2,7 @@ use std::{
|
|||||||
fs::{File, OpenOptions, create_dir_all, remove_dir_all},
|
fs::{File, OpenOptions, create_dir_all, remove_dir_all},
|
||||||
io::{BufRead, Write},
|
io::{BufRead, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
|
pin::Pin,
|
||||||
process::{Child, Command, Stdio},
|
process::{Child, Command, Stdio},
|
||||||
sync::{
|
sync::{
|
||||||
Arc,
|
Arc,
|
||||||
@@ -44,6 +45,7 @@ use sp_runtime::AccountId32;
|
|||||||
|
|
||||||
use revive_dt_config::*;
|
use revive_dt_config::*;
|
||||||
use revive_dt_node_interaction::EthereumNode;
|
use revive_dt_node_interaction::EthereumNode;
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::{Node, common::FallbackGasFiller, constants::INITIAL_BALANCE};
|
use crate::{Node, common::FallbackGasFiller, constants::INITIAL_BALANCE};
|
||||||
|
|
||||||
@@ -387,14 +389,14 @@ impl KitchensinkNode {
|
|||||||
&self,
|
&self,
|
||||||
) -> anyhow::Result<
|
) -> anyhow::Result<
|
||||||
FillProvider<
|
FillProvider<
|
||||||
impl TxFiller<KitchenSinkNetwork>,
|
impl TxFiller<KitchensinkNetwork>,
|
||||||
impl Provider<KitchenSinkNetwork>,
|
impl Provider<KitchensinkNetwork>,
|
||||||
KitchenSinkNetwork,
|
KitchensinkNetwork,
|
||||||
>,
|
>,
|
||||||
> {
|
> {
|
||||||
ProviderBuilder::new()
|
ProviderBuilder::new()
|
||||||
.disable_recommended_fillers()
|
.disable_recommended_fillers()
|
||||||
.network::<KitchenSinkNetwork>()
|
.network::<KitchensinkNetwork>()
|
||||||
.filler(FallbackGasFiller::new(
|
.filler(FallbackGasFiller::new(
|
||||||
25_000_000,
|
25_000_000,
|
||||||
1_000_000_000,
|
1_000_000_000,
|
||||||
@@ -479,106 +481,287 @@ impl EthereumNode for KitchensinkNode {
|
|||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn resolver(&self) -> impl Future<Output = anyhow::Result<Box<dyn ResolverApi + '_>>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let id = self.id;
|
||||||
|
let provider = self.provider().await?;
|
||||||
|
Ok(Box::new(KitchensinkNodeResolver { id, provider }) as Box<dyn ResolverApi>)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct KitchensinkNodeResolver<F: TxFiller<KitchensinkNetwork>, P: Provider<KitchensinkNetwork>>
|
||||||
|
{
|
||||||
|
id: u32,
|
||||||
|
provider: FillProvider<F, P, KitchensinkNetwork>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F: TxFiller<KitchensinkNetwork>, P: Provider<KitchensinkNetwork>> ResolverApi
|
||||||
|
for KitchensinkNodeResolver<F, P>
|
||||||
|
{
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn chain_id(
|
||||||
|
&self,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<alloy::primitives::ChainId>> + '_>> {
|
||||||
|
Box::pin(async move { self.provider.get_chain_id().await.map_err(Into::into) })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn transaction_gas_price(
|
||||||
|
&self,
|
||||||
|
tx_hash: TxHash,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_transaction_receipt(tx_hash)
|
||||||
|
.await?
|
||||||
|
.context("Failed to get the transaction receipt")
|
||||||
|
.map(|receipt| receipt.effective_gas_price)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_gas_limit(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.gas_limit as _)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_coinbase(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<Address>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.beneficiary)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_difficulty(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<U256>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_base_fee(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u64>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.and_then(|block| {
|
||||||
|
block
|
||||||
|
.header
|
||||||
|
.base_fee_per_gas
|
||||||
|
.context("Failed to get the base fee per gas")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_hash(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockHash>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.hash)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn block_timestamp(
|
||||||
|
&self,
|
||||||
|
number: BlockNumberOrTag,
|
||||||
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockTimestamp>> + '_>> {
|
||||||
|
Box::pin(async move {
|
||||||
|
self.provider
|
||||||
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.timestamp)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "info", skip_all, fields(kitchensink_node_id = self.id))]
|
||||||
|
fn last_block_number(&self) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockNumber>> + '_>> {
|
||||||
|
Box::pin(async move { self.provider.get_block_number().await.map_err(Into::into) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove
|
||||||
impl ResolverApi for KitchensinkNode {
|
impl ResolverApi for KitchensinkNode {
|
||||||
async fn chain_id(&self) -> anyhow::Result<alloy::primitives::ChainId> {
|
fn chain_id(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<alloy::primitives::ChainId>> + '_>> {
|
||||||
.context("Failed to get the Kitchensink provider")?
|
Box::pin(async move {
|
||||||
.get_chain_id()
|
self.provider()
|
||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.context("Failed to get the Kitchensink provider")?
|
||||||
|
.get_chain_id()
|
||||||
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn transaction_gas_price(&self, tx_hash: &TxHash) -> anyhow::Result<u128> {
|
fn transaction_gas_price(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
tx_hash: TxHash,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
.get_transaction_receipt(*tx_hash)
|
Box::pin(async move {
|
||||||
.await?
|
self.provider()
|
||||||
.context("Failed to get the transaction receipt")
|
.await
|
||||||
.map(|receipt| receipt.effective_gas_price)
|
.context("Failed to get the Kitchensink provider")?
|
||||||
|
.get_transaction_receipt(tx_hash)
|
||||||
|
.await?
|
||||||
|
.context("Failed to get the transaction receipt")
|
||||||
|
.map(|receipt| receipt.effective_gas_price)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_gas_limit(&self, number: BlockNumberOrTag) -> anyhow::Result<u128> {
|
fn block_gas_limit(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u128>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.map(|block| block.header.gas_limit as _)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.gas_limit as _)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_coinbase(&self, number: BlockNumberOrTag) -> anyhow::Result<Address> {
|
fn block_coinbase(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<Address>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.map(|block| block.header.beneficiary)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.beneficiary)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_difficulty(&self, number: BlockNumberOrTag) -> anyhow::Result<U256> {
|
fn block_difficulty(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<U256>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| U256::from_be_bytes(block.header.mix_hash.0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_base_fee(&self, number: BlockNumberOrTag) -> anyhow::Result<u64> {
|
fn block_base_fee(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<u64>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.and_then(|block| {
|
.get_block_by_number(number)
|
||||||
block
|
.await
|
||||||
.header
|
.context("Failed to get the kitchensink block")?
|
||||||
.base_fee_per_gas
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
.context("Failed to get the base fee per gas")
|
.and_then(|block| {
|
||||||
})
|
block
|
||||||
|
.header
|
||||||
|
.base_fee_per_gas
|
||||||
|
.context("Failed to get the base fee per gas")
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_hash(&self, number: BlockNumberOrTag) -> anyhow::Result<BlockHash> {
|
fn block_hash(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockHash>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.map(|block| block.header.hash)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.hash)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn block_timestamp(&self, number: BlockNumberOrTag) -> anyhow::Result<BlockTimestamp> {
|
fn block_timestamp(
|
||||||
self.provider()
|
&self,
|
||||||
.await
|
number: BlockNumberOrTag,
|
||||||
.context("Failed to get the Kitchensink provider")?
|
) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockTimestamp>> + '_>> {
|
||||||
.get_block_by_number(number)
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the kitchensink block")?
|
.await
|
||||||
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.map(|block| block.header.timestamp)
|
.get_block_by_number(number)
|
||||||
|
.await
|
||||||
|
.context("Failed to get the kitchensink block")?
|
||||||
|
.context("Failed to get the Kitchensink block, perhaps the chain has no blocks?")
|
||||||
|
.map(|block| block.header.timestamp)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn last_block_number(&self) -> anyhow::Result<BlockNumber> {
|
fn last_block_number(&self) -> Pin<Box<dyn Future<Output = anyhow::Result<BlockNumber>> + '_>> {
|
||||||
self.provider()
|
Box::pin(async move {
|
||||||
.await
|
self.provider()
|
||||||
.context("Failed to get the Kitchensink provider")?
|
.await
|
||||||
.get_block_number()
|
.context("Failed to get the Kitchensink provider")?
|
||||||
.await
|
.get_block_number()
|
||||||
.map_err(Into::into)
|
.await
|
||||||
|
.map_err(Into::into)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,9 +884,9 @@ impl Drop for KitchensinkNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
struct KitchenSinkNetwork;
|
pub struct KitchensinkNetwork;
|
||||||
|
|
||||||
impl Network for KitchenSinkNetwork {
|
impl Network for KitchensinkNetwork {
|
||||||
type TxType = <Ethereum as Network>::TxType;
|
type TxType = <Ethereum as Network>::TxType;
|
||||||
|
|
||||||
type TxEnvelope = <Ethereum as Network>::TxEnvelope;
|
type TxEnvelope = <Ethereum as Network>::TxEnvelope;
|
||||||
@@ -712,7 +895,7 @@ impl Network for KitchenSinkNetwork {
|
|||||||
|
|
||||||
type ReceiptEnvelope = <Ethereum as Network>::ReceiptEnvelope;
|
type ReceiptEnvelope = <Ethereum as Network>::ReceiptEnvelope;
|
||||||
|
|
||||||
type Header = KitchenSinkHeader;
|
type Header = KitchensinkHeader;
|
||||||
|
|
||||||
type TransactionRequest = <Ethereum as Network>::TransactionRequest;
|
type TransactionRequest = <Ethereum as Network>::TransactionRequest;
|
||||||
|
|
||||||
@@ -720,12 +903,12 @@ impl Network for KitchenSinkNetwork {
|
|||||||
|
|
||||||
type ReceiptResponse = <Ethereum as Network>::ReceiptResponse;
|
type ReceiptResponse = <Ethereum as Network>::ReceiptResponse;
|
||||||
|
|
||||||
type HeaderResponse = Header<KitchenSinkHeader>;
|
type HeaderResponse = Header<KitchensinkHeader>;
|
||||||
|
|
||||||
type BlockResponse = Block<Transaction<TxEnvelope>, Header<KitchenSinkHeader>>;
|
type BlockResponse = Block<Transaction<TxEnvelope>, Header<KitchensinkHeader>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::TransactionRequest {
|
impl TransactionBuilder<KitchensinkNetwork> for <Ethereum as Network>::TransactionRequest {
|
||||||
fn chain_id(&self) -> Option<alloy::primitives::ChainId> {
|
fn chain_id(&self) -> Option<alloy::primitives::ChainId> {
|
||||||
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::chain_id(self)
|
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::chain_id(self)
|
||||||
}
|
}
|
||||||
@@ -857,7 +1040,7 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
|
|
||||||
fn complete_type(
|
fn complete_type(
|
||||||
&self,
|
&self,
|
||||||
ty: <KitchenSinkNetwork as Network>::TxType,
|
ty: <KitchensinkNetwork as Network>::TxType,
|
||||||
) -> Result<(), Vec<&'static str>> {
|
) -> Result<(), Vec<&'static str>> {
|
||||||
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::complete_type(
|
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::complete_type(
|
||||||
self, ty,
|
self, ty,
|
||||||
@@ -874,13 +1057,13 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::can_build(self)
|
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::can_build(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_tx_type(&self) -> <KitchenSinkNetwork as Network>::TxType {
|
fn output_tx_type(&self) -> <KitchensinkNetwork as Network>::TxType {
|
||||||
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::output_tx_type(
|
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::output_tx_type(
|
||||||
self,
|
self,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn output_tx_type_checked(&self) -> Option<<KitchenSinkNetwork as Network>::TxType> {
|
fn output_tx_type_checked(&self) -> Option<<KitchensinkNetwork as Network>::TxType> {
|
||||||
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::output_tx_type_checked(
|
<<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::output_tx_type_checked(
|
||||||
self,
|
self,
|
||||||
)
|
)
|
||||||
@@ -894,7 +1077,7 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
|
|
||||||
fn build_unsigned(
|
fn build_unsigned(
|
||||||
self,
|
self,
|
||||||
) -> alloy::network::BuildResult<<KitchenSinkNetwork as Network>::UnsignedTx, KitchenSinkNetwork>
|
) -> alloy::network::BuildResult<<KitchensinkNetwork as Network>::UnsignedTx, KitchensinkNetwork>
|
||||||
{
|
{
|
||||||
let result = <<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::build_unsigned(
|
let result = <<Ethereum as Network>::TransactionRequest as TransactionBuilder<Ethereum>>::build_unsigned(
|
||||||
self,
|
self,
|
||||||
@@ -902,7 +1085,7 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
match result {
|
match result {
|
||||||
Ok(unsigned_tx) => Ok(unsigned_tx),
|
Ok(unsigned_tx) => Ok(unsigned_tx),
|
||||||
Err(UnbuiltTransactionError { request, error }) => {
|
Err(UnbuiltTransactionError { request, error }) => {
|
||||||
Err(UnbuiltTransactionError::<KitchenSinkNetwork> {
|
Err(UnbuiltTransactionError::<KitchensinkNetwork> {
|
||||||
request,
|
request,
|
||||||
error: match error {
|
error: match error {
|
||||||
TransactionBuilderError::InvalidTransactionRequest(tx_type, items) => {
|
TransactionBuilderError::InvalidTransactionRequest(tx_type, items) => {
|
||||||
@@ -923,12 +1106,12 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn build<W: alloy::network::NetworkWallet<KitchenSinkNetwork>>(
|
async fn build<W: alloy::network::NetworkWallet<KitchensinkNetwork>>(
|
||||||
self,
|
self,
|
||||||
wallet: &W,
|
wallet: &W,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
<KitchenSinkNetwork as Network>::TxEnvelope,
|
<KitchensinkNetwork as Network>::TxEnvelope,
|
||||||
TransactionBuilderError<KitchenSinkNetwork>,
|
TransactionBuilderError<KitchensinkNetwork>,
|
||||||
> {
|
> {
|
||||||
Ok(wallet.sign_request(self).await?)
|
Ok(wallet.sign_request(self).await?)
|
||||||
}
|
}
|
||||||
@@ -936,7 +1119,7 @@ impl TransactionBuilder<KitchenSinkNetwork> for <Ethereum as Network>::Transacti
|
|||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct KitchenSinkHeader {
|
pub struct KitchensinkHeader {
|
||||||
/// The Keccak 256-bit hash of the parent
|
/// The Keccak 256-bit hash of the parent
|
||||||
/// block’s header, in its entirety; formally Hp.
|
/// block’s header, in its entirety; formally Hp.
|
||||||
pub parent_hash: B256,
|
pub parent_hash: B256,
|
||||||
@@ -1039,7 +1222,7 @@ pub struct KitchenSinkHeader {
|
|||||||
pub requests_hash: Option<B256>,
|
pub requests_hash: Option<B256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockHeader for KitchenSinkHeader {
|
impl BlockHeader for KitchensinkHeader {
|
||||||
fn parent_hash(&self) -> B256 {
|
fn parent_hash(&self) -> B256 {
|
||||||
self.parent_hash
|
self.parent_hash
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user