feat: support finalized block tag (#28)
This commit is contained in:
parent
cf6c211516
commit
56385f15ed
|
@ -13,7 +13,7 @@ use tokio::spawn;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
use crate::node::Node;
|
use crate::node::{BlockTag, Node};
|
||||||
use crate::rpc::Rpc;
|
use crate::rpc::Rpc;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
|
@ -55,7 +55,7 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call(&self, opts: &CallOpts, block: &Option<u64>) -> Result<Vec<u8>> {
|
pub async fn call(&self, opts: &CallOpts, block: &BlockTag) -> Result<Vec<u8>> {
|
||||||
self.node.lock().await.call(opts, block)
|
self.node.lock().await.call(opts, block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +63,15 @@ impl Client {
|
||||||
self.node.lock().await.estimate_gas(opts)
|
self.node.lock().await.estimate_gas(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_balance(&self, address: &Address, block: &Option<u64>) -> Result<U256> {
|
pub async fn get_balance(&self, address: &Address, block: &BlockTag) -> Result<U256> {
|
||||||
self.node.lock().await.get_balance(address, block).await
|
self.node.lock().await.get_balance(address, block).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_nonce(&self, address: &Address, block: &Option<u64>) -> Result<u64> {
|
pub async fn get_nonce(&self, address: &Address, block: &BlockTag) -> Result<u64> {
|
||||||
self.node.lock().await.get_nonce(address, block).await
|
self.node.lock().await.get_nonce(address, block).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_code(&self, address: &Address, block: &Option<u64>) -> Result<Vec<u8>> {
|
pub async fn get_code(&self, address: &Address, block: &BlockTag) -> Result<Vec<u8>> {
|
||||||
self.node.lock().await.get_code(address, block).await
|
self.node.lock().await.get_code(address, block).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ impl Client {
|
||||||
self.node.lock().await.get_block_number()
|
self.node.lock().await.get_block_number()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_block_by_number(&self, block: &Option<u64>) -> Result<ExecutionBlock> {
|
pub async fn get_block_by_number(&self, block: &BlockTag) -> Result<ExecutionBlock> {
|
||||||
self.node.lock().await.get_block_by_number(block)
|
self.node.lock().await.get_block_by_number(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::sync::Arc;
|
||||||
|
|
||||||
use ethers::prelude::{Address, U256};
|
use ethers::prelude::{Address, U256};
|
||||||
use ethers::types::{Transaction, TransactionReceipt, H256};
|
use ethers::types::{Transaction, TransactionReceipt, H256};
|
||||||
use eyre::Result;
|
use eyre::{eyre, Result};
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use consensus::rpc::nimbus_rpc::NimbusRpc;
|
use consensus::rpc::nimbus_rpc::NimbusRpc;
|
||||||
|
@ -20,7 +20,8 @@ pub struct Node {
|
||||||
config: Arc<Config>,
|
config: Arc<Config>,
|
||||||
payloads: HashMap<u64, ExecutionPayload>,
|
payloads: HashMap<u64, ExecutionPayload>,
|
||||||
block_hashes: HashMap<Vec<u8>, u64>,
|
block_hashes: HashMap<Vec<u8>, u64>,
|
||||||
block_head: u64,
|
latest_block: u64,
|
||||||
|
finalized_block: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
impl Node {
|
||||||
|
@ -42,75 +43,84 @@ impl Node {
|
||||||
config,
|
config,
|
||||||
payloads,
|
payloads,
|
||||||
block_hashes,
|
block_hashes,
|
||||||
block_head: 0,
|
latest_block: 0,
|
||||||
|
finalized_block: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn sync(&mut self) -> Result<()> {
|
pub async fn sync(&mut self) -> Result<()> {
|
||||||
self.consensus.sync().await?;
|
self.consensus.sync().await?;
|
||||||
|
self.update_payloads().await
|
||||||
let head = self.consensus.get_header();
|
|
||||||
let payload = self
|
|
||||||
.consensus
|
|
||||||
.get_execution_payload(&Some(head.slot))
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
self.block_head = payload.block_number;
|
|
||||||
self.block_hashes
|
|
||||||
.insert(payload.block_hash.to_vec(), payload.block_number);
|
|
||||||
self.payloads.insert(payload.block_number, payload);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn advance(&mut self) -> Result<()> {
|
pub async fn advance(&mut self) -> Result<()> {
|
||||||
self.consensus.advance().await?;
|
self.consensus.advance().await?;
|
||||||
|
self.update_payloads().await
|
||||||
|
}
|
||||||
|
|
||||||
let head = self.consensus.get_header();
|
async fn update_payloads(&mut self) -> Result<()> {
|
||||||
let payload = self
|
let latest_header = self.consensus.get_header();
|
||||||
|
let latest_payload = self
|
||||||
.consensus
|
.consensus
|
||||||
.get_execution_payload(&Some(head.slot))
|
.get_execution_payload(&Some(latest_header.slot))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
self.block_head = payload.block_number;
|
self.latest_block = latest_payload.block_number;
|
||||||
self.block_hashes
|
self.block_hashes.insert(
|
||||||
.insert(payload.block_hash.to_vec(), payload.block_number);
|
latest_payload.block_hash.to_vec(),
|
||||||
self.payloads.insert(payload.block_number, payload);
|
latest_payload.block_number,
|
||||||
|
);
|
||||||
|
self.payloads
|
||||||
|
.insert(latest_payload.block_number, latest_payload);
|
||||||
|
|
||||||
|
let finalized_header = self.consensus.get_finalized_header();
|
||||||
|
let finalized_payload = self
|
||||||
|
.consensus
|
||||||
|
.get_execution_payload(&Some(finalized_header.slot))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
self.finalized_block = finalized_payload.block_number;
|
||||||
|
self.block_hashes.insert(
|
||||||
|
finalized_payload.block_hash.to_vec(),
|
||||||
|
finalized_payload.block_number,
|
||||||
|
);
|
||||||
|
self.payloads
|
||||||
|
.insert(finalized_payload.block_number, finalized_payload);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(&self, opts: &CallOpts, block: &Option<u64>) -> Result<Vec<u8>> {
|
pub fn call(&self, opts: &CallOpts, block: &BlockTag) -> Result<Vec<u8>> {
|
||||||
let payload = self.get_payload(block)?;
|
let payload = self.get_payload(block)?;
|
||||||
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
|
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
|
||||||
evm.call(opts)
|
evm.call(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn estimate_gas(&self, opts: &CallOpts) -> Result<u64> {
|
pub fn estimate_gas(&self, opts: &CallOpts) -> Result<u64> {
|
||||||
let payload = self.get_payload(&None)?;
|
let payload = self.get_payload(&BlockTag::Latest)?;
|
||||||
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
|
let mut evm = Evm::new(self.execution.clone(), payload, self.chain_id());
|
||||||
evm.estimate_gas(opts)
|
evm.estimate_gas(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_balance(&self, address: &Address, block: &Option<u64>) -> Result<U256> {
|
pub async fn get_balance(&self, address: &Address, block: &BlockTag) -> Result<U256> {
|
||||||
let payload = self.get_payload(block)?;
|
let payload = self.get_payload(block)?;
|
||||||
let account = self.execution.get_account(&address, None, &payload).await?;
|
let account = self.execution.get_account(&address, None, &payload).await?;
|
||||||
Ok(account.balance)
|
Ok(account.balance)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_nonce(&self, address: &Address, block: &Option<u64>) -> Result<u64> {
|
pub async fn get_nonce(&self, address: &Address, block: &BlockTag) -> Result<u64> {
|
||||||
let payload = self.get_payload(block)?;
|
let payload = self.get_payload(block)?;
|
||||||
let account = self.execution.get_account(&address, None, &payload).await?;
|
let account = self.execution.get_account(&address, None, &payload).await?;
|
||||||
Ok(account.nonce)
|
Ok(account.nonce)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_code(&self, address: &Address, block: &Option<u64>) -> Result<Vec<u8>> {
|
pub async fn get_code(&self, address: &Address, block: &BlockTag) -> Result<Vec<u8>> {
|
||||||
let payload = self.get_payload(block)?;
|
let payload = self.get_payload(block)?;
|
||||||
self.execution.get_code(&address, &payload).await
|
self.execution.get_code(&address, &payload).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_storage_at(&self, address: &Address, slot: H256) -> Result<U256> {
|
pub async fn get_storage_at(&self, address: &Address, slot: H256) -> Result<U256> {
|
||||||
let payload = self.get_payload(&None)?;
|
let payload = self.get_payload(&BlockTag::Latest)?;
|
||||||
let account = self
|
let account = self
|
||||||
.execution
|
.execution
|
||||||
.get_account(address, Some(&[slot]), &payload)
|
.get_account(address, Some(&[slot]), &payload)
|
||||||
|
@ -118,7 +128,7 @@ impl Node {
|
||||||
let value = account.slots.get(&slot);
|
let value = account.slots.get(&slot);
|
||||||
match value {
|
match value {
|
||||||
Some(value) => Ok(*value),
|
Some(value) => Ok(*value),
|
||||||
None => Err(eyre::eyre!("Slot Not Found")),
|
None => Err(eyre!("Slot Not Found")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +152,7 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_gas_price(&self) -> Result<U256> {
|
pub fn get_gas_price(&self) -> Result<U256> {
|
||||||
let payload = self.get_payload(&None)?;
|
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));
|
let tip = U256::from(10_u64.pow(9));
|
||||||
Ok(base_fee + tip)
|
Ok(base_fee + tip)
|
||||||
|
@ -154,18 +164,21 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block_number(&self) -> Result<u64> {
|
pub fn get_block_number(&self) -> Result<u64> {
|
||||||
let payload = self.get_payload(&None)?;
|
let payload = self.get_payload(&BlockTag::Latest)?;
|
||||||
Ok(payload.block_number)
|
Ok(payload.block_number)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block_by_number(&self, block: &Option<u64>) -> Result<ExecutionBlock> {
|
pub fn get_block_by_number(&self, block: &BlockTag) -> Result<ExecutionBlock> {
|
||||||
let payload = self.get_payload(block)?;
|
let payload = self.get_payload(block)?;
|
||||||
self.execution.get_block(&payload)
|
self.execution.get_block(&payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_block_by_hash(&self, hash: &Vec<u8>) -> Result<ExecutionBlock> {
|
pub fn get_block_by_hash(&self, hash: &Vec<u8>) -> Result<ExecutionBlock> {
|
||||||
let block = self.block_hashes.get(hash);
|
let block = self
|
||||||
let payload = self.get_payload(&block.cloned())?;
|
.block_hashes
|
||||||
|
.get(hash)
|
||||||
|
.ok_or(eyre!("Block Not Found"))?;
|
||||||
|
let payload = self.get_payload(&BlockTag::Number(*block))?;
|
||||||
self.execution.get_block(&payload)
|
self.execution.get_block(&payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,22 +190,26 @@ impl Node {
|
||||||
self.consensus.get_header()
|
self.consensus.get_header()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_payload(&self, block: &Option<u64>) -> Result<ExecutionPayload> {
|
fn get_payload(&self, block: &BlockTag) -> Result<ExecutionPayload> {
|
||||||
match block {
|
match block {
|
||||||
Some(block) => {
|
BlockTag::Latest => {
|
||||||
let payload = self.payloads.get(block);
|
let payload = self.payloads.get(&self.latest_block);
|
||||||
match payload {
|
payload.cloned().ok_or(eyre!("Block Not Found"))
|
||||||
Some(payload) => Ok(payload.clone()),
|
|
||||||
None => Err(eyre::eyre!("Block Not Found")),
|
|
||||||
}
|
}
|
||||||
|
BlockTag::Finalized => {
|
||||||
|
let payload = self.payloads.get(&self.finalized_block);
|
||||||
|
payload.cloned().ok_or(eyre!("Block Not Found"))
|
||||||
}
|
}
|
||||||
None => {
|
BlockTag::Number(num) => {
|
||||||
let payload = self.payloads.get(&self.block_head);
|
let payload = self.payloads.get(&num);
|
||||||
match payload {
|
payload.cloned().ok_or(eyre!("Block Not Found"))
|
||||||
Some(payload) => Ok(payload.clone()),
|
|
||||||
None => Err(eyre::eyre!("Block Not Found")),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum BlockTag {
|
||||||
|
Latest,
|
||||||
|
Finalized,
|
||||||
|
Number(u64),
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use jsonrpsee::{
|
||||||
proc_macros::rpc,
|
proc_macros::rpc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::node::Node;
|
use crate::node::{BlockTag, Node};
|
||||||
|
|
||||||
use common::utils::{hex_str_to_bytes, u64_to_hex_string};
|
use common::utils::{hex_str_to_bytes, u64_to_hex_string};
|
||||||
use execution::types::{CallOpts, ExecutionBlock};
|
use execution::types::{CallOpts, ExecutionBlock};
|
||||||
|
@ -242,17 +242,18 @@ fn convert_err<T, E: Display>(res: Result<T, E>) -> Result<T, Error> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decode_block(block: &str) -> Result<Option<u64>> {
|
fn decode_block(block: &str) -> Result<BlockTag> {
|
||||||
match block {
|
match block {
|
||||||
"latest" => Ok(None),
|
"latest" => Ok(BlockTag::Latest),
|
||||||
|
"finalized" => Ok(BlockTag::Finalized),
|
||||||
_ => {
|
_ => {
|
||||||
if block.starts_with("0x") {
|
if block.starts_with("0x") {
|
||||||
Ok(Some(u64::from_str_radix(
|
Ok(BlockTag::Number(u64::from_str_radix(
|
||||||
block.strip_prefix("0x").unwrap(),
|
block.strip_prefix("0x").unwrap(),
|
||||||
16,
|
16,
|
||||||
)?))
|
)?))
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(block.parse()?))
|
Ok(BlockTag::Number(block.parse()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::time::UNIX_EPOCH;
|
||||||
use blst::min_pk::{PublicKey, Signature};
|
use blst::min_pk::{PublicKey, Signature};
|
||||||
use blst::BLST_ERROR;
|
use blst::BLST_ERROR;
|
||||||
use chrono::Duration;
|
use chrono::Duration;
|
||||||
use eyre::Result;
|
use eyre::{eyre, Result};
|
||||||
use log::info;
|
use log::info;
|
||||||
use ssz_rs::prelude::*;
|
use ssz_rs::prelude::*;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
header_hash.to_string() == format!("0x{}", hex::encode(checkpoint_block_root));
|
header_hash.to_string() == format!("0x{}", hex::encode(checkpoint_block_root));
|
||||||
|
|
||||||
if !(header_valid && committee_valid) {
|
if !(header_valid && committee_valid) {
|
||||||
return Err(eyre::eyre!("Invalid Bootstrap"));
|
return Err(eyre!("Invalid Bootstrap"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let store = Store {
|
let store = Store {
|
||||||
|
@ -72,10 +72,20 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
let slot = slot.unwrap_or(self.store.optimistic_header.slot);
|
let slot = slot.unwrap_or(self.store.optimistic_header.slot);
|
||||||
let mut block = self.rpc.get_block(slot).await?.clone();
|
let mut block = self.rpc.get_block(slot).await?.clone();
|
||||||
let block_hash = block.hash_tree_root()?;
|
let block_hash = block.hash_tree_root()?;
|
||||||
let verified_block_hash = self.store.optimistic_header.clone().hash_tree_root()?;
|
|
||||||
|
let latest_slot = self.store.optimistic_header.slot;
|
||||||
|
let finalized_slot = self.store.finalized_header.slot;
|
||||||
|
|
||||||
|
let verified_block_hash = if slot == latest_slot {
|
||||||
|
self.store.optimistic_header.clone().hash_tree_root()?
|
||||||
|
} else if slot == finalized_slot {
|
||||||
|
self.store.finalized_header.clone().hash_tree_root()?
|
||||||
|
} else {
|
||||||
|
return Err(eyre!("Block Not Found"));
|
||||||
|
};
|
||||||
|
|
||||||
if verified_block_hash != block_hash {
|
if verified_block_hash != block_hash {
|
||||||
Err(eyre::eyre!("Block Root Mismatch"))
|
Err(eyre!("Block Root Mismatch"))
|
||||||
} else {
|
} else {
|
||||||
Ok(block.body.execution_payload)
|
Ok(block.body.execution_payload)
|
||||||
}
|
}
|
||||||
|
@ -127,13 +137,13 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
||||||
{
|
{
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(update.signature_slot > update.attested_header.slot
|
if !(update.signature_slot > update.attested_header.slot
|
||||||
&& update.attested_header.slot > update.finalized_header.slot)
|
&& update.attested_header.slot > update.finalized_header.slot)
|
||||||
{
|
{
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let finality_branch_valid = is_finality_proof_valid(
|
let finality_branch_valid = is_finality_proof_valid(
|
||||||
|
@ -143,7 +153,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if !(finality_branch_valid) {
|
if !(finality_branch_valid) {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_committee_branch_valid = is_next_committee_proof_valid(
|
let next_committee_branch_valid = is_next_committee_proof_valid(
|
||||||
|
@ -153,7 +163,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if !next_committee_branch_valid {
|
if !next_committee_branch_valid {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let sync_committee = if store_period == update_signature_period {
|
let sync_committee = if store_period == update_signature_period {
|
||||||
|
@ -169,7 +179,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
let committee_quorum = pks.len() > 1;
|
let committee_quorum = pks.len() > 1;
|
||||||
if !committee_quorum {
|
if !committee_quorum {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let header_root = bytes_to_bytes32(update.attested_header.hash_tree_root()?.as_bytes());
|
let header_root = bytes_to_bytes32(update.attested_header.hash_tree_root()?.as_bytes());
|
||||||
|
@ -178,7 +188,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
||||||
|
|
||||||
if !is_valid_sig {
|
if !is_valid_sig {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -190,13 +200,13 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
||||||
{
|
{
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(update.signature_slot > update.attested_header.slot
|
if !(update.signature_slot > update.attested_header.slot
|
||||||
&& update.attested_header.slot > update.finalized_header.slot)
|
&& update.attested_header.slot > update.finalized_header.slot)
|
||||||
{
|
{
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let finality_branch_valid = is_finality_proof_valid(
|
let finality_branch_valid = is_finality_proof_valid(
|
||||||
|
@ -206,7 +216,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
);
|
);
|
||||||
|
|
||||||
if !(finality_branch_valid) {
|
if !(finality_branch_valid) {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let sync_committee = &self.store.current_sync_committee;
|
let sync_committee = &self.store.current_sync_committee;
|
||||||
|
@ -218,7 +228,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
let committee_quorum = pks.len() > 1;
|
let committee_quorum = pks.len() > 1;
|
||||||
if !committee_quorum {
|
if !committee_quorum {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let header_root =
|
let header_root =
|
||||||
|
@ -228,7 +238,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
||||||
|
|
||||||
if !is_valid_sig {
|
if !is_valid_sig {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -240,11 +250,11 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
if !(update_signature_period == store_period + 1 || update_signature_period == store_period)
|
||||||
{
|
{
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !(update.signature_slot > update.attested_header.slot) {
|
if !(update.signature_slot > update.attested_header.slot) {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let sync_committee = &self.store.current_sync_committee;
|
let sync_committee = &self.store.current_sync_committee;
|
||||||
|
@ -256,7 +266,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
|
|
||||||
let committee_quorum = pks.len() > 1;
|
let committee_quorum = pks.len() > 1;
|
||||||
if !committee_quorum {
|
if !committee_quorum {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let header_root =
|
let header_root =
|
||||||
|
@ -266,7 +276,7 @@ impl<R: Rpc> ConsensusClient<R> {
|
||||||
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
let is_valid_sig = is_aggregate_valid(sig, signing_root.as_bytes(), &pks);
|
||||||
|
|
||||||
if !is_valid_sig {
|
if !is_valid_sig {
|
||||||
return Err(eyre::eyre!("Invalid Update"));
|
return Err(eyre!("Invalid Update"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Reference in New Issue