Skip to content

Commit 0bb2c6f

Browse files
committed
fix test
reset gas_price to 1_000 or diff between actual gas and encoded are too high for small tx
1 parent 50232db commit 0bb2c6f

File tree

1 file changed

+64
-59
lines changed

1 file changed

+64
-59
lines changed

substrate/frame/revive/src/evm/runtime.rs

Lines changed: 64 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type CallOf<T> = <T as frame_system::Config>::RuntimeCall;
5454
/// - Not too high, ensuring the gas value is large enough (at least 7 digits) to encode the
5555
/// ref_time, proof_size, and deposit into the less significant (6 lower) digits of the gas value.
5656
/// - Not too low, enabling users to adjust the gas price to define a tip.
57-
pub const GAS_PRICE: u32 = 100_000u32;
57+
pub const GAS_PRICE: u32 = 1_000u32;
5858

5959
/// Convert a `Balance` into a gas value, using the fixed `GAS_PRICE`.
6060
/// The gas is calculated as `balance / GAS_PRICE`, rounded up to the nearest integer.
@@ -324,6 +324,11 @@ pub trait EthExtra {
324324
let GenericTransaction { nonce, chain_id, to, value, input, gas, gas_price, .. } =
325325
GenericTransaction::from_signed(tx, None);
326326

327+
let Some(gas) = gas else {
328+
log::debug!(target: LOG_TARGET, "No gas provided");
329+
return Err(InvalidTransaction::Call);
330+
};
331+
327332
if chain_id.unwrap_or_default() != <Self::Config as Config>::ChainId::get().into() {
328333
log::debug!(target: LOG_TARGET, "Invalid chain_id {chain_id:?}");
329334
return Err(InvalidTransaction::Call);
@@ -337,13 +342,11 @@ pub trait EthExtra {
337342

338343
let data = input.unwrap_or_default().0;
339344

340-
let (gas_limit, storage_deposit_limit) = <Self::Config as Config>::EthGasEncoder::decode(
341-
gas.unwrap_or_default(),
342-
)
343-
.ok_or_else(|| {
344-
log::debug!(target: LOG_TARGET, "Failed to decode gas: {gas:?}");
345-
InvalidTransaction::Call
346-
})?;
345+
let (gas_limit, storage_deposit_limit) =
346+
<Self::Config as Config>::EthGasEncoder::decode(gas).ok_or_else(|| {
347+
log::debug!(target: LOG_TARGET, "Failed to decode gas: {gas:?}");
348+
InvalidTransaction::Call
349+
})?;
347350

348351
let call = if let Some(dest) = to {
349352
crate::Call::call::<Self::Config> {
@@ -380,13 +383,13 @@ pub trait EthExtra {
380383
// Fees calculated with the fixed `GAS_PRICE`
381384
// When we dry-run the transaction, we set the gas to `Fee / GAS_PRICE`
382385
let eth_fee_no_tip = U256::from(GAS_PRICE)
383-
.saturating_mul(gas.unwrap_or_default())
386+
.saturating_mul(gas)
384387
.try_into()
385388
.map_err(|_| InvalidTransaction::Call)?;
386389

387390
// Fees with the actual gas_price from the transaction.
388391
let eth_fee: BalanceOf<Self::Config> = U256::from(gas_price.unwrap_or_default())
389-
.saturating_mul(gas.unwrap_or_default())
392+
.saturating_mul(gas)
390393
.try_into()
391394
.map_err(|_| InvalidTransaction::Call)?;
392395

@@ -411,7 +414,8 @@ pub trait EthExtra {
411414
}
412415

413416
if eth_fee_no_tip > actual_fee.saturating_mul(2u32.into()) {
414-
log::debug!(target: LOG_TARGET, "actual fees: {actual_fee:?} too high, base eth fees: {eth_fee_no_tip:?}");
417+
log::debug!(target: LOG_TARGET, "actual fees: {actual_fee:?} too high, base eth fees:
418+
{eth_fee_no_tip:?}");
415419
return Err(InvalidTransaction::Call.into())
416420
}
417421

@@ -473,8 +477,6 @@ mod test {
473477
#[derive(Clone)]
474478
struct UncheckedExtrinsicBuilder {
475479
tx: GenericTransaction,
476-
gas_limit: Weight,
477-
storage_deposit_limit: BalanceOf<Test>,
478480
before_validate: Option<std::sync::Arc<dyn Fn() + Send + Sync>>,
479481
}
480482

@@ -488,8 +490,6 @@ mod test {
488490
gas_price: Some(U256::from(GAS_PRICE)),
489491
..Default::default()
490492
},
491-
gas_limit: Weight::zero(),
492-
storage_deposit_limit: 0,
493493
before_validate: None,
494494
}
495495
}
@@ -506,11 +506,6 @@ mod test {
506506
Ok(dry_run) => {
507507
log::debug!(target: LOG_TARGET, "Estimated gas: {:?}", dry_run.eth_gas);
508508
self.tx.gas = Some(dry_run.eth_gas);
509-
let (gas_limit, deposit) =
510-
<<Test as Config>::EthGasEncoder as GasEncoder<_>>::decode(dry_run.eth_gas)
511-
.unwrap();
512-
self.gas_limit = gas_limit;
513-
self.storage_deposit_limit = deposit;
514509
},
515510
Err(err) => {
516511
log::debug!(target: LOG_TARGET, "Failed to estimate gas: {:?}", err);
@@ -522,31 +517,35 @@ mod test {
522517
fn call_with(dest: H160) -> Self {
523518
let mut builder = Self::new();
524519
builder.tx.to = Some(dest);
525-
ExtBuilder::default().build().execute_with(|| builder.estimate_gas());
526520
builder
527521
}
528522

529523
/// Create a new builder with an instantiate call.
530524
fn instantiate_with(code: Vec<u8>, data: Vec<u8>) -> Self {
531525
let mut builder = Self::new();
532526
builder.tx.input = Some(Bytes(code.into_iter().chain(data.into_iter()).collect()));
533-
ExtBuilder::default().build().execute_with(|| builder.estimate_gas());
534527
builder
535528
}
536529

537-
/// Update the transaction with the given function.
538-
fn update(mut self, f: impl FnOnce(&mut GenericTransaction) -> ()) -> Self {
539-
f(&mut self.tx);
540-
self
541-
}
542530
/// Set before_validate function.
543531
fn before_validate(mut self, f: impl Fn() + Send + Sync + 'static) -> Self {
544532
self.before_validate = Some(std::sync::Arc::new(f));
545533
self
546534
}
547535

536+
fn check(
537+
self,
538+
) -> Result<(RuntimeCall, SignedExtra, GenericTransaction), TransactionValidityError> {
539+
self.mutate_estimate_and_check(Box::new(|_| ()))
540+
}
541+
548542
/// Call `check` on the unchecked extrinsic, and `pre_dispatch` on the signed extension.
549-
fn check(&self) -> Result<(RuntimeCall, SignedExtra), TransactionValidityError> {
543+
fn mutate_estimate_and_check(
544+
mut self,
545+
f: Box<dyn FnOnce(&mut GenericTransaction) -> ()>,
546+
) -> Result<(RuntimeCall, SignedExtra, GenericTransaction), TransactionValidityError> {
547+
ExtBuilder::default().build().execute_with(|| self.estimate_gas());
548+
f(&mut self.tx);
550549
ExtBuilder::default().build().execute_with(|| {
551550
let UncheckedExtrinsicBuilder { tx, before_validate, .. } = self.clone();
552551

@@ -557,8 +556,9 @@ mod test {
557556
100_000_000_000_000,
558557
);
559558

560-
let payload =
561-
account.sign_transaction(tx.try_into_unsigned().unwrap()).signed_payload();
559+
let payload = account
560+
.sign_transaction(tx.clone().try_into_unsigned().unwrap())
561+
.signed_payload();
562562
let call = RuntimeCall::Contracts(crate::Call::eth_transact { payload });
563563

564564
let encoded_len = call.encoded_size();
@@ -578,22 +578,26 @@ mod test {
578578
0,
579579
)?;
580580

581-
Ok((result.function, extra))
581+
Ok((result.function, extra, tx))
582582
})
583583
}
584584
}
585585

586586
#[test]
587587
fn check_eth_transact_call_works() {
588588
let builder = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]));
589+
let (call, _, tx) = builder.check().unwrap();
590+
let (gas_limit, storage_deposit_limit) =
591+
<<Test as Config>::EthGasEncoder as GasEncoder<_>>::decode(tx.gas.unwrap()).unwrap();
592+
589593
assert_eq!(
590-
builder.check().unwrap().0,
594+
call,
591595
crate::Call::call::<Test> {
592-
dest: builder.tx.to.unwrap(),
593-
value: builder.tx.value.unwrap_or_default().as_u64(),
594-
gas_limit: builder.gas_limit,
595-
storage_deposit_limit: builder.storage_deposit_limit,
596-
data: builder.tx.input.unwrap_or_default().0
596+
dest: tx.to.unwrap(),
597+
value: tx.value.unwrap_or_default().as_u64(),
598+
data: tx.input.unwrap_or_default().0,
599+
gas_limit,
600+
storage_deposit_limit
597601
}
598602
.into()
599603
);
@@ -604,28 +608,30 @@ mod test {
604608
let (code, _) = compile_module("dummy").unwrap();
605609
let data = vec![];
606610
let builder = UncheckedExtrinsicBuilder::instantiate_with(code.clone(), data.clone());
611+
let (call, _, tx) = builder.check().unwrap();
612+
let (gas_limit, storage_deposit_limit) =
613+
<<Test as Config>::EthGasEncoder as GasEncoder<_>>::decode(tx.gas.unwrap()).unwrap();
607614

608615
assert_eq!(
609-
builder.check().unwrap().0,
616+
call,
610617
crate::Call::instantiate_with_code::<Test> {
611-
value: builder.tx.value.unwrap_or_default().as_u64(),
612-
gas_limit: builder.gas_limit,
613-
storage_deposit_limit: builder.storage_deposit_limit,
618+
value: tx.value.unwrap_or_default().as_u64(),
614619
code,
615620
data,
616-
salt: None
621+
salt: None,
622+
gas_limit,
623+
storage_deposit_limit
617624
}
618625
.into()
619626
);
620627
}
621628

622629
#[test]
623630
fn check_eth_transact_nonce_works() {
624-
let builder = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]))
625-
.update(|tx| tx.nonce = Some(1u32.into()));
631+
let builder = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]));
626632

627633
assert_eq!(
628-
builder.check(),
634+
builder.mutate_estimate_and_check(Box::new(|tx| tx.nonce = Some(1u32.into()))),
629635
Err(TransactionValidityError::Invalid(InvalidTransaction::Future))
630636
);
631637

@@ -642,11 +648,10 @@ mod test {
642648

643649
#[test]
644650
fn check_eth_transact_chain_id_works() {
645-
let builder = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]))
646-
.update(|tx| tx.chain_id = Some(42.into()));
651+
let builder = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]));
647652

