Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sequencer): rework fee handling #1526

Closed
wants to merge 14 commits into from
51 changes: 7 additions & 44 deletions crates/astria-sequencer/src/accounts/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ use crate::{
},
address::StateReadExt as _,
app::ActionHandler,
assets::{
StateReadExt as _,
StateWriteExt as _,
},
assets::StateReadExt as _,
bridge::StateReadExt as _,
transaction::StateReadExt as _,
};
Expand Down Expand Up @@ -63,50 +60,16 @@ where
S: StateWrite,
TAddress: AddressBytes,
{
let fee = state
.get_transfer_base_fee()
let from = from.address_bytes();
state
.decrease_balance(from, &action.asset, action.amount)
.await
.wrap_err("failed to get transfer base fee")?;
.wrap_err("failed decreasing `from` account balance")?;
state
.get_and_increase_block_fees::<Transfer, _>(&action.fee_asset, fee)
.increase_balance(&action.to, &action.asset, action.amount)
.await
.wrap_err("failed to add to block fees")?;

// if fee payment asset is same asset as transfer asset, deduct fee
// from same balance as asset transferred
if action.asset.to_ibc_prefixed() == action.fee_asset.to_ibc_prefixed() {
// check_stateful should have already checked this arithmetic
let payment_amount = action
.amount
.checked_add(fee)
.expect("transfer amount plus fee should not overflow");

state
.decrease_balance(from, &action.asset, payment_amount)
.await
.wrap_err("failed decreasing `from` account balance")?;
state
.increase_balance(&action.to, &action.asset, action.amount)
.await
.wrap_err("failed increasing `to` account balance")?;
} else {
// otherwise, just transfer the transfer asset and deduct fee from fee asset balance
// later
state
.decrease_balance(from, &action.asset, action.amount)
.await
.wrap_err("failed decreasing `from` account balance")?;
state
.increase_balance(&action.to, &action.asset, action.amount)
.await
.wrap_err("failed increasing `to` account balance")?;
.wrap_err("failed increasing `to` account balance")?;

// deduct fee from fee asset balance
state
.decrease_balance(from, &action.fee_asset, fee)
.await
.wrap_err("failed decreasing `from` account balance for fee payment")?;
}
Ok(())
}

