Skip to content

Commit

Permalink
[Solana]: Fix advance nonce not work with priority fee instruction (#…
Browse files Browse the repository at this point in the history
…3717)

* [Solana]: Fix advance nonce not work with priority fee instruction

* Convert indent to spaces

* Adjust format
  • Loading branch information
w20089527 authored Mar 8, 2024
1 parent c0cf03f commit 13cdf83
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 13 deletions.
26 changes: 13 additions & 13 deletions rust/chains/tw_solana/src/modules/message_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, from)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, from)
.maybe_memo(transfer.memo.as_ref())
.add_instruction(transfer_ix);
Ok(builder.output())
Expand Down Expand Up @@ -201,9 +201,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, sender)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, sender)
.add_instructions(deposit_ixs);
Ok(builder.output())
}
Expand All @@ -218,9 +218,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, sender)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, sender)
.add_instruction(deactivate_ix);
Ok(builder.output())
}
Expand All @@ -241,9 +241,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, sender)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, sender)
.add_instructions(deactivate_ixs);
Ok(builder.output())
}
Expand All @@ -266,9 +266,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, sender)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, sender)
.add_instruction(withdraw_ix);
Ok(builder.output())
}
Expand Down Expand Up @@ -297,9 +297,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, sender)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, sender)
.add_instructions(withdraw_ixs);
Ok(builder.output())
}
Expand All @@ -322,9 +322,9 @@ impl<'a> MessageBuilder<'a> {
);
let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, funding_account)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, funding_account)
.add_instruction(instruction);
Ok(builder.output())
}
Expand Down Expand Up @@ -359,9 +359,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, signer)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, signer)
.maybe_memo(token_transfer.memo.as_ref())
.add_instruction(transfer_instruction);
Ok(builder.output())
Expand Down Expand Up @@ -407,9 +407,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, signer)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, signer)
.add_instruction(create_account_instruction)
// Optional memo. Order: before transfer, as per documentation.
.maybe_memo(create_and_transfer.memo.as_ref())
Expand All @@ -435,9 +435,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(prev_nonce_account, signer)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(prev_nonce_account, signer)
.add_instructions(SystemInstructionBuilder::create_nonce_account(
signer,
new_nonce_account,
Expand All @@ -457,9 +457,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(self.nonce_account()?, signer)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(self.nonce_account()?, signer)
.add_instruction(SystemInstructionBuilder::withdraw_nonce_account(
withdraw_from_nonce,
signer,
Expand All @@ -478,9 +478,9 @@ impl<'a> MessageBuilder<'a> {

let mut builder = InstructionBuilder::default();
builder
.maybe_advance_nonce(Some(nonce_account), signer)
.maybe_priority_fee_price(self.priority_fee_price())
.maybe_priority_fee_limit(self.priority_fee_limit())
.maybe_advance_nonce(Some(nonce_account), signer);
.maybe_priority_fee_limit(self.priority_fee_limit());
Ok(builder.output())
}

Expand Down
48 changes: 48 additions & 0 deletions tests/chains/Solana/TransactionCompilerTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,52 @@ TEST(SolanaCompiler, CompileTransferWithSignatures) {
}
}

TEST(SolanaCompiler, CompileTransferWithPriorityFee) {
// tx on mainnet
// https://explorer.solana.com/tx/5asW13PSGvbZAeiGe8YFo7jt3UTqb8KUfFhXh5DXpDVfpVup1ZP41tp7PmBJH43gK5xT9U4VDVChDynmC7PJp9fa

const auto coin = TWCoinTypeSolana;
/// Step 1: Prepare transaction input (protobuf)
auto input = TW::Solana::Proto::SigningInput();
auto& message = *input.mutable_transfer_transaction();
auto recipient = std::string("6NdFCrugyZVRhFbHvJT3dFBrGE9ZYFbfc8dBS2q4d2a9");
auto sender = std::string("EQ37VYUVcqUSzYgvaguDB4yVRg5m3Xg7qQoKF8zFiJxe");
input.set_sender(sender);
input.set_recent_blockhash(std::string("8oFmGuWUpsy8h8WP8AXTp3yhcLt4gQJRG5GxNcK7jfhX"));
input.set_nonce_account("ubKTCz9avQt3twiC9TbRjfoCiJnggH1abjgj9FjZJJm");
input.mutable_priority_fee_price()->set_price(40000);
input.mutable_priority_fee_limit()->set_limit(480000);
message.set_recipient(recipient);
message.set_value((uint64_t)10000);
auto inputString = input.SerializeAsString();
auto inputStrData = TW::Data(inputString.begin(), inputString.end());

/// Step 2: Obtain preimage hash
const auto preImageHashesData = TransactionCompiler::preImageHashes(coin, inputStrData);
auto preSigningOutput = TW::Solana::Proto::PreSigningOutput();
preSigningOutput.ParseFromArray(preImageHashesData.data(), (int)preImageHashesData.size());
ASSERT_EQ(preSigningOutput.signers_size(), 1);
auto signer = preSigningOutput.signers(0);
EXPECT_EQ(signer, sender);
auto preImageHash = preSigningOutput.data();
EXPECT_EQ(hex(preImageHash), "01000306c70ead37125b5e142838eb59a6883ef915474f9b0a52494f698a4d23f4827ca70d79017647148829ddee52e687a840b42ce55a808367ff3cb0dc67444f5361ca4fd49d2664e7ac3016160e0b943a9222a21bee6510248dc2ae341f58195a2a3606a7d517192c568ee08a845f73d29788cf035c3145b21ab344d8062ea940000000000000000000000000000000000000000000000000000000000000000000000306466fe5211732ffecadba72c39be7bc8ce5bbc5f7126b2c439b3a4000000073db37fafe5d370e4605395dfc4661d886170c751ecfd7d76a744ea43c9f16f6040403010300040400000005000903409c0000000000000500050200530700040200020c020000001027000000000000");

// Simulate signature, normally obtained from signature server
const Data publicKeyData = parse_hex("c70ead37125b5e142838eb59a6883ef915474f9b0a52494f698a4d23f4827ca7");
const PublicKey publicKey = PublicKey(publicKeyData, TWPublicKeyTypeED25519);
const auto signature = parse_hex("e546dbc2b896ff53abe5d3f090abdea84fb3862c6dcab4a6878e4d0dc803a53a2b077ef14014737e049815ff4df5daa92dc3e11b55770466d5feab6bdfccf005");
// Verify signature (pubkey & hash & signature)
EXPECT_TRUE(publicKey.verify(signature, TW::data(preImageHash)));

/// Step 3: Compile transaction info
auto outputData = TransactionCompiler::compileWithSignatures(coin, inputStrData, {signature}, {publicKeyData});
const auto ExpectedTx = "84RnGAbza5DstiCPgBwtyuGnB2TPYsRGFr4L9tvzc71tBjyPS5aK9xGfMPdKA16gm8dJSxdAwMQX22zF3bQAHtgNHSApaL9Hs2B4Rz1HjazPmbNYLJKkSZ4gq2MWbY6DSKkg3NUf4L9HpZVFbrUw7TNgFYbEYiA1wTJ4aVwVAh9NQLDaQBgANnMvjFTYy2rDjgHL8nZU6omjK2uvDaLdqp2L4hXjGTKQ1mMFVRLXnrMUX8dijBPty3NDcgJ3G442ccGguez7DwYooirYuZ5ajiJwkKtqu8tW4namRdvAC7YmL1tCqZpWXyDBhqMapoyf1bVCvUbnuz64RZwhd7nj6DyULtiMXCUXFayeShe2nvJGTkzWZxEEeHPyvLtTmSNrmRWqE2ZEDCFGH3bopBKG2QJVeEomh7rKFSZ6WTDmG2V7L6zPFexAhuen9ynEBu8JJWRM3nx5dj4BSDeQf";
{
Solana::Proto::SigningOutput output;
ASSERT_TRUE(output.ParseFromArray(outputData.data(), (int)outputData.size()));

EXPECT_EQ(output.encoded(), ExpectedTx);
}
}

} // namespace TW::Solana::tests

0 comments on commit 13cdf83

Please sign in to comment.