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

Testnet fees #962

Merged
merged 6 commits into from
Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/src/lib/client/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use namada::proto::Tx;
use namada::types::address::{Address, ImplicitAddress};
use namada::types::key::*;
use namada::types::storage::Epoch;
use namada::types::token::Amount;
use namada::types::transaction::{hash_tx, Fee, WrapperTx};

use super::rpc;
Expand Down Expand Up @@ -174,7 +175,7 @@ pub async fn sign_wrapper(
let tx = {
WrapperTx::new(
Fee {
amount: args.fee_amount,
amount: Amount::from(100),
tzemanovic marked this conversation as resolved.
Show resolved Hide resolved
token: ctx.get(&args.fee_token),
},
keypair,
Expand Down
109 changes: 102 additions & 7 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

use namada::ledger::pos::types::into_tm_voting_power;
use namada::ledger::protocol;
use namada::ledger::storage::write_log::StorageModification;
use namada::ledger::storage_api::StorageRead;
use namada::types::storage::{BlockHash, BlockResults, Header};
use namada::types::token::Amount;

use super::governance::execute_governance_proposals;
use super::*;
Expand Down Expand Up @@ -128,9 +131,80 @@ where
}

let mut tx_event = match &tx_type {
TxType::Wrapper(_wrapper) => {
self.storage.tx_queue.push(_wrapper.clone());
Event::new_tx_event(&tx_type, height.0)
TxType::Wrapper(wrapper) => {
let mut tx_event = Event::new_tx_event(&tx_type, height.0);

// Charge fee
let fee_payer =
if wrapper.pk != address::masp_tx_key().ref_to() {
wrapper.fee_payer()
} else {
address::masp()
};

let balance_key = token::balance_key(
&self.storage.native_token,
tzemanovic marked this conversation as resolved.
Show resolved Hide resolved
&fee_payer,
);
let balance: Amount =
match self.write_log.read(&balance_key).0 {
Some(wal_mod) => {
// Read from WAL
if let StorageModification::Write { value } =
wal_mod
{
Amount::try_from_slice(value).unwrap()
} else {
Amount::default()
}
}
None => {
// Read from storage
let balance = StorageRead::read(
&self.storage,
&balance_key,
);
// Storage read must not fail, but there might
// be no value, in which
// case default (0) is returned
balance
.expect(
"Storage read in the protocol must \
not fail",
)
.unwrap_or_default()
}
};

let balance: u64 = balance.into();
match balance.checked_sub(100) {
Some(v) => {
self.write_log
.write(
&balance_key,
Amount::from(v).try_to_vec().unwrap(),
)
.unwrap();
}
None => {
// Burn remaining funds
self.write_log
.write(
&balance_key,
Amount::from(0).try_to_vec().unwrap(),
)
.unwrap();
tx_event["log"] =
"Insufficient balance for fee".into();
tx_event["code"] = ErrorCodes::InvalidTx.into();

response.events.push(tx_event);
continue;
}
}

self.storage.tx_queue.push(wrapper.clone());
tx_event
}
TxType::Decrypted(inner) => {
// We remove the corresponding wrapper tx from the queue
Expand Down Expand Up @@ -348,15 +422,26 @@ mod test_finalize_block {
let keypair = gen_keypair();
let mut processed_txs = vec![];
let mut valid_wrappers = vec![];

// Add unshielded balance for fee paymenty
let balance_key = token::balance_key(
&shell.storage.native_token,
&Address::from(&keypair.ref_to()),
);
shell
.storage
.write(&balance_key, Amount::from(1000).try_to_vec().unwrap())
.unwrap();

// create some wrapper txs
for i in 1..5 {
for i in 1u64..5 {
let raw_tx = Tx::new(
"wasm_code".as_bytes().to_owned(),
Some(format!("transaction data: {}", i).as_bytes().to_owned()),
);
let wrapper = WrapperTx::new(
Fee {
amount: i.into(),
amount: 100.into(),
token: shell.storage.native_token.clone(),
},
&keypair,
Expand Down Expand Up @@ -529,6 +614,16 @@ mod test_finalize_block {
let mut processed_txs = vec![];
let mut valid_txs = vec![];

// Add unshielded balance for fee paymenty
let balance_key = token::balance_key(
&shell.storage.native_token,
&Address::from(&keypair.ref_to()),
);
shell
.storage
.write(&balance_key, Amount::from(1000).try_to_vec().unwrap())
.unwrap();

// create two decrypted txs
let mut wasm_path = top_level_directory();
wasm_path.push("wasm_for_tests/tx_no_op.wasm");
Expand All @@ -545,7 +640,7 @@ mod test_finalize_block {
);
let wrapper_tx = WrapperTx::new(
Fee {
amount: 0.into(),
amount: 100.into(),
token: shell.storage.native_token.clone(),
},
&keypair,
Expand Down Expand Up @@ -576,7 +671,7 @@ mod test_finalize_block {
);
let wrapper_tx = WrapperTx::new(
Fee {
amount: 0.into(),
amount: 100.into(),
token: shell.storage.native_token.clone(),
},
&keypair,
Expand Down
28 changes: 26 additions & 2 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,17 @@ use namada::ledger::storage::{
};
use namada::ledger::{ibc, pos, protocol};
use namada::proto::{self, Tx};
use namada::types::address;
use namada::types::address::{masp, masp_tx_key, Address};
use namada::types::chain::ChainId;
use namada::types::key::*;
use namada::types::storage::{BlockHeight, Key, TxIndex};
use namada::types::time::{DateTimeUtc, TimeZone, Utc};
use namada::types::token::{self, Amount};
use namada::types::transaction::{
hash_tx, process_tx, verify_decrypted_correctly, AffineCurve, DecryptedTx,
EllipticCurve, PairingEngine, TxType, WrapperTx,
};
use namada::types::{address, token};
use namada::vm::wasm::{TxCache, VpCache};
use namada::vm::WasmCacheRwAccess;
use num_derive::{FromPrimitive, ToPrimitive};
Expand Down Expand Up @@ -575,7 +576,30 @@ where
) -> response::CheckTx {
let mut response = response::CheckTx::default();
match Tx::try_from(tx_bytes).map_err(Error::TxDecoding) {
Ok(_) => response.log = String::from("Mempool validation passed"),
Ok(tx) => {
// Check balance for fee
if let Ok(TxType::Wrapper(wrapper)) = process_tx(tx) {
let fee_payer = if wrapper.pk != masp_tx_key().ref_to() {
wrapper.fee_payer()
} else {
masp()
};
// check that the fee payer has sufficient balance
let balance = self
.get_balance(&self.storage.native_token, &fee_payer);
tzemanovic marked this conversation as resolved.
Show resolved Hide resolved

if Amount::from(100) > balance {
response.code = 1;
response.log = String::from(
"The address given does not have sufficient \
balance to pay fee",
);
return response;
}
}

response.log = String::from("Mempool validation passed");
}
Err(msg) => {
response.code = 1;
response.log = msg.to_string();
Expand Down
17 changes: 14 additions & 3 deletions apps/src/lib/node/ledger/shell/process_proposal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,12 @@ where
masp()
};
// check that the fee payer has sufficient balance
let balance =
self.get_balance(&tx.fee.token, &fee_payer);
let balance = self.get_balance(
&self.storage.native_token,
&fee_payer,
);

if tx.fee.amount <= balance {
if Amount::from(100) <= balance {
TxResult {
code: ErrorCodes::Ok.into(),
info: "Process proposal accepted this \
Expand Down Expand Up @@ -398,6 +400,15 @@ mod test_process_proposal {
..Default::default()
});
let keypair = crate::wallet::defaults::daewon_keypair();
// reduce address balance to match the 100 token fee
let balance_key = token::balance_key(
&shell.storage.native_token,
tzemanovic marked this conversation as resolved.
Show resolved Hide resolved
&Address::from(&keypair.ref_to()),
);
shell
.storage
.write(&balance_key, Amount::from(99).try_to_vec().unwrap())
.unwrap();

let tx = Tx::new(
"wasm_code".as_bytes().to_owned(),
Expand Down