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:
parent
deeabc096d
commit
bf690e9adc
|
@ -131,9 +131,6 @@ impl DeserializePayload for PayloadTransferWithPayload {
|
||||||
|
|
||||||
let to_chain = v.read_u16::<BigEndian>()?;
|
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();
|
let mut from_address = Address::default();
|
||||||
v.read_exact(&mut from_address)?;
|
v.read_exact(&mut from_address)?;
|
||||||
|
|
||||||
|
@ -380,6 +377,7 @@ mod tests {
|
||||||
PayloadAssetMeta,
|
PayloadAssetMeta,
|
||||||
PayloadGovernanceRegisterChain,
|
PayloadGovernanceRegisterChain,
|
||||||
PayloadTransfer,
|
PayloadTransfer,
|
||||||
|
PayloadTransferWithPayload
|
||||||
};
|
};
|
||||||
use bridge::{
|
use bridge::{
|
||||||
DeserializePayload,
|
DeserializePayload,
|
||||||
|
@ -457,4 +455,32 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(original, deser);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,7 @@ mod helpers {
|
||||||
use token_bridge::{
|
use token_bridge::{
|
||||||
CompleteNativeData,
|
CompleteNativeData,
|
||||||
CompleteWrappedData,
|
CompleteWrappedData,
|
||||||
|
CompleteNativeWithPayloadData,
|
||||||
CreateWrappedData,
|
CreateWrappedData,
|
||||||
RegisterChainData,
|
RegisterChainData,
|
||||||
TransferNativeData,
|
TransferNativeData,
|
||||||
|
@ -93,6 +94,7 @@ mod helpers {
|
||||||
PayloadAssetMeta,
|
PayloadAssetMeta,
|
||||||
PayloadGovernanceRegisterChain,
|
PayloadGovernanceRegisterChain,
|
||||||
PayloadTransfer,
|
PayloadTransfer,
|
||||||
|
PayloadTransferWithPayload
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Generate `count` secp256k1 private keys, along with their ethereum-styled public key
|
/// Generate `count` secp256k1 private keys, along with their ethereum-styled public key
|
||||||
|
@ -507,6 +509,45 @@ mod helpers {
|
||||||
.await
|
.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(
|
pub async fn create_wrapped(
|
||||||
client: &mut BanksClient,
|
client: &mut BanksClient,
|
||||||
program: Pubkey,
|
program: Pubkey,
|
||||||
|
|
|
@ -40,6 +40,7 @@ use token_bridge::{
|
||||||
PayloadAssetMeta,
|
PayloadAssetMeta,
|
||||||
PayloadGovernanceRegisterChain,
|
PayloadGovernanceRegisterChain,
|
||||||
PayloadTransfer,
|
PayloadTransfer,
|
||||||
|
PayloadTransferWithPayload
|
||||||
},
|
},
|
||||||
types::Config,
|
types::Config,
|
||||||
};
|
};
|
||||||
|
@ -53,6 +54,9 @@ const GOVERNANCE_KEY: [u8; 64] = [
|
||||||
88, 97, 199,
|
88, 97, 199,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const CHAIN_ID_SOLANA: u16 = 1;
|
||||||
|
const CHAIN_ID_ETH: u16 = 2;
|
||||||
|
|
||||||
struct Context {
|
struct Context {
|
||||||
/// Guardian public keys.
|
/// Guardian public keys.
|
||||||
guardians: Vec<[u8; 20]>,
|
guardians: Vec<[u8; 20]>,
|
||||||
|
@ -539,3 +543,78 @@ async fn transfer_wrapped() {
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.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();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue