Skip to content

Commit

Permalink
sequence -> id and make it 32 bytes (#228)
Browse files Browse the repository at this point in the history
* solana: use outbox item as id instead of incremental sequence counter

* evm: adjust wire format so that id is 32 bytes
  • Loading branch information
kcsongor authored Feb 29, 2024
1 parent f4e2277 commit 2f3c087
Show file tree
Hide file tree
Showing 24 changed files with 81 additions and 132 deletions.
4 changes: 3 additions & 1 deletion evm/src/NttManager/NttManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,9 @@ contract NttManager is INttManager, NttManagerState {
// construct the NttManagerMessage payload
bytes memory encodedNttManagerPayload = TransceiverStructs.encodeNttManagerMessage(
TransceiverStructs.NttManagerMessage(
seq, toWormholeFormat(sender), TransceiverStructs.encodeNativeTokenTransfer(ntt)
bytes32(uint256(seq)),
toWormholeFormat(sender),
TransceiverStructs.encodeNativeTokenTransfer(ntt)
)
);

Expand Down
12 changes: 7 additions & 5 deletions evm/src/libraries/TransceiverStructs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ library TransceiverStructs {

/// @dev Message emitted and received by the nttManager contract.
/// The wire format is as follows:
/// - sequence - 8 bytes
/// - id - 32 bytes
/// - sender - 32 bytes
/// - payloadLength - 2 bytes
/// - payload - `payloadLength` bytes
struct NttManagerMessage {
/// @notice unique sequence number
uint64 sequence;
/// @notice unique message identifier
/// @dev This is incrementally assigned on EVM chains, but this is not
/// guaranteed on other runtimes.
bytes32 id;
/// @notice original message sender address.
bytes32 sender;
/// @notice payload that corresponds to the type.
Expand All @@ -55,7 +57,7 @@ library TransceiverStructs {
revert PayloadTooLong(m.payload.length);
}
uint16 payloadLength = uint16(m.payload.length);
return abi.encodePacked(m.sequence, m.sender, payloadLength, m.payload);
return abi.encodePacked(m.id, m.sender, payloadLength, m.payload);
}

/// @notice Parse a NttManagerMessage.
Expand All @@ -67,7 +69,7 @@ library TransceiverStructs {
returns (NttManagerMessage memory nttManagerMessage)
{
uint256 offset = 0;
(nttManagerMessage.sequence, offset) = encoded.asUint64Unchecked(offset);
(nttManagerMessage.id, offset) = encoded.asBytes32Unchecked(offset);
(nttManagerMessage.sender, offset) = encoded.asBytes32Unchecked(offset);
uint256 payloadLength;
(payloadLength, offset) = encoded.asUint16Unchecked(offset);
Expand Down
2 changes: 1 addition & 1 deletion evm/test/NttManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ contract TestNttManager is Test, INttManagerEvents, IRateLimiterEvents {

TransceiverHelpersLib.attestTransceiversHelper(
user_B,
1,
bytes32(uint256(1)),
chainId,
nttManager, // this is the proxy
nttManagerOther, // this is the proxy
Expand Down
6 changes: 3 additions & 3 deletions evm/test/TransceiverStructs.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ contract TestTransceiverStructs is Test {
});

TransceiverStructs.NttManagerMessage memory mm = TransceiverStructs.NttManagerMessage({
sequence: 233968345345,
id: hex"128434bafe23430000000000000000000000000000000000ce00aa0000000000",
sender: hex"46679213412343",
payload: TransceiverStructs.encodeNativeTokenTransfer(ntt)
});
Expand All @@ -39,7 +39,7 @@ contract TestTransceiverStructs is Test {

// this is a useful test case for implementations on other runtimes
bytes memory encodedExpected =
hex"9945ff10042942fafabe0000000000000000000000000000000000000000000000000000042942fababe00000000000000000000000000000000000000000000000000000079000000367999a1014667921341234300000000000000000000000000000000000000000000000000004f994e545407000000000012d687beefface00000000000000000000000000000000000000000000000000000000feebcafe0000000000000000000000000000000000000000000000000000000000110000";
hex"9945ff10042942fafabe0000000000000000000000000000000000000000000000000000042942fababe00000000000000000000000000000000000000000000000000000091128434bafe23430000000000000000000000000000000000ce00aa00000000004667921341234300000000000000000000000000000000000000000000000000004f994e545407000000000012d687beefface00000000000000000000000000000000000000000000000000000000feebcafe0000000000000000000000000000000000000000000000000000000000110000";
assertEq(encodedTransceiverMessage, encodedExpected);

TransceiverStructs.TransceiverMessage memory emParsed =
Expand All @@ -66,7 +66,7 @@ contract TestTransceiverStructs is Test {
TransceiverStructs.NttManagerMessage memory parsed =
TransceiverStructs.parseNttManagerMessage(message);

assertEq(m.sequence, parsed.sequence);
assertEq(m.id, parsed.id);
assertEq(m.sender, parsed.sender);
assertEq(m.payload, parsed.payload);
}
Expand Down
12 changes: 6 additions & 6 deletions evm/test/libraries/TransceiverHelpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ library TransceiverHelpersLib {

function attestTransceiversHelper(
address to,
uint64 sequence,
bytes32 id,
uint16 toChain,
NttManager nttManager,
NttManager recipientNttManager,
Expand All @@ -44,7 +44,7 @@ library TransceiverHelpersLib {
)
{
TransceiverStructs.NttManagerMessage memory m =
buildNttManagerMessage(to, sequence, toChain, nttManager, amount);
buildNttManagerMessage(to, id, toChain, nttManager, amount);
bytes memory encodedM = TransceiverStructs.encodeNttManagerMessage(m);

prepTokenReceive(nttManager, recipientNttManager, amount, inboundLimit);
Expand All @@ -69,15 +69,15 @@ library TransceiverHelpersLib {

function buildNttManagerMessage(
address to,
uint64 sequence,
bytes32 id,
uint16 toChain,
NttManager nttManager,
TrimmedAmount memory amount
) internal view returns (TransceiverStructs.NttManagerMessage memory) {
DummyToken token = DummyToken(nttManager.token());

return TransceiverStructs.NttManagerMessage(
sequence,
id,
bytes32(0),
TransceiverStructs.encodeNativeTokenTransfer(
TransceiverStructs.NativeTokenTransfer({
Expand All @@ -104,14 +104,14 @@ library TransceiverHelpersLib {
}

function buildTransceiverMessageWithNttManagerPayload(
uint64 sequence,
bytes32 id,
bytes32 sender,
bytes32 sourceNttManager,
bytes32 recipientNttManager,
bytes memory payload
) internal pure returns (TransceiverStructs.NttManagerMessage memory, bytes memory) {
TransceiverStructs.NttManagerMessage memory m =
TransceiverStructs.NttManagerMessage(sequence, sender, payload);
TransceiverStructs.NttManagerMessage(id, sender, payload);
bytes memory nttManagerMessage = TransceiverStructs.encodeNttManagerMessage(m);
bytes memory transceiverMessage;
(, transceiverMessage) = TransceiverStructs.buildAndEncodeTransceiverMessage(
Expand Down
12 changes: 6 additions & 6 deletions solana/modules/ntt-messages/src/ntt_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::utils::maybe_space::MaybeSpace;
derive(AnchorSerialize, AnchorDeserialize, InitSpace)
)]
pub struct NttManagerMessage<A: MaybeSpace> {
pub sequence: u64,
pub id: [u8; 32],
pub sender: [u8; 32],
pub payload: A,
}
Expand Down Expand Up @@ -43,14 +43,14 @@ impl<A: TypePrefixedPayload + MaybeSpace> Readable for NttManagerMessage<A> {
Self: Sized,
R: io::Read,
{
let sequence = Readable::read(reader)?;
let id = Readable::read(reader)?;
let sender = Readable::read(reader)?;
// TODO: same as below for ntt_manager payload
let _payload_len: u16 = Readable::read(reader)?;
let payload = A::read_payload(reader)?;

Ok(Self {
sequence,
id,
sender,
payload,
})
Expand All @@ -59,7 +59,7 @@ impl<A: TypePrefixedPayload + MaybeSpace> Readable for NttManagerMessage<A> {

impl<A: TypePrefixedPayload + MaybeSpace> Writeable for NttManagerMessage<A> {
fn written_size(&self) -> usize {
u64::SIZE.unwrap()
self.id.len()
+ self.sender.len()
+ u16::SIZE.unwrap() // payload length
+ self.payload.written_size()
Expand All @@ -70,12 +70,12 @@ impl<A: TypePrefixedPayload + MaybeSpace> Writeable for NttManagerMessage<A> {
W: io::Write,
{
let NttManagerMessage {
sequence,
id,
sender,
payload,
} = self;

sequence.write(writer)?;
id.write(writer)?;
writer.write_all(sender)?;
let len: u16 = u16::try_from(payload.written_size()).expect("u16 overflow");
len.write(writer)?;
Expand Down
7 changes: 5 additions & 2 deletions solana/modules/ntt-messages/src/transceiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod test {
//
#[test]
fn test_deserialize_transceiver_message() {
let data = hex::decode("9945ff10042942fafabe0000000000000000000000000000000000000000000000000000042942fababe00000000000000000000000000000000000000000000000000000079000000367999a1014667921341234300000000000000000000000000000000000000000000000000004f994e545407000000000012d687beefface00000000000000000000000000000000000000000000000000000000feebcafe0000000000000000000000000000000000000000000000000000000000110000").unwrap();
let data = hex::decode("9945ff10042942fafabe0000000000000000000000000000000000000000000000000000042942fababe00000000000000000000000000000000000000000000000000000091128434bafe23430000000000000000000000000000000000ce00aa00000000004667921341234300000000000000000000000000000000000000000000000000004f994e545407000000000012d687beefface00000000000000000000000000000000000000000000000000000000feebcafe0000000000000000000000000000000000000000000000000000000000110000").unwrap();
let mut vec = &data[..];
let message: TransceiverMessage<WormholeTransceiver, NativeTokenTransfer> =
TypePrefixedPayload::read_payload(&mut vec).unwrap();
Expand All @@ -204,7 +204,10 @@ mod test {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
],
ntt_manager_payload: NttManagerMessage {
sequence: 233968345345,
id: [
0x12, 0x84, 0x34, 0xBA, 0xFE, 0x23, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0xCE, 0, 0xAA, 0, 0, 0, 0, 0,
],
sender: [
0x46, 0x67, 0x92, 0x13, 0x41, 0x23, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Expand Down
1 change: 1 addition & 0 deletions solana/modules/ntt-messages/src/transceivers/wormhole.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[cfg(feature = "anchor")]
use std::io;

use wormhole_io::{Readable, TypePrefixedPayload, Writeable};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::{
bitmap::Bitmap,
error::NTTError,
queue::{outbox::OutboxRateLimit, rate_limit::RateLimitState},
sequence::Sequence,
};

// TODO: upgradeability
Expand Down Expand Up @@ -47,15 +46,6 @@ pub struct Initialize<'info> {
)]
pub mint: InterfaceAccount<'info, token_interface::Mint>,

#[account(
init,
payer = payer,
space = 8 + Sequence::INIT_SPACE,
seeds = [Sequence::SEED_PREFIX],
bump,
)]
pub seq: Account<'info, Sequence>,

#[account(
init,
payer = payer,
Expand Down Expand Up @@ -114,11 +104,6 @@ pub fn initialize(ctx: Context<Initialize>, args: InitializeArgs) -> Result<()>
enabled_transceivers: Bitmap::new(),
});

ctx.accounts.seq.set_inner(Sequence {
bump: ctx.bumps.seq,
sequence: 0,
});

ctx.accounts.rate_limit.set_inner(OutboxRateLimit {
rate_limit: RateLimitState::new(args.limit),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,6 @@ pub struct Transfer<'info> {

pub token_program: Interface<'info, token_interface::TokenInterface>,

#[account(
mut,
seeds = [crate::sequence::Sequence::SEED_PREFIX],
bump = seq.bump,
)]
pub seq: Account<'info, crate::sequence::Sequence>,

#[account(
init,
payer = payer,
Expand Down Expand Up @@ -266,10 +259,7 @@ fn insert_into_outbox(
}
};

let sequence = common.seq.next_sequence();

common.outbox_item.set_inner(OutboxItem {
sequence,
amount: trimmed_amount,
sender: common.sender.key(),
recipient_chain,
Expand Down
1 change: 0 additions & 1 deletion solana/programs/example-native-token-transfers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub mod messages;
pub mod peer;
pub mod queue;
pub mod registered_transceiver;
pub mod sequence;
pub mod transceivers;

use transceivers::wormhole::instructions::*;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use super::rate_limit::RateLimitState;
#[derive(InitSpace, Debug, PartialEq, Eq)]
// TODO: generalise this to arbitrary outbound messages (via a generic parameter in place of amount and recipient info)
pub struct OutboxItem {
pub sequence: u64,
pub amount: TrimmedAmount,
pub sender: Pubkey,
pub recipient_chain: ChainId,
Expand Down
18 changes: 0 additions & 18 deletions solana/programs/example-native-token-transfers/src/sequence.rs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub struct ReceiveMessage<'info> {
seeds = [
ValidatedTransceiverMessage::<TransceiverMessageData<NativeTokenTransfer>>::SEED_PREFIX,
vaa.emitter_chain().to_be_bytes().as_ref(),
vaa.message().ntt_manager_payload.sequence.to_be_bytes().as_ref(),
vaa.message().ntt_manager_payload.id.as_ref(),
],
bump,
)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ pub fn release_outbound(ctx: Context<ReleaseOutbound>, args: ReleaseOutboundArgs
accs.outbox_item.to_account_info().owner.to_bytes(),
accs.outbox_item.recipient_ntt_manager,
NttManagerMessage {
sequence: accs.outbox_item.sequence,
id: accs.outbox_item.key().to_bytes(),
sender: accs.outbox_item.sender.to_bytes(),
payload: NativeTokenTransfer {
amount: accs.outbox_item.amount,
Expand Down
Loading

0 comments on commit 2f3c087

Please sign in to comment.