Expand Down
19 changes: 9 additions & 10 deletions crates/astria-sequencer/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,7 @@ use crate::{
StateWriteExt as _,
},
address::StateWriteExt as _,
assets::{
StateReadExt as _,
StateWriteExt as _,
},
assets::StateWriteExt as _,
authority::{
component::{
AuthorityComponent,
Expand All @@ -107,6 +104,10 @@ use crate::{
StateWriteExt as _,
},
component::Component as _,
fees::{
construct_tx_fee_event,
StateReadExt as _,
},
grpc::StateWriteExt as _,
ibc::component::IbcComponent,
mempool::{
Expand Down Expand Up @@ -1169,19 +1170,17 @@ impl App {
let fees = self
.state
.get_block_fees()
.await
.wrap_err("failed to get block fees")?;

for (asset, amount) in fees {
for fee in fees {
state_tx
.increase_balance(fee_recipient, &asset, amount)
.increase_balance(fee_recipient, fee.asset(), fee.amount())
.await
.wrap_err("failed to increase fee recipient balance")?;
let fee_event = construct_tx_fee_event(&fee);
state_tx.record(fee_event);
}

// clear block fees
state_tx.clear_block_fees().await;

let events = self.apply(state_tx);
Ok(abci::response::EndBlock {
validator_updates: validator_updates
Expand Down
3 changes: 2 additions & 1 deletion crates/astria-sequencer/src/app/tests_app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ use crate::{
ValidatorSet,
},
bridge::StateWriteExt as _,
fees::StateReadExt as _,
proposal::commitment::generate_rollup_datas_commitment,
test_utils::{
astria_address,
Expand Down Expand Up @@ -277,7 +278,7 @@ async fn app_transfer_block_fees_to_sudo() {
.unwrap(),
transfer_fee,
);
assert_eq!(app.state.get_block_fees().await.unwrap().len(), 0);
assert_eq!(app.state.get_block_fees().unwrap().len(), 0);
}

#[tokio::test]
Expand Down
54 changes: 28 additions & 26 deletions crates/astria-sequencer/src/app/tests_block_fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ use crate::{
initialize_app,
BOB_ADDRESS,
},
assets::StateReadExt as _,
bridge::{
authority::StateReadExt as _,
bridge::StateWriteExt as _,
fees::{
calculate_base_deposit_fee,
StateWriteExt as _,
},
sequence::{
calculate_fee_from_state,
StateWriteExt as _,
calculate_sequence_action_fee_from_state,
StateReadExt as _,
},
sequence::StateWriteExt as _,
test_utils::{
astria_address,
astria_address_from_hex_string,
Expand Down Expand Up @@ -66,27 +65,33 @@ async fn transaction_execution_records_fee_event() {
.try_build()
.unwrap();
let signed_tx = Arc::new(tx.into_signed(&alice));
let tx_id = signed_tx.id();
app.execute_transaction(signed_tx).await.unwrap();

let events = app.execute_transaction(signed_tx).await.unwrap();
let sudo_address = app.state.get_sudo_address().await.unwrap();
let end_block = app.end_block(1, &sudo_address).await.unwrap();

let events = end_block.events;
let transfer_fee = app.state.get_transfer_base_fee().await.unwrap();
let event = events.first().unwrap();
assert_eq!(event.kind, "tx.fees");
assert_eq!(
event.attributes[0],
("asset", nria().to_string()).index().into()
("asset", nria().to_ibc_prefixed().to_string())
.index()
.into()
);
assert_eq!(
event.attributes[1],
("feeAmount", transfer_fee.to_string()).index().into()
);
assert_eq!(
event.attributes[2],
(
"actionType",
"astria.protocol.transactions.v1alpha1.Transfer"
)
.index()
.into()
("sourceTransactionId", tx_id.to_string(),).index().into()
);
assert_eq!(
event.attributes[3],
("sourceActionIndex", "0",).index().into()
);
}

Expand Down Expand Up @@ -121,10 +126,9 @@ async fn ensure_correct_block_fees_transfer() {
let total_block_fees: u128 = app
.state
.get_block_fees()
.await
.unwrap()
.into_iter()
.map(|(_, fee)| fee)
.map(|fee| fee.amount())
.sum();
assert_eq!(total_block_fees, transfer_base_fee);
}
Expand Down Expand Up @@ -162,12 +166,13 @@ async fn ensure_correct_block_fees_sequence() {
let total_block_fees: u128 = app
.state
.get_block_fees()
.await
.unwrap()
.into_iter()
.map(|(_, fee)| fee)
.map(|fee| fee.amount())
.sum();
let expected_fees = calculate_fee_from_state(&data, &app.state).await.unwrap();
let expected_fees = calculate_sequence_action_fee_from_state(&data, &app.state)
.await
.unwrap();
assert_eq!(total_block_fees, expected_fees);
}

Expand Down Expand Up @@ -205,10 +210,9 @@ async fn ensure_correct_block_fees_init_bridge_acct() {
let total_block_fees: u128 = app
.state
.get_block_fees()
.await
.unwrap()
.into_iter()
.map(|(_, fee)| fee)
.map(|fee| fee.amount())
.sum();
assert_eq!(total_block_fees, init_bridge_account_base_fee);
}
Expand Down Expand Up @@ -271,10 +275,9 @@ async fn ensure_correct_block_fees_bridge_lock() {
let total_block_fees: u128 = app
.state
.get_block_fees()
.await
.unwrap()
.into_iter()
.map(|(_, fee)| fee)
.map(|fee| fee.amount())
.sum();
let expected_fees = transfer_base_fee
+ (calculate_base_deposit_fee(&test_deposit).unwrap() * bridge_lock_byte_cost_multiplier);
Expand Down Expand Up @@ -325,10 +328,9 @@ async fn ensure_correct_block_fees_bridge_sudo_change() {
let total_block_fees: u128 = app
.state
.get_block_fees()
.await
.unwrap()
.into_iter()
.map(|(_, fee)| fee)
.map(|fee| fee.amount())
.sum();
assert_eq!(total_block_fees, sudo_change_base_fee);
}
Expand Down
10 changes: 6 additions & 4 deletions crates/astria-sequencer/src/app/tests_execute_transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ use crate::{
StateReadExt as _,
StateWriteExt as _,
},
fees::calculate_sequence_action_fee_from_state,
ibc::StateReadExt as _,
sequence::calculate_fee_from_state,
test_utils::{
astria_address,
astria_address_from_hex_string,
Expand Down Expand Up @@ -266,7 +266,9 @@ async fn app_execute_transaction_sequence() {
let alice = get_alice_signing_key();
let alice_address = astria_address(&alice.address_bytes());
let data = Bytes::from_static(b"hello world");
let fee = calculate_fee_from_state(&data, &app.state).await.unwrap();
let fee = calculate_sequence_action_fee_from_state(&data, &app.state)
.await
.unwrap();

let tx = UnsignedTransaction::builder()
.actions(vec![
Expand Down Expand Up @@ -757,7 +759,7 @@ async fn app_execute_transaction_bridge_lock_action_ok() {
.get_bridge_lock_byte_cost_multiplier()
.await
.unwrap()
* crate::bridge::calculate_base_deposit_fee(&expected_deposit).unwrap();
* crate::fees::calculate_base_deposit_fee(&expected_deposit).unwrap();
assert_eq!(
app.state
.get_account_balance(&alice_address, &nria())
Expand Down Expand Up @@ -918,7 +920,7 @@ async fn app_stateful_check_fails_insufficient_total_balance() {

// figure out needed fee for a single transfer
let data = Bytes::from_static(b"hello world");
let fee = calculate_fee_from_state(&data, &app.state.clone())
let fee = calculate_sequence_action_fee_from_state(&data, &app.state.clone())
.await
.unwrap();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
source: crates/astria-sequencer/src/assets/state_ext.rs
expression: fee_asset_key(trace_prefixed)
---
fee_asset/ce072174ebc356c6ead681d61ab417ee72fdedd8155eb76478ece374bb04dc1d

Loading
Loading