feat: support capella (#214)
* handle forks using superstructs * fix ssz for superstructs * add capella types * fix tests * clippy * clippy take two
This commit is contained in:
parent
3afa312776
commit
ba3f31111f
|
@ -695,6 +695,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"ssz-rs",
|
||||
"superstruct",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
|
@ -975,6 +976,41 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.6.1"
|
||||
|
@ -2184,6 +2220,12 @@ dependencies = [
|
|||
"cxx-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
|
@ -4206,6 +4248,20 @@ version = "2.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "superstruct"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f4e1f478a7728f8855d7e620e9a152cf8932c6614f86564c886f9b8141f3201"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"smallvec",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
|
|
|
@ -109,11 +109,11 @@ impl Node {
|
|||
.map_err(NodeError::ConsensusPayloadError)?;
|
||||
|
||||
self.payloads
|
||||
.insert(latest_payload.block_number, latest_payload);
|
||||
.insert(*latest_payload.block_number(), latest_payload);
|
||||
self.payloads
|
||||
.insert(finalized_payload.block_number, finalized_payload.clone());
|
||||
.insert(*finalized_payload.block_number(), finalized_payload.clone());
|
||||
self.finalized_payloads
|
||||
.insert(finalized_payload.block_number, finalized_payload);
|
||||
.insert(*finalized_payload.block_number(), finalized_payload);
|
||||
|
||||
let start_slot = self
|
||||
.current_slot
|
||||
|
@ -124,7 +124,7 @@ impl Node {
|
|||
.await
|
||||
.map_err(NodeError::ConsensusPayloadError)?;
|
||||
for payload in backfill_payloads {
|
||||
self.payloads.insert(payload.block_number, payload);
|
||||
self.payloads.insert(*payload.block_number(), payload);
|
||||
}
|
||||
|
||||
self.current_slot = Some(latest_header.slot);
|
||||
|
@ -188,14 +188,14 @@ impl Node {
|
|||
|
||||
pub fn get_block_transaction_count_by_hash(&self, hash: &Vec<u8>) -> Result<u64> {
|
||||
let payload = self.get_payload_by_hash(hash)?;
|
||||
let transaction_count = payload.1.transactions.len();
|
||||
let transaction_count = payload.1.transactions().len();
|
||||
|
||||
Ok(transaction_count as u64)
|
||||
}
|
||||
|
||||
pub fn get_block_transaction_count_by_number(&self, block: BlockTag) -> Result<u64> {
|
||||
let payload = self.get_payload(block)?;
|
||||
let transaction_count = payload.transactions.len();
|
||||
let transaction_count = payload.transactions().len();
|
||||
|
||||
Ok(transaction_count as u64)
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ impl Node {
|
|||
self.check_head_age()?;
|
||||
|
||||
let payload = self.get_payload(BlockTag::Latest)?;
|
||||
let base_fee = U256::from_little_endian(&payload.base_fee_per_gas.to_bytes_le());
|
||||
let base_fee = U256::from_little_endian(&payload.base_fee_per_gas().to_bytes_le());
|
||||
let tip = U256::from(10_u64.pow(9));
|
||||
Ok(base_fee + tip)
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ impl Node {
|
|||
self.check_head_age()?;
|
||||
|
||||
let payload = self.get_payload(BlockTag::Latest)?;
|
||||
Ok(payload.block_number)
|
||||
Ok(*payload.block_number())
|
||||
}
|
||||
|
||||
pub async fn get_block_by_number(
|
||||
|
@ -367,7 +367,7 @@ impl Node {
|
|||
pub fn get_coinbase(&self) -> Result<Address> {
|
||||
self.check_head_age()?;
|
||||
let payload = self.get_payload(BlockTag::Latest)?;
|
||||
let coinbase_address = Address::from_slice(&payload.fee_recipient);
|
||||
let coinbase_address = Address::from_slice(payload.fee_recipient());
|
||||
Ok(coinbase_address)
|
||||
}
|
||||
|
||||
|
@ -398,7 +398,7 @@ impl Node {
|
|||
let payloads = self
|
||||
.payloads
|
||||
.iter()
|
||||
.filter(|entry| &entry.1.block_hash.to_vec() == hash)
|
||||
.filter(|entry| &entry.1.block_hash().to_vec() == hash)
|
||||
.collect::<Vec<(&u64, &ExecutionPayload)>>();
|
||||
|
||||
payloads
|
||||
|
|
|
@ -73,7 +73,9 @@ impl Config {
|
|||
pub fn fork_version(&self, slot: u64) -> Vec<u8> {
|
||||
let epoch = slot / 32;
|
||||
|
||||
if epoch >= self.forks.bellatrix.epoch {
|
||||
if epoch >= self.forks.capella.epoch {
|
||||
self.forks.capella.fork_version.clone()
|
||||
} else if epoch >= self.forks.bellatrix.epoch {
|
||||
self.forks.bellatrix.fork_version.clone()
|
||||
} else if epoch >= self.forks.altair.epoch {
|
||||
self.forks.altair.fork_version.clone()
|
||||
|
|
|
@ -62,6 +62,10 @@ pub fn mainnet() -> BaseConfig {
|
|||
epoch: 144896,
|
||||
fork_version: hex_str_to_bytes("0x02000000").unwrap(),
|
||||
},
|
||||
capella: Fork {
|
||||
epoch: u64::MAX, // TODO: set epoch when known
|
||||
fork_version: hex_str_to_bytes("0x03000000").unwrap(),
|
||||
},
|
||||
},
|
||||
max_checkpoint_age: 1_209_600, // 14 days
|
||||
}
|
||||
|
@ -96,6 +100,10 @@ pub fn goerli() -> BaseConfig {
|
|||
epoch: 112260,
|
||||
fork_version: hex_str_to_bytes("0x02001020").unwrap(),
|
||||
},
|
||||
capella: Fork {
|
||||
epoch: 162304,
|
||||
fork_version: hex_str_to_bytes("0x03001020").unwrap(),
|
||||
},
|
||||
},
|
||||
max_checkpoint_age: 1_209_600, // 14 days
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ pub struct Forks {
|
|||
pub genesis: Fork,
|
||||
pub altair: Fork,
|
||||
pub bellatrix: Fork,
|
||||
pub capella: Fork,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default, Clone)]
|
||||
|
|
|
@ -19,6 +19,7 @@ log = "0.4.17"
|
|||
chrono = "0.4.23"
|
||||
thiserror = "1.0.37"
|
||||
reqwest = { version = "0.11.13", features = ["json"] }
|
||||
superstruct = "0.7.0"
|
||||
|
||||
common = { path = "../common" }
|
||||
config = { path = "../config" }
|
||||
|
|
|
@ -103,7 +103,7 @@ impl<R: ConsensusRpc> ConsensusClient<R> {
|
|||
)
|
||||
.into())
|
||||
} else {
|
||||
Ok(block.body.execution_payload)
|
||||
Ok(block.body.execution_payload().clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,30 +115,33 @@ impl<R: ConsensusRpc> ConsensusClient<R> {
|
|||
let payloads_fut = (start_slot..end_slot)
|
||||
.rev()
|
||||
.map(|slot| self.rpc.get_block(slot));
|
||||
|
||||
let mut prev_parent_hash: Bytes32 = self
|
||||
.rpc
|
||||
.get_block(end_slot)
|
||||
.await?
|
||||
.body
|
||||
.execution_payload
|
||||
.parent_hash;
|
||||
.execution_payload()
|
||||
.parent_hash()
|
||||
.clone();
|
||||
|
||||
let mut payloads: Vec<ExecutionPayload> = Vec::new();
|
||||
for result in join_all(payloads_fut).await {
|
||||
if result.is_err() {
|
||||
continue;
|
||||
}
|
||||
let payload = result.unwrap().body.execution_payload;
|
||||
if payload.block_hash != prev_parent_hash {
|
||||
let payload = result.unwrap().body.execution_payload().clone();
|
||||
if payload.block_hash() != &prev_parent_hash {
|
||||
warn!(
|
||||
"error while backfilling blocks: {}",
|
||||
ConsensusError::InvalidHeaderHash(
|
||||
format!("{prev_parent_hash:02X?}"),
|
||||
format!("{:02X?}", payload.parent_hash),
|
||||
format!("{:02X?}", payload.parent_hash()),
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
prev_parent_hash = payload.parent_hash.clone();
|
||||
prev_parent_hash = payload.parent_hash().clone();
|
||||
payloads.push(payload);
|
||||
}
|
||||
Ok(payloads)
|
||||
|
|
|
@ -4,6 +4,7 @@ use ssz_rs::prelude::*;
|
|||
|
||||
use common::types::Bytes32;
|
||||
use common::utils::hex_str_to_bytes;
|
||||
use superstruct::superstruct;
|
||||
|
||||
pub type BLSPubKey = Vector<u8, 48>;
|
||||
pub type SignatureBytes = Vector<u8, 96>;
|
||||
|
@ -24,7 +25,15 @@ pub struct BeaconBlock {
|
|||
pub body: BeaconBlockBody,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella),
|
||||
variant_attributes(
|
||||
derive(serde::Deserialize, Clone, Debug, SimpleSerialize, Default),
|
||||
serde(deny_unknown_fields)
|
||||
)
|
||||
)]
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub struct BeaconBlockBody {
|
||||
#[serde(deserialize_with = "signature_deserialize")]
|
||||
randao_reveal: SignatureBytes,
|
||||
|
@ -38,9 +47,79 @@ pub struct BeaconBlockBody {
|
|||
voluntary_exits: List<SignedVoluntaryExit, 16>,
|
||||
sync_aggregate: SyncAggregate,
|
||||
pub execution_payload: ExecutionPayload,
|
||||
#[superstruct(only(Capella))]
|
||||
bls_to_execution_changes: List<SignedBlsToExecutionChange, 16>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
impl ssz_rs::Merkleized for BeaconBlockBody {
|
||||
fn hash_tree_root(&mut self) -> Result<Node, MerkleizationError> {
|
||||
match self {
|
||||
BeaconBlockBody::Bellatrix(body) => body.hash_tree_root(),
|
||||
BeaconBlockBody::Capella(body) => body.hash_tree_root(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Sized for BeaconBlockBody {
|
||||
fn is_variable_size() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn size_hint() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Serialize for BeaconBlockBody {
|
||||
fn serialize(&self, buffer: &mut Vec<u8>) -> Result<usize, SerializeError> {
|
||||
match self {
|
||||
BeaconBlockBody::Bellatrix(body) => body.serialize(buffer),
|
||||
BeaconBlockBody::Capella(body) => body.serialize(buffer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Deserialize for BeaconBlockBody {
|
||||
fn deserialize(_encoding: &[u8]) -> Result<Self, DeserializeError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
panic!("not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, SimpleSerialize, serde::Deserialize)]
|
||||
pub struct SignedBlsToExecutionChange {
|
||||
message: BlsToExecutionChange,
|
||||
#[serde(deserialize_with = "signature_deserialize")]
|
||||
signature: SignatureBytes,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, SimpleSerialize, serde::Deserialize)]
|
||||
pub struct BlsToExecutionChange {
|
||||
#[serde(deserialize_with = "u64_deserialize")]
|
||||
validator_index: u64,
|
||||
#[serde(deserialize_with = "pubkey_deserialize")]
|
||||
from_bls_pubkey: BLSPubKey,
|
||||
#[serde(deserialize_with = "address_deserialize")]
|
||||
to_execution_address: Address,
|
||||
}
|
||||
|
||||
impl Default for BeaconBlockBody {
|
||||
fn default() -> Self {
|
||||
BeaconBlockBody::Bellatrix(BeaconBlockBodyBellatrix::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[superstruct(
|
||||
variants(Bellatrix, Capella),
|
||||
variant_attributes(
|
||||
derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone),
|
||||
serde(deny_unknown_fields)
|
||||
)
|
||||
)]
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
#[serde(untagged)]
|
||||
pub struct ExecutionPayload {
|
||||
#[serde(deserialize_with = "bytes32_deserialize")]
|
||||
pub parent_hash: Bytes32,
|
||||
|
@ -70,10 +149,67 @@ pub struct ExecutionPayload {
|
|||
pub block_hash: Bytes32,
|
||||
#[serde(deserialize_with = "transactions_deserialize")]
|
||||
pub transactions: List<Transaction, 1048576>,
|
||||
#[superstruct(only(Capella))]
|
||||
withdrawals: List<Withdrawal, 16>,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, SimpleSerialize, serde::Deserialize)]
|
||||
pub struct Withdrawal {
|
||||
#[serde(deserialize_with = "u64_deserialize")]
|
||||
index: u64,
|
||||
#[serde(deserialize_with = "u64_deserialize")]
|
||||
validator_index: u64,
|
||||
#[serde(deserialize_with = "address_deserialize")]
|
||||
address: Address,
|
||||
#[serde(deserialize_with = "u64_deserialize")]
|
||||
amount: u64,
|
||||
}
|
||||
|
||||
impl ssz_rs::Merkleized for ExecutionPayload {
|
||||
fn hash_tree_root(&mut self) -> Result<Node, MerkleizationError> {
|
||||
match self {
|
||||
ExecutionPayload::Bellatrix(payload) => payload.hash_tree_root(),
|
||||
ExecutionPayload::Capella(payload) => payload.hash_tree_root(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Sized for ExecutionPayload {
|
||||
fn is_variable_size() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn size_hint() -> usize {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Serialize for ExecutionPayload {
|
||||
fn serialize(&self, buffer: &mut Vec<u8>) -> Result<usize, SerializeError> {
|
||||
match self {
|
||||
ExecutionPayload::Bellatrix(payload) => payload.serialize(buffer),
|
||||
ExecutionPayload::Capella(payload) => payload.serialize(buffer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ssz_rs::Deserialize for ExecutionPayload {
|
||||
fn deserialize(_encoding: &[u8]) -> Result<Self, DeserializeError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
panic!("not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ExecutionPayload {
|
||||
fn default() -> Self {
|
||||
ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
struct ProposerSlashing {
|
||||
pub struct ProposerSlashing {
|
||||
signed_header_1: SignedBeaconBlockHeader,
|
||||
signed_header_2: SignedBeaconBlockHeader,
|
||||
}
|
||||
|
@ -100,7 +236,7 @@ struct BeaconBlockHeader {
|
|||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
struct AttesterSlashing {
|
||||
pub struct AttesterSlashing {
|
||||
attestation_1: IndexedAttestation,
|
||||
attestation_2: IndexedAttestation,
|
||||
}
|
||||
|
@ -115,7 +251,7 @@ struct IndexedAttestation {
|
|||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
struct Attestation {
|
||||
pub struct Attestation {
|
||||
aggregation_bits: Bitlist<2048>,
|
||||
data: AttestationData,
|
||||
#[serde(deserialize_with = "signature_deserialize")]
|
||||
|
@ -143,7 +279,7 @@ struct Checkpoint {
|
|||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
struct SignedVoluntaryExit {
|
||||
pub struct SignedVoluntaryExit {
|
||||
message: VoluntaryExit,
|
||||
#[serde(deserialize_with = "signature_deserialize")]
|
||||
signature: SignatureBytes,
|
||||
|
@ -158,7 +294,7 @@ struct VoluntaryExit {
|
|||
}
|
||||
|
||||
#[derive(serde::Deserialize, Debug, Default, SimpleSerialize, Clone)]
|
||||
struct Deposit {
|
||||
pub struct Deposit {
|
||||
#[serde(deserialize_with = "bytes_vector_deserialize")]
|
||||
proof: Vector<Bytes32, 33>,
|
||||
data: DepositData,
|
||||
|
|
|
@ -38,5 +38,5 @@ async fn test_get_payload() {
|
|||
client.sync().await.unwrap();
|
||||
|
||||
let payload = client.get_execution_payload(&None).await.unwrap();
|
||||
assert_eq!(payload.block_number, 7530932);
|
||||
assert_eq!(*payload.block_number(), 7530932);
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> {
|
|||
let rpc = db.execution.rpc.clone();
|
||||
let payload = db.current_payload.clone();
|
||||
let execution = db.execution.clone();
|
||||
let block = db.current_payload.block_number;
|
||||
let block = *db.current_payload.block_number();
|
||||
|
||||
let opts_moved = CallOpts {
|
||||
from: opts.from,
|
||||
|
@ -139,7 +139,7 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> {
|
|||
};
|
||||
|
||||
let producer_account = AccessListItem {
|
||||
address: Address::from_slice(&payload.fee_recipient),
|
||||
address: Address::from_slice(payload.fee_recipient()),
|
||||
storage_keys: Vec::default(),
|
||||
};
|
||||
|
||||
|
@ -182,10 +182,10 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> {
|
|||
env.tx.gas_limit = opts.gas.map(|v| v.as_u64()).unwrap_or(u64::MAX);
|
||||
env.tx.gas_price = opts.gas_price.unwrap_or(U256::zero());
|
||||
|
||||
env.block.number = U256::from(payload.block_number);
|
||||
env.block.coinbase = Address::from_slice(&payload.fee_recipient);
|
||||
env.block.timestamp = U256::from(payload.timestamp);
|
||||
env.block.difficulty = U256::from_little_endian(&payload.prev_randao);
|
||||
env.block.number = U256::from(*payload.block_number());
|
||||
env.block.coinbase = Address::from_slice(payload.fee_recipient());
|
||||
env.block.timestamp = U256::from(*payload.timestamp());
|
||||
env.block.difficulty = U256::from_little_endian(payload.prev_randao());
|
||||
|
||||
env.cfg.chain_id = self.chain_id.into();
|
||||
|
||||
|
@ -266,7 +266,7 @@ impl<'a, R: ExecutionRpc> Database for ProofDB<'a, R> {
|
|||
.payloads
|
||||
.get(&number)
|
||||
.ok_or(BlockNotFoundError::new(BlockTag::Number(number)))?;
|
||||
Ok(H256::from_slice(&payload.block_hash))
|
||||
Ok(H256::from_slice(payload.block_hash()))
|
||||
}
|
||||
|
||||
fn storage(&mut self, address: H160, slot: U256) -> Result<U256, Report> {
|
||||
|
@ -304,6 +304,7 @@ fn is_precompile(address: &Address) -> bool {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use common::utils::hex_str_to_bytes;
|
||||
use consensus::types::ExecutionPayloadBellatrix;
|
||||
use ssz_rs::Vector;
|
||||
|
||||
use crate::rpc::mock_rpc::MockRpc;
|
||||
|
@ -319,15 +320,16 @@ mod tests {
|
|||
// Construct proofdb params
|
||||
let execution = get_client();
|
||||
let address = Address::from_str("14f9D4aF749609c1438528C0Cce1cC3f6D411c47").unwrap();
|
||||
let payload = ExecutionPayload {
|
||||
let payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
state_root: Vector::from_iter(
|
||||
hex_str_to_bytes(
|
||||
"0xaa02f5db2ee75e3da400d10f3c30e894b6016ce8a2501680380a907b6674ce0d",
|
||||
)
|
||||
.unwrap(),
|
||||
),
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(7530933, payload.clone());
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
|
||||
let proof = self
|
||||
.rpc
|
||||
.get_proof(address, slots, payload.block_number)
|
||||
.get_proof(address, slots, *payload.block_number())
|
||||
.await?;
|
||||
|
||||
let account_path = keccak256(address.as_bytes()).to_vec();
|
||||
|
@ -62,7 +62,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
|
||||
let is_valid = verify_proof(
|
||||
&proof.account_proof,
|
||||
&payload.state_root,
|
||||
payload.state_root(),
|
||||
&account_path,
|
||||
&account_encoded,
|
||||
);
|
||||
|
@ -98,7 +98,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
let code = if proof.code_hash == KECCAK_EMPTY {
|
||||
Vec::new()
|
||||
} else {
|
||||
let code = self.rpc.get_code(address, payload.block_number).await?;
|
||||
let code = self.rpc.get_code(address, *payload.block_number()).await?;
|
||||
let code_hash = keccak256(&code).into();
|
||||
|
||||
if proof.code_hash != code_hash {
|
||||
|
@ -136,7 +136,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
let empty_uncle_hash = "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347";
|
||||
|
||||
let tx_hashes = payload
|
||||
.transactions
|
||||
.transactions()
|
||||
.iter()
|
||||
.map(|tx| H256::from_slice(&keccak256(tx)))
|
||||
.collect::<Vec<H256>>();
|
||||
|
@ -144,7 +144,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
let txs = if full_tx {
|
||||
let txs_fut = tx_hashes.iter().map(|hash| async move {
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(payload.block_number, payload.clone());
|
||||
payloads.insert(*payload.block_number(), payload.clone());
|
||||
let tx = self
|
||||
.get_transaction(hash, &payloads)
|
||||
.await?
|
||||
|
@ -163,22 +163,22 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
};
|
||||
|
||||
Ok(ExecutionBlock {
|
||||
number: payload.block_number,
|
||||
base_fee_per_gas: U256::from_little_endian(&payload.base_fee_per_gas.to_bytes_le()),
|
||||
number: *payload.block_number(),
|
||||
base_fee_per_gas: U256::from_little_endian(&payload.base_fee_per_gas().to_bytes_le()),
|
||||
difficulty: U256::from(0),
|
||||
extra_data: payload.extra_data.to_vec(),
|
||||
gas_limit: payload.gas_limit,
|
||||
gas_used: payload.gas_used,
|
||||
hash: H256::from_slice(&payload.block_hash),
|
||||
logs_bloom: payload.logs_bloom.to_vec(),
|
||||
miner: Address::from_slice(&payload.fee_recipient),
|
||||
parent_hash: H256::from_slice(&payload.parent_hash),
|
||||
receipts_root: H256::from_slice(&payload.receipts_root),
|
||||
state_root: H256::from_slice(&payload.state_root),
|
||||
timestamp: payload.timestamp,
|
||||
extra_data: payload.extra_data().to_vec(),
|
||||
gas_limit: *payload.gas_limit(),
|
||||
gas_used: *payload.gas_used(),
|
||||
hash: H256::from_slice(payload.block_hash()),
|
||||
logs_bloom: payload.logs_bloom().to_vec(),
|
||||
miner: Address::from_slice(payload.fee_recipient()),
|
||||
parent_hash: H256::from_slice(payload.parent_hash()),
|
||||
receipts_root: H256::from_slice(payload.receipts_root()),
|
||||
state_root: H256::from_slice(payload.state_root()),
|
||||
timestamp: *payload.timestamp(),
|
||||
total_difficulty: 0,
|
||||
transactions: txs,
|
||||
mix_hash: H256::from_slice(&payload.prev_randao),
|
||||
mix_hash: H256::from_slice(payload.prev_randao()),
|
||||
nonce: empty_nonce,
|
||||
sha3_uncles: H256::from_str(empty_uncle_hash)?,
|
||||
size: 0,
|
||||
|
@ -192,10 +192,10 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
payload: &ExecutionPayload,
|
||||
index: usize,
|
||||
) -> Result<Option<Transaction>> {
|
||||
let tx = payload.transactions[index].clone();
|
||||
let tx = payload.transactions()[index].clone();
|
||||
let tx_hash = H256::from_slice(&keccak256(tx));
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(payload.block_number, payload.clone());
|
||||
payloads.insert(*payload.block_number(), payload.clone());
|
||||
let tx_option = self.get_transaction(&tx_hash, &payloads).await?;
|
||||
let tx = tx_option.ok_or(eyre::eyre!("not reachable"))?;
|
||||
|
||||
|
@ -222,7 +222,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
let payload = payload.unwrap();
|
||||
|
||||
let tx_hashes = payload
|
||||
.transactions
|
||||
.transactions()
|
||||
.iter()
|
||||
.map(|tx| H256::from_slice(&keccak256(tx)))
|
||||
.collect::<Vec<H256>>();
|
||||
|
@ -239,7 +239,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
|
||||
let expected_receipt_root = ordered_trie_root(receipts_encoded);
|
||||
let expected_receipt_root = H256::from_slice(&expected_receipt_root.to_fixed_bytes());
|
||||
let payload_receipt_root = H256::from_slice(&payload.receipts_root);
|
||||
let payload_receipt_root = H256::from_slice(payload.receipts_root());
|
||||
|
||||
if expected_receipt_root != payload_receipt_root || !receipts.contains(&receipt) {
|
||||
return Err(ExecutionError::ReceiptRootMismatch(tx_hash.to_string()).into());
|
||||
|
@ -275,7 +275,7 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
|
||||
let tx_encoded = tx.rlp().to_vec();
|
||||
let txs_encoded = payload
|
||||
.transactions
|
||||
.transactions()
|
||||
.iter()
|
||||
.map(|tx| tx.to_vec())
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -396,29 +396,19 @@ impl<R: ExecutionRpc> ExecutionClient<R> {
|
|||
.get(&block_id)
|
||||
.ok_or(ExecutionError::EmptyExecutionPayload())?;
|
||||
let converted_base_fee_per_gas = ethers::types::U256::from_little_endian(
|
||||
&execution_payload.base_fee_per_gas.to_bytes_le(),
|
||||
&execution_payload.base_fee_per_gas().to_bytes_le(),
|
||||
);
|
||||
fee_history
|
||||
.base_fee_per_gas
|
||||
.push(converted_base_fee_per_gas);
|
||||
let gas_used_ratio_helios = ((execution_payload.gas_used as f64
|
||||
/ execution_payload.gas_limit as f64)
|
||||
let gas_used_ratio_helios = ((*execution_payload.gas_used() as f64
|
||||
/ *execution_payload.gas_limit() as f64)
|
||||
* 10.0_f64.powi(12))
|
||||
.round()
|
||||
/ 10.0_f64.powi(12);
|
||||
fee_history.gas_used_ratio.push(gas_used_ratio_helios);
|
||||
}
|
||||
|
||||
// TODO: Maybe place behind a query option param?
|
||||
// Optionally verify the computed fee history using the rpc
|
||||
// verify_fee_history(
|
||||
// &self.rpc,
|
||||
// &fee_history,
|
||||
// fee_history.base_fee_per_gas.len(),
|
||||
// request_latest_block,
|
||||
// reward_percentiles,
|
||||
// ).await?;
|
||||
|
||||
Ok(Some(fee_history))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use ethers::types::{Address, Filter, H256, U256};
|
|||
use ssz_rs::{List, Vector};
|
||||
|
||||
use common::utils::hex_str_to_bytes;
|
||||
use consensus::types::ExecutionPayload;
|
||||
use consensus::types::{ExecutionPayload, ExecutionPayloadBellatrix};
|
||||
use execution::rpc::mock_rpc::MockRpc;
|
||||
use execution::ExecutionClient;
|
||||
|
||||
|
@ -18,13 +18,13 @@ async fn test_get_account() {
|
|||
let execution = get_client();
|
||||
let address = Address::from_str("14f9D4aF749609c1438528C0Cce1cC3f6D411c47").unwrap();
|
||||
|
||||
let payload = ExecutionPayload {
|
||||
let payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
state_root: Vector::from_iter(
|
||||
hex_str_to_bytes("0xaa02f5db2ee75e3da400d10f3c30e894b6016ce8a2501680380a907b6674ce0d")
|
||||
.unwrap(),
|
||||
),
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
|
||||
let account = execution
|
||||
.get_account(&address, None, &payload)
|
||||
|
@ -55,7 +55,7 @@ async fn test_get_tx() {
|
|||
H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap();
|
||||
|
||||
let mut payload = ExecutionPayload::default();
|
||||
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
payload.transactions_mut().push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(7530933, payload);
|
||||
|
@ -104,15 +104,15 @@ async fn test_get_tx_not_included() {
|
|||
#[tokio::test]
|
||||
async fn test_get_logs() {
|
||||
let execution = get_client();
|
||||
let mut payload = ExecutionPayload {
|
||||
let mut payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
receipts_root: Vector::from_iter(
|
||||
hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f")
|
||||
.unwrap(),
|
||||
),
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
|
||||
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
payload.transactions_mut().push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(7530933, payload);
|
||||
|
@ -134,15 +134,15 @@ async fn test_get_receipt() {
|
|||
let tx_hash =
|
||||
H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap();
|
||||
|
||||
let mut payload = ExecutionPayload {
|
||||
let mut payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
receipts_root: Vector::from_iter(
|
||||
hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f")
|
||||
.unwrap(),
|
||||
),
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
|
||||
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
payload.transactions_mut().push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(7530933, payload);
|
||||
|
@ -163,7 +163,7 @@ async fn test_get_receipt_bad_proof() {
|
|||
H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap();
|
||||
|
||||
let mut payload = ExecutionPayload::default();
|
||||
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
payload.transactions_mut().push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
|
||||
let mut payloads = BTreeMap::new();
|
||||
payloads.insert(7530933, payload);
|
||||
|
@ -191,10 +191,10 @@ async fn test_get_receipt_not_included() {
|
|||
#[tokio::test]
|
||||
async fn test_get_block() {
|
||||
let execution = get_client();
|
||||
let payload = ExecutionPayload {
|
||||
let payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
block_number: 12345,
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
|
||||
let block = execution.get_block(&payload, false).await.unwrap();
|
||||
|
||||
|
@ -207,11 +207,11 @@ async fn test_get_tx_by_block_hash_and_index() {
|
|||
let tx_hash =
|
||||
H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap();
|
||||
|
||||
let mut payload = ExecutionPayload {
|
||||
let mut payload = ExecutionPayload::Bellatrix(ExecutionPayloadBellatrix {
|
||||
block_number: 7530933,
|
||||
..ExecutionPayload::default()
|
||||
};
|
||||
payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
..ExecutionPayloadBellatrix::default()
|
||||
});
|
||||
payload.transactions_mut().push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap()));
|
||||
|
||||
let tx = execution
|
||||
.get_transaction_by_block_hash_and_index(&payload, 0)
|
||||
|
|
Loading…
Reference in New Issue