Skip to content

Commit

Permalink
Fix check gasprice for airdao txs
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewAR2 committed Dec 4, 2024
1 parent 73c1ea5 commit 1f0af89
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 47 deletions.
7 changes: 4 additions & 3 deletions crates/ethcore/src/engines/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -660,10 +660,11 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> {
&self,
t: UnverifiedTransaction,
header: &Header,
gas_price: Option<U256>,
current_block_reward_address: Option<Address>,
gas_price: Option<U256>,
current_block_reward_address: Option<Address>,
current_fees_address: Option<Address>,
) -> Result<SignedTransaction, transaction::Error> {
self.machine().verify_transaction_unordered(t, header, gas_price, current_block_reward_address)
self.machine().verify_transaction_unordered(t, header, gas_price, current_block_reward_address, current_fees_address)
}

/// Perform basic/cheap transaction verification.
Expand Down
110 changes: 67 additions & 43 deletions crates/ethcore/src/machine/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,52 +376,76 @@ impl EthereumMachine {
&self,
t: UnverifiedTransaction,
header: &Header,
gas_price: Option<U256>,
current_block_reward_addr: Option<Address>,
gas_price: Option<U256>,
current_block_reward_addr: Option<Address>,
current_fees_addr: Option<Address>,
) -> Result<SignedTransaction, transaction::Error> {
// Cheching block reward transaction. It should be verified with zero gas price
// all other should pay at least minimal gas price
// Check transaction sended by the block author
let public = t.recover_public()?;
let sender = public_to_address(&public);
let sended_by_block_author = sender == *header.author();

//Check if transaction has block reward specific data
let has_reward_data = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
tx.data == vec![0xc3, 0x3f, 0xb8, 0x77]
}
_ => false,
};

//Check if transaction calling the correct contract
let calling_block_reward = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
match tx.action {
Action::Call(addr) => {
if let Some(reward_address) = current_block_reward_addr {
addr == reward_address
} else {
false
}
}
_ => false,
}
}
_ => false,
};

let is_block_reward_tx = sended_by_block_author && has_reward_data && calling_block_reward;

if !is_block_reward_tx {
if let Some(price) = gas_price {
if t.tx().gas_price < price {
return Err(transaction::Error::InsufficientGas { minimal: price, got: t.tx().gas_price });
}
}
}
// Cheching block reward transaction. It should be verified with zero gas price
// all other should pay at least minimal gas price
// Check transaction sended by the block author
let public = t.recover_public()?;
let sender = public_to_address(&public);
let sended_by_block_author = sender == *header.author();

//Check if transaction has block reward specific data
let has_reward_data = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
tx.data == vec![0xc3, 0x3f, 0xb8, 0x77]
}
_ => false,
};

//Check if transaction has fees specific data
let has_fees_data = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
tx.data == vec![0x57, 0xc3, 0xc9, 0xfb]
}
_ => false,
};

//Check if transaction calling the block reward contract
let calling_block_reward = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
match tx.action {
Action::Call(addr) => {
if let Some(reward_address) = current_block_reward_addr {
addr == reward_address
} else {
false
}
}
_ => false,
}
}
_ => false,
};

//Check if transaction calling the fees contract
let calling_fees = match t.as_unsigned() {
TypedTransaction::Legacy(tx) => {
match tx.action {
Action::Call(addr) => {
if let Some(fees_address) = current_fees_addr {
addr == fees_address
} else {
false
}
}
_ => false,
}
}
_ => false,
};

let is_airdao_tx = sended_by_block_author && ((has_reward_data && calling_block_reward) || (has_fees_data && calling_fees));

if !is_airdao_tx {
if let Some(price) = gas_price {
if t.tx().gas_price < price {
return Err(transaction::Error::InsufficientGas { minimal: price, got: t.tx().gas_price });
}
}
}

// ensure that the user was willing to at least pay the base fee
if t.tx().gas_price < header.base_fee().unwrap_or_default() && !t.has_zero_gas_price() {
Expand Down
3 changes: 2 additions & 1 deletion crates/ethcore/src/verification/verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,15 @@ pub fn verify_block_unordered(

let latest_gas_price = engine.get_gas_price(&header);
let current_block_reward_address = engine.current_block_reward_address(&header);
let current_fees_address = engine.current_fees_address(&header);

// t_nb 5.3 iterate over all transactions
let transactions = block
.transactions
.into_iter()
.map(|t| {
// t_nb 5.3.1 call verify_unordered. Check signatures and calculate address
let t = engine.verify_transaction_unordered(t, &header, latest_gas_price, current_block_reward_address)?;
let t = engine.verify_transaction_unordered(t, &header, latest_gas_price, current_block_reward_address, current_fees_address)?;
// t_nb 5.3.2 check if nonce is more then max nonce (EIP-168 and EIP169)
if let Some(max_nonce) = nonce_cap {
if t.tx().nonce >= max_nonce {
Expand Down

0 comments on commit 1f0af89

Please sign in to comment.