648653
assert_eq!(
649-
builder.check(),
654+
builder.mutate_estimate_and_check(Box::new(|tx| tx.chain_id = Some(42.into()))),
650655
Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
651656
);
652657
}
@@ -659,7 +664,7 @@ mod test {
659664

660665
// Fail because the tx input fail to get the blob length
661666
assert_eq!(
662-
builder.clone().update(|tx| tx.input = Some(Bytes(vec![1, 2, 3]))).check(),
667+
builder.mutate_estimate_and_check(Box::new(|tx| tx.input = Some(Bytes(vec![1, 2, 3])))),
663668
Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
664669
);
665670
}
@@ -691,27 +696,27 @@ mod test {
691696
];
692697

693698
for (msg, update_tx, err) in scenarios {
694-
let builder =
695-
UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20])).update(update_tx);
699+
let res = UncheckedExtrinsicBuilder::call_with(H160::from([1u8; 20]))
700+
.mutate_estimate_and_check(update_tx);
696701

697-
assert_eq!(builder.check(), Err(TransactionValidityError::Invalid(err)), "{}", msg);
702+
assert_eq!(res, Err(TransactionValidityError::Invalid(err)), "{}", msg);
698703
}
699704
}
700705

701706
#[test]
702707
fn check_transaction_tip() {
703708
let (code, _) = compile_module("dummy").unwrap();
704709
let data = vec![];
705-
let builder = UncheckedExtrinsicBuilder::instantiate_with(code.clone(), data.clone())
706-
.update(|tx| {
707-
tx.gas_price = Some(tx.gas_price.unwrap() * 103 / 100);
708-
log::debug!(target: LOG_TARGET, "Gas price: {:?}", tx.gas_price);
709-
});
710+
let (_, extra, tx) =
711+
UncheckedExtrinsicBuilder::instantiate_with(code.clone(), data.clone())
712+
.mutate_estimate_and_check(Box::new(|tx| {
713+
tx.gas_price = Some(tx.gas_price.unwrap() * 103 / 100);
714+
log::debug!(target: LOG_TARGET, "Gas price: {:?}", tx.gas_price);
715+
}))
716+
.unwrap();
710717

711-
let tx = &builder.tx;
712718
let expected_tip =
713719
tx.gas_price.unwrap() * tx.gas.unwrap() - U256::from(GAS_PRICE) * tx.gas.unwrap();
714-
let (_, extra) = builder.check().unwrap();
715720
assert_eq!(U256::from(extra.1.tip()), expected_tip);
716721
}
717722
}

0 commit comments

Comments
 (0)