solana: fix payload3 deserialization (#1354)

* fix solana payload3 deserialization and add rust integration & unit tests

* add integration test for complete_native_with_payload
This commit is contained in:
swimricky 2022-07-14 14:30:38 -04:00 committed by GitHub
parent deeabc096d
commit bf690e9adc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 149 additions and 3 deletions

View File

@ -131,9 +131,6 @@ impl DeserializePayload for PayloadTransferWithPayload {
let to_chain = v.read_u16::<BigEndian>()?;
let mut fee_data: [u8; 32] = [0; 32];
v.read_exact(&mut fee_data)?;
let mut from_address = Address::default();
v.read_exact(&mut from_address)?;
@ -380,6 +377,7 @@ mod tests {
PayloadAssetMeta,
PayloadGovernanceRegisterChain,
PayloadTransfer,
PayloadTransferWithPayload
};
use bridge::{
DeserializePayload,
@ -457,4 +455,32 @@ mod tests {
assert_eq!(original, deser);
}
#[test]
pub fn test_serde_transfer_with_payload() {
let mut token_address = [0u8; 32];
rand::thread_rng().fill_bytes(&mut token_address);
let mut from_address = [0u8; 32];
rand::thread_rng().fill_bytes(&mut from_address);
let mut to = [0u8; 32];
rand::thread_rng().fill_bytes(&mut to);
let payload = vec![0u8; 10];
let transfer_original = PayloadTransferWithPayload {
amount: U256::from(1003),
token_address,
token_chain: 8,
to,
to_chain: 1,
from_address,
payload
};
let data = transfer_original.try_to_vec().unwrap();
let transfer_deser = PayloadTransferWithPayload::deserialize(
&mut data.as_slice()
).unwrap();
assert_eq!(transfer_original, transfer_deser);
}
}

View File

@ -83,6 +83,7 @@ mod helpers {
use token_bridge::{
CompleteNativeData,
CompleteWrappedData,
CompleteNativeWithPayloadData,
CreateWrappedData,
RegisterChainData,
TransferNativeData,
@ -93,6 +94,7 @@ mod helpers {
PayloadAssetMeta,
PayloadGovernanceRegisterChain,
PayloadTransfer,
PayloadTransferWithPayload
};
/// Generate `count` secp256k1 private keys, along with their ethereum-styled public key
@ -507,6 +509,45 @@ mod helpers {
.await
}
pub async fn complete_native_with_payload(
client: &mut BanksClient,
program: Pubkey,
bridge: Pubkey,
message_acc: Pubkey,
vaa: PostVAAData,
payload: PayloadTransferWithPayload,
to: Pubkey,
redeemer: &Keypair,
payer: &Keypair,
) -> Result<(), TransportError> {
let instruction = instructions::complete_native_with_payload(
program,
bridge,
payer.pubkey(),
message_acc,
vaa,
to,
redeemer.pubkey(),
None,
Pubkey::new(&payload.token_address[..]),
CompleteNativeWithPayloadData {},
)
.expect("Could not create Complete Native With Payload instruction");
for account in instruction.accounts.iter().enumerate() {
println!("{}: {}", account.0, account.1.pubkey);
}
execute(
client,
payer,
&[payer, redeemer],
&[instruction],
CommitmentLevel::Processed,
)
.await
}
pub async fn create_wrapped(
client: &mut BanksClient,
program: Pubkey,

View File

@ -40,6 +40,7 @@ use token_bridge::{
PayloadAssetMeta,
PayloadGovernanceRegisterChain,
PayloadTransfer,
PayloadTransferWithPayload
},
types::Config,
};
@ -53,6 +54,9 @@ const GOVERNANCE_KEY: [u8; 64] = [
88, 97, 199,
];
const CHAIN_ID_SOLANA: u16 = 1;
const CHAIN_ID_ETH: u16 = 2;
struct Context {
/// Guardian public keys.
guardians: Vec<[u8; 20]>,
@ -539,3 +543,78 @@ async fn transfer_wrapped() {
.await
.unwrap();
}
#[tokio::test]
async fn transfer_native_with_payload_in() {
let mut context = set_up().await.unwrap();
register_chain(&mut context).await;
let Context {
ref payer,
ref mut client,
bridge,
token_bridge,
ref mint,
ref token_account,
ref token_authority,
ref guardian_keys,
..
} = context;
// Do an initial transfer so that the bridge account has some native tokens. This also creates
// the custody account.
let message = &Keypair::new();
common::transfer_native(
client,
token_bridge,
bridge,
payer,
message,
token_account,
token_authority,
mint.pubkey(),
100,
)
.await
.unwrap();
let nonce = rand::thread_rng().gen();
let from_address = Keypair::new().pubkey().to_bytes();
let payload: Vec<u8> = vec![1, 2, 3];
let payload = PayloadTransferWithPayload {
amount: U256::from(100u128),
token_address: mint.pubkey().to_bytes(),
token_chain: CHAIN_ID_SOLANA,
to: token_authority.pubkey().to_bytes(),
to_chain: CHAIN_ID_SOLANA,
from_address,
payload
};
let message = payload.try_to_vec().unwrap();
let (vaa, body, _) = common::generate_vaa([0u8; 32], CHAIN_ID_ETH, message, nonce, 1);
let signature_set = common::verify_signatures(client, &bridge, payer, body, guardian_keys, 0)
.await
.unwrap();
common::post_vaa(client, bridge, payer, signature_set, vaa.clone())
.await
.unwrap();
let msg_derivation_data = &PostedVAADerivationData {
payload_hash: body.to_vec(),
};
let message_key =
PostedVAA::<'_, { AccountState::MaybeInitialized }>::key(msg_derivation_data, &bridge);
common::complete_native_with_payload(
client,
token_bridge,
bridge,
message_key,
vaa,
payload,
token_account.pubkey(),
token_authority,
payer,
)
.await
.unwrap();
}