Skip to content

Commit

Permalink
Merge branch 'tiago/tx-memo-field' (#2358)
Browse files Browse the repository at this point in the history
* origin/tiago/tx-memo-field:
  Changelog for #2358
  Regen pre-genesis tx signatures
  Rebuild test wasms
  Add tx memo CLI arg
  Attach memo to tx if it is present in sdk args
  Add memo to the sdk's tx args
  Extend transactions with memo sections
  • Loading branch information
brentstone committed Jan 12, 2024
2 parents cc71421 + 204803c commit e08e2a0
Show file tree
Hide file tree
Showing 26 changed files with 88 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .changelog/unreleased/SDK/2358-tx-memo-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add optional memo field to transaction args.
([\#2358](https://github.com/anoma/namada/pull/2358))
2 changes: 2 additions & 0 deletions .changelog/unreleased/improvements/2358-tx-memo-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Introduce a memo field, to allow including arbitrary data inside of
transactions. ([\#2358](https://github.com/anoma/namada/pull/2358))
9 changes: 9 additions & 0 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2965,6 +2965,7 @@ pub mod args {
pub const MAX_COMMISSION_RATE_CHANGE: Arg<Dec> =
arg("max-commission-rate-change");
pub const MAX_ETH_GAS: ArgOpt<u64> = arg_opt("max_eth-gas");
pub const MEMO_OPT: ArgOpt<String> = arg_opt("memo");
pub const MODE: ArgOpt<String> = arg_opt("mode");
pub const NET_ADDRESS: Arg<SocketAddr> = arg("net-address");
pub const NAMADA_START_TIME: ArgOpt<DateTimeUtc> = arg_opt("time");
Expand Down Expand Up @@ -5848,6 +5849,7 @@ pub mod args {
.chain_id
.or_else(|| Some(ctx.config.ledger.chain_id.clone())),
wrapper_fee_payer: self.wrapper_fee_payer.map(|x| ctx.get(&x)),
memo: self.memo,
use_device: self.use_device,
}
}
Expand Down Expand Up @@ -5962,6 +5964,11 @@ pub mod args {
"Use an attached hardware wallet device to sign the \
transaction.",
))
.arg(
MEMO_OPT
.def()
.help("Attach a plaintext memo to the transaction."),
)
}

fn parse(matches: &ArgMatches) -> Self {
Expand All @@ -5986,6 +5993,7 @@ pub mod args {
let tx_reveal_code_path = PathBuf::from(TX_REVEAL_PK);
let chain_id = CHAIN_ID_OPT.parse(matches);
let password = None;
let memo = MEMO_OPT.parse(matches).map(String::into_bytes);
let wrapper_fee_payer = FEE_PAYER_OPT.parse(matches);
let output_folder = OUTPUT_FOLDER_PATH.parse(matches);
let use_device = USE_DEVICE.parse(matches);
Expand All @@ -6011,6 +6019,7 @@ pub mod args {
chain_id,
wrapper_fee_payer,
output_folder,
memo,
use_device,
}
}
Expand Down
1 change: 1 addition & 0 deletions apps/src/lib/config/genesis/transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fn get_tx_args(use_device: bool) -> TxArgs {
signatures: vec![],
tx_reveal_code_path: Default::default(),
password: None,
memo: None,
use_device,
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/proto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod types;

pub use types::{
standalone_signature, verify_standalone_sig, Code, Commitment,
CompressedSignature, Data, Error, Header, MaspBuilder, Section,
CompressedSignature, Data, Error, Header, MaspBuilder, Memo, Section,
SerializeWithBorsh, Signable, SignableEthMessage, Signature,
SignatureIndex, Signed, Signer, Tx, TxError,
};
Expand Down
45 changes: 45 additions & 0 deletions core/src/proto/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ impl Code {
}
}

pub type Memo = Vec<u8>;

#[derive(
Clone,
Debug,
Expand Down Expand Up @@ -974,6 +976,11 @@ pub struct Header {
pub code_hash: crate::types::hash::Hash,
/// The SHA-256 hash of the transaction's data section
pub data_hash: crate::types::hash::Hash,
/// The SHA-256 hash of the transaction's memo section
///
/// In case a memo is not present in the transaction, a
/// byte array filled with zeroes is present instead
pub memo_hash: crate::types::hash::Hash,
/// The type of this transaction
pub tx_type: TxType,
}
Expand All @@ -988,6 +995,7 @@ impl Header {
timestamp: DateTimeUtc::now(),
code_hash: crate::types::hash::Hash::default(),
data_hash: crate::types::hash::Hash::default(),
memo_hash: crate::types::hash::Hash::default(),
}
}

Expand Down Expand Up @@ -1169,6 +1177,31 @@ impl Tx {
None
}

/// Set the transaction memo hash stored in the header
pub fn set_memo_sechash(&mut self, hash: crate::types::hash::Hash) {
self.header.memo_hash = hash;
}

/// Get the hash of this transaction's memo from the heeader
pub fn memo_sechash(&self) -> &crate::types::hash::Hash {
&self.header.memo_hash
}

/// Get the memo designated by the memo hash in the header
pub fn memo(&self) -> Option<Vec<u8>> {
if self.memo_sechash() == &crate::types::hash::Hash::default() {
return None;
}
match self
.get_section(self.memo_sechash())
.as_ref()
.map(Cow::as_ref)
{
Some(Section::ExtraData(section)) => section.code.id(),
_ => None,
}
}

/// Add a new section to the transaction
pub fn add_section(&mut self, section: Section) -> &mut Section {
self.sections.push(section);
Expand Down Expand Up @@ -1486,6 +1519,18 @@ impl Tx {
(self, sechash)
}

/// Add a memo section to the transaction
pub fn add_memo(
&mut self,
memo: &[u8],
) -> (&mut Self, crate::types::hash::Hash) {
let sechash = self
.add_section(Section::ExtraData(Code::new(memo.to_vec(), None)))
.get_hash();
self.set_memo_sechash(sechash);
(self, sechash)
}

/// Add a masp tx section to the tx builder
pub fn add_masp_tx_section(
&mut self,
Expand Down
2 changes: 1 addition & 1 deletion genesis/localnet/src/pre-genesis/signed-transactions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ validator = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
amount = "20000"

[bond.signatures]
tpknam1qrnw8mxyqlj60mykgevnldcj5mg2fya7fs5a8xqdkd2gwtxhef0zy8a2wha = "signam1qpnkmht38f4ewksnu2e4kaue9vqynvujs7hghk358rjn5wt6ywm9zdet6m3txrh08qzc5up47vgskt7cz48dpqlpuan7waz7prlxe0sxn9zsn7"
tpknam1qrnw8mxyqlj60mykgevnldcj5mg2fya7fs5a8xqdkd2gwtxhef0zy8a2wha = "signam1qqv8vvt2yk3gpzth6f5qdtf2g889mk6jv0qrrj0np62czy0qrruj5pgezjhqfvs4vg5f9zmelngpy04c7klschc57upr7zlk9w7647sx4j7x9c"
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ authorization = "signam1qxe6c5h7sfrsampxlhsxdkq33zmetwg45y2lqxxhf4v7sy7sa933xat3
email = "[email protected]"

[validator_account.signatures]
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qqtljxqp03xhfcfg7vpnmxeuke97kqz5etmdzwvkmr08r4x9wj4ckzf6wlqzse8d05p3t70yyn3pd34kjvx87fzp3sytn4vp6adajrgx5uk8my"
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qrgen2xu6zm27mzjeycqhzjt4c0dun8jwqxhaj7d3yduqpxud80whuqpec2k5k5a40w0jfgzwec8483vrvnaa30ky9r2utaxccvh2wsr9em3es"

[[bond]]
source = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
validator = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
amount = "100000"

[bond.signatures]
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qp7jrgg0q488vm3m4yzt8c44e40kaklc08fvsktwuayw69wzjgsvr9zlqs60wml5ewpnm8yydg0g5kga76zm3xmtcxauxszftrv7l9cpalu82v"
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qpama7hqj2lqleln7yhqa94s97mz8n8wqemtljwa9znfr5yq3uhrf33deeskf9alx6zdd8mzpuhrlc0gfr79hkkzhjqa7kw4a6j7r0sdxzqlj8"
6 changes: 3 additions & 3 deletions genesis/localnet/transactions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ authorization = "signam1qxe6c5h7sfrsampxlhsxdkq33zmetwg45y2lqxxhf4v7sy7sa933xat3
email = "[email protected]"

[validator_account.signatures]
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qqtljxqp03xhfcfg7vpnmxeuke97kqz5etmdzwvkmr08r4x9wj4ckzf6wlqzse8d05p3t70yyn3pd34kjvx87fzp3sytn4vp6adajrgx5uk8my"
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qrgen2xu6zm27mzjeycqhzjt4c0dun8jwqxhaj7d3yduqpxud80whuqpec2k5k5a40w0jfgzwec8483vrvnaa30ky9r2utaxccvh2wsr9em3es"

[[bond]]
source = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
validator = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
amount = "100000"

[bond.signatures]
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qp7jrgg0q488vm3m4yzt8c44e40kaklc08fvsktwuayw69wzjgsvr9zlqs60wml5ewpnm8yydg0g5kga76zm3xmtcxauxszftrv7l9cpalu82v"
tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj = "signam1qpama7hqj2lqleln7yhqa94s97mz8n8wqemtljwa9znfr5yq3uhrf33deeskf9alx6zdd8mzpuhrlc0gfr79hkkzhjqa7kw4a6j7r0sdxzqlj8"

# 2.

Expand All @@ -74,4 +74,4 @@ validator = "tnam1q9vhfdur7gadtwx4r223agpal0fvlqhywylf2mzx"
amount = "20000"

[bond.signatures]
tpknam1qrnw8mxyqlj60mykgevnldcj5mg2fya7fs5a8xqdkd2gwtxhef0zy8a2wha = "signam1qpnkmht38f4ewksnu2e4kaue9vqynvujs7hghk358rjn5wt6ywm9zdet6m3txrh08qzc5up47vgskt7cz48dpqlpuan7waz7prlxe0sxn9zsn7"
tpknam1qrnw8mxyqlj60mykgevnldcj5mg2fya7fs5a8xqdkd2gwtxhef0zy8a2wha = "signam1qqv8vvt2yk3gpzth6f5qdtf2g889mk6jv0qrrj0np62czy0qrruj5pgezjhqfvs4vg5f9zmelngpy04c7klschc57upr7zlk9w7647sx4j7x9c"
3 changes: 3 additions & 0 deletions sdk/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::time::Duration as StdDuration;
use namada_core::ledger::governance::cli::onchain::{
DefaultProposal, PgfFundingProposal, PgfStewardProposal,
};
use namada_core::proto::Memo;
use namada_core::types::address::Address;
use namada_core::types::chain::ChainId;
use namada_core::types::dec::Dec;
Expand Down Expand Up @@ -1926,6 +1927,8 @@ pub struct Tx<C: NamadaTypes = SdkTypes> {
pub tx_reveal_code_path: PathBuf,
/// Password to decrypt key
pub password: Option<Zeroizing<String>>,
/// Optional memo to be included in the transaction
pub memo: Option<Memo>,
/// Use device to sign the transaction
pub use_device: bool,
}
Expand Down
3 changes: 3 additions & 0 deletions sdk/src/eth_bridge/bridge_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ pub async fn build_bridge_pool_tx(
.ok_or_else(|| Error::Other("No chain id available".into()))?;

let mut tx = Tx::new(chain_id, tx_args.expiration);
if let Some(memo) = &tx_args.memo {
tx.add_memo(memo);
}
tx.add_code_from_hash(
tx_code_hash,
Some(code_path.to_string_lossy().into_owned()),
Expand Down
4 changes: 4 additions & 0 deletions sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend {
signatures: vec![],
tx_reveal_code_path: PathBuf::from(TX_REVEAL_PK),
password: None,
memo: None,
use_device: false,
}
}
Expand Down Expand Up @@ -655,6 +656,7 @@ where
signatures: vec![],
tx_reveal_code_path: PathBuf::from(TX_REVEAL_PK),
password: None,
memo: None,
use_device: false,
},
}
Expand Down Expand Up @@ -945,6 +947,7 @@ pub mod testing {
timestamp in arb_date_time_utc(),
code_hash in arb_hash(),
data_hash in arb_hash(),
memo_hash in arb_hash(),
tx_type in arb_tx_type(),
) -> Header {
Header {
Expand All @@ -953,6 +956,7 @@ pub mod testing {
timestamp,
data_hash,
code_hash,
memo_hash,
tx_type,
}
}
Expand Down
12 changes: 12 additions & 0 deletions sdk/src/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2103,6 +2103,9 @@ pub async fn build_ibc_transfer(

let chain_id = args.tx.chain_id.clone().unwrap();
let mut tx = Tx::new(chain_id, args.tx.expiration);
if let Some(memo) = &args.tx.memo {
tx.add_memo(memo);
}

let data = match shielded_parts {
Some((shielded_transfer, asset_types)) => {
Expand Down Expand Up @@ -2207,6 +2210,9 @@ where
let chain_id = tx_args.chain_id.clone().unwrap();

let mut tx_builder = Tx::new(chain_id, tx_args.expiration);
if let Some(memo) = &tx_args.memo {
tx_builder.add_memo(memo);
}

let tx_code_hash = query_wasm_code_hash(context, path.to_string_lossy())
.await
Expand Down Expand Up @@ -2548,6 +2554,9 @@ pub async fn build_update_account(

let chain_id = tx_args.chain_id.clone().unwrap();
let mut tx = Tx::new(chain_id, tx_args.expiration);
if let Some(memo) = &tx_args.memo {
tx.add_memo(memo);
}
let extra_section_hash = vp_code_path.as_ref().zip(vp_code_hash).map(
|(code_path, vp_code_hash)| {
tx.add_extra_section_from_hash(
Expand Down Expand Up @@ -2620,6 +2629,9 @@ pub async fn build_custom(
let tx_code_hash = query_wasm_code_hash_buf(context, code_path).await?;
let chain_id = tx_args.chain_id.clone().unwrap();
let mut tx = Tx::new(chain_id, tx_args.expiration);
if let Some(memo) = &tx_args.memo {
tx.add_memo(memo);
}
tx.add_code_from_hash(
tx_code_hash,
Some(code_path.to_string_lossy().into_owned()),
Expand Down
Binary file modified wasm_for_tests/tx_fail.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_memory_limit.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_mint_tokens.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_no_op.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_proposal_code.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_read_storage_key.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_write.wasm
Binary file not shown.
Binary file modified wasm_for_tests/tx_write_storage_key.wasm
Binary file not shown.
Binary file modified wasm_for_tests/vp_always_false.wasm
Binary file not shown.
Binary file modified wasm_for_tests/vp_always_true.wasm
Binary file not shown.
Binary file modified wasm_for_tests/vp_eval.wasm
Binary file not shown.
Binary file modified wasm_for_tests/vp_memory_limit.wasm
Binary file not shown.
Binary file modified wasm_for_tests/vp_read_storage_key.wasm
Binary file not shown.

0 comments on commit e08e2a0

Please sign in to comment.