fix terra vaa parsing
Change-Id: I27306e004897f971d62c82e6046c1f6ec0016247
This commit is contained in:
parent
bb446fb338
commit
d12863f957
|
@ -83,6 +83,7 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
|
||||||
amount,
|
amount,
|
||||||
recipient_chain,
|
recipient_chain,
|
||||||
recipient,
|
recipient,
|
||||||
|
fee,
|
||||||
nonce,
|
nonce,
|
||||||
} => handle_initiate_transfer(
|
} => handle_initiate_transfer(
|
||||||
deps,
|
deps,
|
||||||
|
@ -91,6 +92,7 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
|
||||||
amount,
|
amount,
|
||||||
recipient_chain,
|
recipient_chain,
|
||||||
recipient.as_slice().to_vec(),
|
recipient.as_slice().to_vec(),
|
||||||
|
fee,
|
||||||
nonce,
|
nonce,
|
||||||
),
|
),
|
||||||
HandleMsg::SubmitVaa { data } => submit_vaa(deps, env, &data),
|
HandleMsg::SubmitVaa { data } => submit_vaa(deps, env, &data),
|
||||||
|
@ -337,10 +339,13 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
let token_chain = transfer_info.token_chain;
|
let token_chain = transfer_info.token_chain;
|
||||||
let target_address = (&transfer_info.recipient.as_slice()).get_address(0);
|
let target_address = (&transfer_info.recipient.as_slice()).get_address(0);
|
||||||
|
|
||||||
let (not_supported_amount, amount) = transfer_info.amount;
|
let (not_supported_amount, mut amount) = transfer_info.amount;
|
||||||
|
let (not_supported_fee, fee) = transfer_info.fee;
|
||||||
|
|
||||||
|
amount -= fee;
|
||||||
|
|
||||||
// Check high 128 bit of amount value to be empty
|
// Check high 128 bit of amount value to be empty
|
||||||
if not_supported_amount != 0 {
|
if not_supported_amount != 0 || not_supported_fee != 0 {
|
||||||
return ContractError::AmountTooHigh.std_err();
|
return ContractError::AmountTooHigh.std_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,15 +364,27 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
.human_address(&target_address)
|
.human_address(&target_address)
|
||||||
.or_else(|_| ContractError::WrongTargetAddressFormat.std_err())?;
|
.or_else(|_| ContractError::WrongTargetAddressFormat.std_err())?;
|
||||||
|
|
||||||
Ok(HandleResponse {
|
let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
|
||||||
contract_addr: contract_addr.clone(),
|
contract_addr: contract_addr.clone(),
|
||||||
msg: to_binary(&WrappedMsg::Mint {
|
msg: to_binary(&WrappedMsg::Mint {
|
||||||
recipient: recipient.clone(),
|
recipient: recipient.clone(),
|
||||||
amount: Uint128::from(amount),
|
amount: Uint128::from(amount),
|
||||||
})?,
|
})?,
|
||||||
send: vec![],
|
send: vec![],
|
||||||
})],
|
})];
|
||||||
|
if fee != 0 {
|
||||||
|
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
|
contract_addr: contract_addr.clone(),
|
||||||
|
msg: to_binary(&WrappedMsg::Mint {
|
||||||
|
recipient: env.message.sender.clone(),
|
||||||
|
amount: Uint128::from(fee),
|
||||||
|
})?,
|
||||||
|
send: vec![],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HandleResponse {
|
||||||
|
messages,
|
||||||
log: vec![
|
log: vec![
|
||||||
log("action", "complete_transfer_wrapped"),
|
log("action", "complete_transfer_wrapped"),
|
||||||
log("contract", contract_addr),
|
log("contract", contract_addr),
|
||||||
|
@ -384,15 +401,29 @@ fn handle_complete_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
|
|
||||||
let recipient = deps.api.human_address(&target_address)?;
|
let recipient = deps.api.human_address(&target_address)?;
|
||||||
let contract_addr = deps.api.human_address(&token_address)?;
|
let contract_addr = deps.api.human_address(&token_address)?;
|
||||||
Ok(HandleResponse {
|
|
||||||
messages: vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
let mut messages = vec![CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
contract_addr: contract_addr.clone(),
|
contract_addr: contract_addr.clone(),
|
||||||
msg: to_binary(&TokenMsg::Transfer {
|
msg: to_binary(&TokenMsg::Transfer {
|
||||||
recipient: recipient.clone(),
|
recipient: recipient.clone(),
|
||||||
amount: Uint128::from(amount),
|
amount: Uint128::from(amount),
|
||||||
})?,
|
})?,
|
||||||
send: vec![],
|
send: vec![],
|
||||||
})],
|
})];
|
||||||
|
|
||||||
|
if fee != 0 {
|
||||||
|
messages.push(CosmosMsg::Wasm(WasmMsg::Execute {
|
||||||
|
contract_addr: contract_addr.clone(),
|
||||||
|
msg: to_binary(&TokenMsg::Transfer {
|
||||||
|
recipient: env.message.sender.clone(),
|
||||||
|
amount: Uint128::from(fee),
|
||||||
|
})?,
|
||||||
|
send: vec![],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HandleResponse {
|
||||||
|
messages,
|
||||||
log: vec![
|
log: vec![
|
||||||
log("action", "complete_transfer_native"),
|
log("action", "complete_transfer_native"),
|
||||||
log("recipient", recipient),
|
log("recipient", recipient),
|
||||||
|
@ -411,6 +442,7 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
amount: Uint128,
|
amount: Uint128,
|
||||||
recipient_chain: u16,
|
recipient_chain: u16,
|
||||||
recipient: Vec<u8>,
|
recipient: Vec<u8>,
|
||||||
|
fee: Uint128,
|
||||||
nonce: u32,
|
nonce: u32,
|
||||||
) -> StdResult<HandleResponse> {
|
) -> StdResult<HandleResponse> {
|
||||||
// if recipient_chain == CHAIN_ID {
|
// if recipient_chain == CHAIN_ID {
|
||||||
|
@ -421,6 +453,10 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
return ContractError::AmountTooLow.std_err();
|
return ContractError::AmountTooLow.std_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if fee > amount {
|
||||||
|
return Err(StdError::generic_err("fee greater than sent amount"))
|
||||||
|
}
|
||||||
|
|
||||||
let asset_chain: u16;
|
let asset_chain: u16;
|
||||||
let asset_address: Vec<u8>;
|
let asset_address: Vec<u8>;
|
||||||
|
|
||||||
|
@ -471,6 +507,7 @@ fn handle_initiate_transfer<S: Storage, A: Api, Q: Querier>(
|
||||||
amount: (0, amount.u128()),
|
amount: (0, amount.u128()),
|
||||||
recipient_chain,
|
recipient_chain,
|
||||||
recipient: recipient.clone(),
|
recipient: recipient.clone(),
|
||||||
|
fee: (0, fee.u128()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let token_bridge_message = TokenBridgeMessage {
|
let token_bridge_message = TokenBridgeMessage {
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub enum HandleMsg {
|
||||||
amount: Uint128,
|
amount: Uint128,
|
||||||
recipient_chain: u16,
|
recipient_chain: u16,
|
||||||
recipient: Binary,
|
recipient: Binary,
|
||||||
|
fee: Uint128,
|
||||||
nonce: u32,
|
nonce: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -89,65 +89,65 @@ impl TokenBridgeMessage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 u16 token_chain
|
// 0 u256 amount
|
||||||
// 2 [u8; 32] token_address
|
// 32 [u8; 32] token_address
|
||||||
// 34 u256 amount
|
// 64 u16 token_chain
|
||||||
// 66 u16 recipient_chain
|
// 66 [u8; 32] recipient
|
||||||
// 68 [u8; 32] recipient
|
// 98 u16 recipient_chain
|
||||||
|
// 100 u256 fee
|
||||||
|
|
||||||
pub struct TransferInfo {
|
pub struct TransferInfo {
|
||||||
pub token_chain: u16,
|
|
||||||
pub token_address: Vec<u8>,
|
|
||||||
pub amount: (u128, u128),
|
pub amount: (u128, u128),
|
||||||
|
pub token_address: Vec<u8>,
|
||||||
|
pub token_chain: u16,
|
||||||
pub recipient_chain: u16,
|
pub recipient_chain: u16,
|
||||||
pub recipient: Vec<u8>,
|
pub recipient: Vec<u8>,
|
||||||
|
pub fee: (u128, u128),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransferInfo {
|
impl TransferInfo {
|
||||||
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
|
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
|
||||||
let data = data.as_slice();
|
let data = data.as_slice();
|
||||||
let token_chain = data.get_u16(0);
|
let amount = data.get_u256(0);
|
||||||
let token_address = data.get_bytes32(2).to_vec();
|
let token_address = data.get_bytes32(32).to_vec();
|
||||||
let amount = data.get_u256(34);
|
let token_chain = data.get_u16(64);
|
||||||
let recipient_chain = data.get_u16(66);
|
let recipient = data.get_bytes32(66).to_vec();
|
||||||
let recipient = data.get_bytes32(68).to_vec();
|
let recipient_chain = data.get_u16(98);
|
||||||
|
let fee = data.get_u256(100);
|
||||||
|
|
||||||
Ok(TransferInfo {
|
Ok(TransferInfo {
|
||||||
token_chain,
|
|
||||||
token_address,
|
|
||||||
amount,
|
amount,
|
||||||
recipient_chain,
|
token_address,
|
||||||
|
token_chain,
|
||||||
recipient,
|
recipient,
|
||||||
|
recipient_chain,
|
||||||
|
fee,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
[
|
[
|
||||||
self.token_chain.to_be_bytes().to_vec(),
|
|
||||||
self.token_address.clone(),
|
|
||||||
self.amount.0.to_be_bytes().to_vec(),
|
self.amount.0.to_be_bytes().to_vec(),
|
||||||
self.amount.1.to_be_bytes().to_vec(),
|
self.amount.1.to_be_bytes().to_vec(),
|
||||||
self.recipient_chain.to_be_bytes().to_vec(),
|
self.token_address.clone(),
|
||||||
|
self.token_chain.to_be_bytes().to_vec(),
|
||||||
self.recipient.to_vec(),
|
self.recipient.to_vec(),
|
||||||
|
self.recipient_chain.to_be_bytes().to_vec(),
|
||||||
|
self.fee.0.to_be_bytes().to_vec(),
|
||||||
|
self.fee.1.to_be_bytes().to_vec(),
|
||||||
]
|
]
|
||||||
.concat()
|
.concat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//PayloadID uint8 = 2
|
// 0 [32]uint8 TokenAddress
|
||||||
// // Address of the token. Left-zero-padded if shorter than 32 bytes
|
// 32 uint16 TokenChain
|
||||||
// TokenAddress [32]uint8
|
// 34 uint8 Decimals
|
||||||
// // Chain ID of the token
|
// 35 [32]uint8 Symbol
|
||||||
// TokenChain uint16
|
// 67 [32]uint8 Name
|
||||||
// // Number of decimals of the token
|
|
||||||
// Decimals uint8
|
|
||||||
// // Symbol of the token (UTF-8)
|
|
||||||
// Symbol [32]uint8
|
|
||||||
// // Name of the token (UTF-8)
|
|
||||||
// Name [32]uint8
|
|
||||||
|
|
||||||
pub struct AssetMeta {
|
pub struct AssetMeta {
|
||||||
pub token_chain: u16,
|
|
||||||
pub token_address: Vec<u8>,
|
pub token_address: Vec<u8>,
|
||||||
|
pub token_chain: u16,
|
||||||
pub decimals: u8,
|
pub decimals: u8,
|
||||||
pub symbol: Vec<u8>,
|
pub symbol: Vec<u8>,
|
||||||
pub name: Vec<u8>,
|
pub name: Vec<u8>,
|
||||||
|
@ -156,8 +156,8 @@ pub struct AssetMeta {
|
||||||
impl AssetMeta {
|
impl AssetMeta {
|
||||||
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
|
pub fn deserialize(data: &Vec<u8>) -> StdResult<Self> {
|
||||||
let data = data.as_slice();
|
let data = data.as_slice();
|
||||||
let token_chain = data.get_u16(0);
|
let token_address = data.get_bytes32(0).to_vec();
|
||||||
let token_address = data.get_bytes32(2).to_vec();
|
let token_chain = data.get_u16(32);
|
||||||
let decimals = data.get_u8(34);
|
let decimals = data.get_u8(34);
|
||||||
let symbol = data.get_bytes32(35).to_vec();
|
let symbol = data.get_bytes32(35).to_vec();
|
||||||
let name = data.get_bytes32(67).to_vec();
|
let name = data.get_bytes32(67).to_vec();
|
||||||
|
@ -173,8 +173,8 @@ impl AssetMeta {
|
||||||
|
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
[
|
[
|
||||||
self.token_chain.to_be_bytes().to_vec(),
|
|
||||||
self.token_address.clone(),
|
self.token_address.clone(),
|
||||||
|
self.token_chain.to_be_bytes().to_vec(),
|
||||||
self.decimals.to_be_bytes().to_vec(),
|
self.decimals.to_be_bytes().to_vec(),
|
||||||
self.symbol.clone(),
|
self.symbol.clone(),
|
||||||
self.name.clone(),
|
self.name.clone(),
|
||||||
|
|
|
@ -42,7 +42,7 @@ pub struct ConfigInfo {
|
||||||
pub struct ParsedVAA {
|
pub struct ParsedVAA {
|
||||||
pub version: u8,
|
pub version: u8,
|
||||||
pub guardian_set_index: u32,
|
pub guardian_set_index: u32,
|
||||||
pub timestamp: u64,
|
pub timestamp: u32,
|
||||||
pub nonce: u32,
|
pub nonce: u32,
|
||||||
pub len_signers: u8,
|
pub len_signers: u8,
|
||||||
|
|
||||||
|
@ -68,13 +68,13 @@ impl ParsedVAA {
|
||||||
1 [65]uint8 signature
|
1 [65]uint8 signature
|
||||||
|
|
||||||
body:
|
body:
|
||||||
0 uint64 timestamp (unix in seconds)
|
0 uint32 timestamp (unix in seconds)
|
||||||
8 uint32 nonce
|
4 uint32 nonce
|
||||||
12 uint16 emitter_chain
|
8 uint16 emitter_chain
|
||||||
14 [32]uint8 emitter_address
|
10 [32]uint8 emitter_address
|
||||||
46 uint64 sequence
|
42 uint64 sequence
|
||||||
46 uint8 consistency_level
|
50 uint8 consistency_level
|
||||||
54 []uint8 payload
|
51 []uint8 payload
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub const HEADER_LEN: usize = 6;
|
pub const HEADER_LEN: usize = 6;
|
||||||
|
@ -83,12 +83,12 @@ impl ParsedVAA {
|
||||||
pub const GUARDIAN_SET_INDEX_POS: usize = 1;
|
pub const GUARDIAN_SET_INDEX_POS: usize = 1;
|
||||||
pub const LEN_SIGNER_POS: usize = 5;
|
pub const LEN_SIGNER_POS: usize = 5;
|
||||||
|
|
||||||
pub const VAA_NONCE_POS: usize = 8;
|
pub const VAA_NONCE_POS: usize = 4;
|
||||||
pub const VAA_EMITTER_CHAIN_POS: usize = 12;
|
pub const VAA_EMITTER_CHAIN_POS: usize = 8;
|
||||||
pub const VAA_EMITTER_ADDRESS_POS: usize = 14;
|
pub const VAA_EMITTER_ADDRESS_POS: usize = 10;
|
||||||
pub const VAA_SEQUENCE_POS: usize = 46;
|
pub const VAA_SEQUENCE_POS: usize = 42;
|
||||||
pub const VAA_CONSISTENCY_LEVEL_POS: usize = 54;
|
pub const VAA_CONSISTENCY_LEVEL_POS: usize = 50;
|
||||||
pub const VAA_PAYLOAD_POS: usize = 55;
|
pub const VAA_PAYLOAD_POS: usize = 51;
|
||||||
|
|
||||||
// Signature data offsets in the signature block
|
// Signature data offsets in the signature block
|
||||||
pub const SIG_DATA_POS: usize = 1;
|
pub const SIG_DATA_POS: usize = 1;
|
||||||
|
@ -124,7 +124,7 @@ impl ParsedVAA {
|
||||||
return ContractError::InvalidVAA.std_err();
|
return ContractError::InvalidVAA.std_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
let timestamp = data.get_u64(body_offset);
|
let timestamp = data.get_u32(body_offset);
|
||||||
let nonce = data.get_u32(body_offset + Self::VAA_NONCE_POS);
|
let nonce = data.get_u32(body_offset + Self::VAA_NONCE_POS);
|
||||||
let emitter_chain = data.get_u16(body_offset + Self::VAA_EMITTER_CHAIN_POS);
|
let emitter_chain = data.get_u16(body_offset + Self::VAA_EMITTER_CHAIN_POS);
|
||||||
let emitter_address = data
|
let emitter_address = data
|
||||||
|
@ -402,31 +402,29 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize() {
|
fn test_deserialize() {
|
||||||
let x = vec![
|
let x = hex::decode("080000000901007bfa71192f886ab6819fa4862e34b4d178962958d9b2e3d9437338c9e5fde1443b809d2886eaa69e0f0158ea517675d96243c9209c3fe1d94d5b19866654c6980000000b150000000500020001020304000000000000000000000000000000000000000000000000000000000000000000000a0261626364").unwrap();
|
||||||
1u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 96u8, 180u8, 80u8, 111u8, 0u8, 0u8,
|
let v = ParsedVAA::deserialize(x.as_slice()).unwrap();
|
||||||
0u8, 1u8, 0u8, 3u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 120u8,
|
assert_eq!(
|
||||||
73u8, 153u8, 19u8, 90u8, 170u8, 138u8, 60u8, 165u8, 145u8, 68u8, 104u8, 133u8, 47u8,
|
v,
|
||||||
221u8, 219u8, 221u8, 216u8, 120u8, 157u8, 0u8, 91u8, 48u8, 44u8, 48u8, 44u8, 51u8,
|
ParsedVAA {
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
version: 8,
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 54u8, 44u8,
|
guardian_set_index: 9,
|
||||||
50u8, 51u8, 51u8, 44u8, 49u8, 44u8, 49u8, 49u8, 49u8, 44u8, 49u8, 54u8, 55u8, 44u8,
|
timestamp: 2837,
|
||||||
49u8, 57u8, 48u8, 44u8, 50u8, 48u8, 51u8, 44u8, 49u8, 54u8, 44u8, 49u8, 55u8, 54u8,
|
nonce: 5,
|
||||||
44u8, 50u8, 49u8, 56u8, 44u8, 50u8, 53u8, 49u8, 44u8, 49u8, 51u8, 49u8, 44u8, 51u8,
|
len_signers: 1,
|
||||||
57u8, 44u8, 49u8, 54u8, 44u8, 49u8, 57u8, 53u8, 44u8, 50u8, 50u8, 55u8, 44u8, 49u8,
|
emitter_chain: 2,
|
||||||
52u8, 57u8, 44u8, 50u8, 51u8, 54u8, 44u8, 49u8, 57u8, 48u8, 44u8, 50u8, 49u8, 50u8,
|
emitter_address: vec![
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
0, 0, 0, 0, 0, 0
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
],
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
sequence: 10,
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 51u8, 44u8, 50u8, 51u8, 50u8, 44u8, 48u8, 44u8, 51u8,
|
consistency_level: 2,
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8,
|
payload: vec![97, 98, 99, 100],
|
||||||
44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 48u8, 44u8, 53u8, 51u8, 44u8,
|
hash: vec![
|
||||||
49u8, 49u8, 54u8, 44u8, 52u8, 56u8, 44u8, 49u8, 49u8, 54u8, 44u8, 49u8, 52u8, 57u8,
|
195, 10, 19, 96, 8, 61, 218, 69, 160, 238, 165, 142, 105, 119, 139, 121, 212,
|
||||||
44u8, 49u8, 48u8, 56u8, 44u8, 49u8, 49u8, 51u8, 44u8, 56u8, 44u8, 48u8, 44u8, 50u8,
|
73, 238, 179, 13, 80, 245, 224, 75, 110, 163, 8, 185, 132, 55, 34
|
||||||
51u8, 50u8, 44u8, 52u8, 57u8, 44u8, 49u8, 53u8, 50u8, 44u8, 49u8, 44u8, 50u8, 56u8,
|
]
|
||||||
44u8, 50u8, 48u8, 51u8, 44u8, 50u8, 49u8, 50u8, 44u8, 50u8, 50u8, 49u8, 44u8, 50u8,
|
}
|
||||||
52u8, 49u8, 44u8, 56u8, 53u8, 44u8, 49u8, 48u8, 57u8, 93u8,
|
);
|
||||||
];
|
|
||||||
ParsedVAA::deserialize(x.as_slice()).unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue