Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
603c562
test in apps/ledger/storage: test prefix iterators
tzemanovic Dec 16, 2022
f78ee60
storage: remove rev_iter_prefix, which doesn't work as expected
tzemanovic Dec 16, 2022
0d4688d
wasm_for_tests: make
tzemanovic Dec 16, 2022
c25a852
changelog: add #912
tzemanovic Dec 16, 2022
65339b1
[ci] wasm checksums update
github-actions[bot] Dec 17, 2022
5d9f3d7
Add StorageKeys derive macro
sug0 Dec 19, 2022
4ad37a1
Fix gen of identifier in StorageKeys proc-macro
sug0 Dec 19, 2022
028924e
Fix static str type check
sug0 Dec 19, 2022
6612ed8
Update macros/src/lib.rs
sug0 Dec 20, 2022
63a4fea
Update macros/src/lib.rs
sug0 Dec 20, 2022
9ac07db
Added unit test for the new proc macro
batconjurer Dec 20, 2022
306829f
Format and inline some code
sug0 Dec 20, 2022
189e9b6
Some TODO items
sug0 Dec 20, 2022
a74d8e3
Use quote!() in macro test
sug0 Dec 20, 2022
fe53976
Add StorageKeys unit tests
sug0 Dec 20, 2022
32d4f49
Add unit tests for tuple and unit structs as well as enums, on Storag…
sug0 Dec 20, 2022
05eb133
Update macros/src/lib.rs
sug0 Dec 20, 2022
56599b1
Remove allow dead code TODO
sug0 Dec 20, 2022
ad0d2bc
Strip out #[allow(dead_code)] from VALUES
sug0 Dec 20, 2022
73c686d
wasm: update checksums.json
juped Dec 21, 2022
51844e6
core/storage/mockDB: remove unused `reverse_order` flag
tzemanovic Dec 23, 2022
5f219bf
Adds fee burning and checks
grarco Dec 23, 2022
0b51129
Fixes fee value in tx contruction
grarco Dec 23, 2022
b934636
Fixes process proposal fee token
grarco Dec 23, 2022
0081be6
Fixes unit tests
grarco Dec 23, 2022
db0cac3
changelog: add #962
grarco Dec 27, 2022
c20b80f
core/storage_api: use GATs to hide lifetime in StorageRead trait
tzemanovic Dec 27, 2022
c40fd1b
changelog: #966
tzemanovic Dec 27, 2022
dd2d504
core/storage: remove redundant `StorageWrite` impl for mut ref
tzemanovic Dec 27, 2022
c6564c2
[ci] wasm checksums update
github-actions[bot] Dec 27, 2022
842bcd5
Merge branch 'origin/tomas/gats-lifetimes-refactor' (#966)
tzemanovic Dec 28, 2022
02c41e8
Merge branch 'origin/grarco/basic-fee' (#962)
tzemanovic Dec 28, 2022
f7b6378
re-export `namada` from `namada_tests` for `namada_core` dev-deps
tzemanovic Dec 28, 2022
3691e52
core: add faucet PoW logic
tzemanovic Dec 23, 2022
abf5b8e
vp_testnet_faucet: integrate faucet PoW check
tzemanovic Dec 26, 2022
42f6b12
ledger/init_chain: init testnet faucet storage when used
tzemanovic Dec 26, 2022
4354285
wasm: add tx_testnet_faucet_withdrawal
tzemanovic Dec 26, 2022
615a245
storage_api/lazy_map: export `get_data_key` fn for client
tzemanovic Dec 26, 2022
094e63e
ledger/queries/vp/client: add method to get faucet PoW challenge
tzemanovic Dec 26, 2022
a0ba265
client: get a PoW challenge solution for faucet withdrawal transfer
tzemanovic Dec 26, 2022
e75ec2d
genesis: add `faucet_pow_difficulty`
tzemanovic Dec 26, 2022
f796169
test/e2e: add a case to withdraw from PoW faucet
tzemanovic Dec 26, 2022
0d521e0
changelog: add #961
tzemanovic Dec 26, 2022
cd8b45e
wasm/vp_testnet_faucet/test: update tests for PoW challenge
tzemanovic Dec 27, 2022
c7c2b7d
vp_testnet_faucet: R/W withdrawal limit from storage, add to genesis
tzemanovic Dec 28, 2022
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: 3 additions & 0 deletions .changelog/unreleased/bugs/912-remove-prefix-iter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
- Removed 'rev_iter_prefix' from storage API as its implementation
depends on RocksDB and it doesn't work as expected.
([#912](https://github.com/anoma/namada/pull/912))
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/961-faucet-pow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added PoW challenge to testnet faucet withdrawal.
([#961](https://github.com/anoma/namada/pull/961))
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/962-basic-fee.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Added a basic fee implementation for testnet.
([#962](https://github.com/anoma/namada/pull/962))
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Hide the explicit lifetime from StorageRead trait.
([#966](https://github.com/anoma/namada/pull/966))
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use masp_primitives::primitives::ViewingKey;
use masp_primitives::sapling::Node;
use masp_primitives::transaction::components::Amount;
use masp_primitives::zip32::ExtendedFullViewingKey;
use namada::core::ledger::faucet_pow;
use namada::ledger::events::Event;
use namada::ledger::governance::parameters::GovParams;
use namada::ledger::governance::storage as gov_storage;
Expand Down Expand Up @@ -2005,6 +2006,26 @@ pub async fn known_address(
}
}

/// Check if the given address is a testnet faucet account address.
pub async fn is_faucet_account(
address: &Address,
ledger_address: TendermintAddress,
) -> bool {
let client = HttpClient::new(ledger_address).unwrap();
unwrap_client_response(RPC.vp().is_faucet(&client, address).await)
}

/// Obtain a PoW challenge for a withdrawal from a testnet faucet account.
pub async fn get_faucet_pow_challenge(
transfer: Transfer,
ledger_address: TendermintAddress,
) -> faucet_pow::Challenge {
let client = HttpClient::new(ledger_address).unwrap();
unwrap_client_response(
RPC.vp().faucet_pow_challenge(&client, transfer).await,
)
}

/// Accumulate slashes starting from `epoch_start` until (optionally)
/// `withdraw_epoch` and apply them to the token amount `delta`.
fn apply_slashes(
Expand Down
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),
token: ctx.get(&args.fee_token),
},
keypair,
Expand Down
40 changes: 35 additions & 5 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ const TX_VOTE_PROPOSAL: &str = "tx_vote_proposal.wasm";
const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm";
const TX_UPDATE_VP_WASM: &str = "tx_update_vp.wasm";
const TX_TRANSFER_WASM: &str = "tx_transfer.wasm";
const TX_TESTNET_FAUCET_WITHDRAWAL_WASM: &str =
"tx_testnet_faucet_withdrawal.wasm";
const TX_IBC_WASM: &str = "tx_ibc.wasm";
const VP_USER_WASM: &str = "vp_user.wasm";
const TX_BOND_WASM: &str = "tx_bond.wasm";
Expand Down Expand Up @@ -1488,6 +1490,8 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) {
safe_exit(1)
}
}
let is_source_faucet =
rpc::is_faucet_account(&source, args.tx.ledger_address.clone()).await;
// Check that the target address exists on chain
let target_exists =
rpc::known_address(&target, args.tx.ledger_address.clone()).await;
Expand Down Expand Up @@ -1552,7 +1556,6 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) {
}
};

let tx_code = ctx.read_wasm(TX_TRANSFER_WASM);
let masp_addr = masp();
// For MASP sources, use a special sentinel key recognized by VPs as default
// signer. Also, if the transaction is shielded, redact the amount and token
Expand Down Expand Up @@ -1606,6 +1609,15 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) {
if spending_key.is_none() && payment_address.is_none() {
None
} else {
if is_source_faucet {
eprintln!(
"Shielded withdrawals from faucet are not supported"
);
if !args.tx.force {
safe_exit(1)
}
}

// We want to fund our transaction solely from supplied spending
// key
let spending_key = spending_key.map(|x| x.into());
Expand Down Expand Up @@ -1643,11 +1655,29 @@ pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) {
},
};
tracing::debug!("Transfer data {:?}", transfer);
let data = transfer
.try_to_vec()
.expect("Encoding tx data shouldn't fail");

let tx = Tx::new(tx_code, Some(data));
let tx = if is_source_faucet {
// Obtain a PoW challenge for faucet withdrawal
let challenge = rpc::get_faucet_pow_challenge(
transfer,
args.tx.ledger_address.clone(),
)
.await;
// Solve the solution, this blocks until a solution is found
let solution = challenge.solve();
let data = solution
.try_to_vec()
.expect("Encoding tx data shouldn't fail");
let tx_code = ctx.read_wasm(TX_TESTNET_FAUCET_WITHDRAWAL_WASM);
Tx::new(tx_code, Some(data))
} else {
let data = transfer
.try_to_vec()
.expect("Encoding tx data shouldn't fail");
let tx_code = ctx.read_wasm(TX_TRANSFER_WASM);
Tx::new(tx_code, Some(data))
};

let signing_address = TxSigningKey::WalletAddress(args.source.to_address());
process_tx(ctx, &args.tx, tx, signing_address).await;
}
Expand Down
14 changes: 14 additions & 0 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::path::Path;

use borsh::{BorshDeserialize, BorshSerialize};
use derivative::Derivative;
use namada::core::ledger::faucet_pow;
use namada::ledger::governance::parameters::GovParams;
use namada::ledger::parameters::EpochDuration;
use namada::ledger::pos::{GenesisValidator, PosParams};
Expand All @@ -28,6 +29,7 @@ pub mod genesis_config {

use data_encoding::HEXLOWER;
use eyre::Context;
use namada::core::ledger::faucet_pow;
use namada::ledger::governance::parameters::GovParams;
use namada::ledger::parameters::EpochDuration;
use namada::ledger::pos::{GenesisValidator, PosParams};
Expand Down Expand Up @@ -109,6 +111,10 @@ pub mod genesis_config {
// Name of the native token - this must one of the tokens included in
// the `token` field
pub native_token: String,
/// Faucet PoW difficulty - defaults to `0` when not set
pub faucet_pow_difficulty: Option<faucet_pow::Difficulty>,
/// Faucet withdrawal limit - defaults to 1000 NAM when not set
pub faucet_withdrawal_limit: Option<token::Amount>,
// Initial validator set
pub validator: HashMap<String, ValidatorConfig>,
// Token accounts present at genesis
Expand Down Expand Up @@ -495,6 +501,8 @@ pub mod genesis_config {
let GenesisConfig {
genesis_time,
native_token,
faucet_pow_difficulty,
faucet_withdrawal_limit,
validator,
token,
established,
Expand Down Expand Up @@ -630,6 +638,8 @@ pub mod genesis_config {
let mut genesis = Genesis {
genesis_time: genesis_time.try_into().unwrap(),
native_token,
faucet_pow_difficulty,
faucet_withdrawal_limit,
validators: validators.into_values().collect(),
token_accounts,
established_accounts: established_accounts.into_values().collect(),
Expand Down Expand Up @@ -678,6 +688,8 @@ pub mod genesis_config {
pub struct Genesis {
pub genesis_time: DateTimeUtc,
pub native_token: Address,
pub faucet_pow_difficulty: Option<faucet_pow::Difficulty>,
pub faucet_withdrawal_limit: Option<token::Amount>,
pub validators: Vec<Validator>,
pub token_accounts: Vec<TokenAccount>,
pub established_accounts: Vec<EstablishedAccount>,
Expand Down Expand Up @@ -952,6 +964,8 @@ pub fn genesis() -> Genesis {
pos_params: PosParams::default(),
gov_params: GovParams::default(),
native_token: address::nam(),
faucet_pow_difficulty: None,
faucet_withdrawal_limit: None,
}
}

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,
&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
Loading