Skip to content

Commit

Permalink
Fixes to VAA submission to Terra smart contract (#115)
Browse files Browse the repository at this point in the history
* Terra smart contract binary interface changed from vector to base64 string

* Added initial guardian set submission to Terra
  • Loading branch information
ysavchenko authored Nov 19, 2020
1 parent e39fb2a commit ee5d07c
Show file tree
Hide file tree
Showing 14 changed files with 47 additions and 63 deletions.
10 changes: 10 additions & 0 deletions bridge/pkg/processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/certusone/wormhole/bridge/pkg/devnet"
gossipv1 "github.com/certusone/wormhole/bridge/pkg/proto/gossip/v1"
"github.com/certusone/wormhole/bridge/pkg/supervisor"
"github.com/certusone/wormhole/bridge/pkg/terra"
"github.com/certusone/wormhole/bridge/pkg/vaa"
)

Expand Down Expand Up @@ -167,6 +168,15 @@ func (p *Processor) checkDevModeGuardianSetUpdate(ctx context.Context) error {

p.logger.Info("devnet guardian set change submitted to Ethereum", zap.Any("trx", trx), zap.Any("vaa", v))

if p.terraChaidID != "" {
// Submit to Terra
trxResponse, err := terra.SubmitVAA(timeout, p.terraLCD, p.terraChaidID, p.terraContract, p.terraFeePayer, v)
if err != nil {
return fmt.Errorf("failed to submit devnet guardian set change: %v", err)
}
p.logger.Info("devnet guardian set change submitted to Terra", zap.Any("trxResponse", trxResponse), zap.Any("vaa", v))
}

// Submit VAA to Solana as well. This is asynchronous and can fail, leading to inconsistent devnet state.
p.vaaC <- v
}
Expand Down
16 changes: 1 addition & 15 deletions bridge/pkg/terra/sender.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package terra
import (
"context"
"encoding/json"
"fmt"
"strings"
"time"

"github.com/certusone/wormhole/bridge/pkg/vaa"
Expand All @@ -14,24 +12,12 @@ import (
"github.com/terra-project/terra.go/tx"
)

type JSONArraySlice []uint8

func (u JSONArraySlice) MarshalJSON() ([]uint8, error) {
var result string
if u == nil {
result = "null"
} else {
result = strings.Join(strings.Fields(fmt.Sprintf("%d", u)), ",")
}
return []byte(result), nil
}

type SubmitVAAMsg struct {
Params SubmitVAAParams `json:"submit_v_a_a"`
}

type SubmitVAAParams struct {
VAA JSONArraySlice `json:"vaa"`
VAA []byte `json:"vaa"`
}

// SubmitVAA prepares transaction with signed VAA and sends it to the Terra blockchain
Expand Down
8 changes: 4 additions & 4 deletions devnet/terra-configmaps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ data:
flush_throttle_timeout = "100ms"
# Maximum size of a message packet payload, in bytes
max_packet_msg_payload_size = 1024
max_packet_msg_payload_size = 4096
# Rate at which packets can be sent, in bytes/second
send_rate = 5120000
Expand Down Expand Up @@ -776,7 +776,7 @@ data:
"params": {
"max_contract_size": "512000",
"max_contract_gas": "100000000",
"max_contract_msg_size": "1024"
"max_contract_msg_size": "4096"
},
"last_code_id": "0",
"last_instance_id": "0",
Expand Down Expand Up @@ -1279,7 +1279,7 @@ data:
flush_throttle_timeout = "100ms"
# Maximum size of a message packet payload, in bytes
max_packet_msg_payload_size = 1024
max_packet_msg_payload_size = 4096
# Rate at which packets can be sent, in bytes/second
send_rate = 5120000
Expand Down Expand Up @@ -1813,7 +1813,7 @@ data:
"params": {
"max_contract_size": "512000",
"max_contract_gas": "100000000",
"max_contract_msg_size": "1024"
"max_contract_msg_size": "4096"
},
"last_code_id": "0",
"last_instance_id": "0",
Expand Down
4 changes: 2 additions & 2 deletions terra/contracts/cw20-wrapped/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ mod tests {
fn do_init<S: Storage, A: Api, Q: Querier>(deps: &mut Extern<S, A, Q>, creator: &HumanAddr) {
let init_msg = InitMsg {
asset_chain: 1,
asset_address: vec![1; 32],
asset_address: vec![1; 32].into(),
decimals: 10,
mint: None,
init_hook: None,
Expand All @@ -191,7 +191,7 @@ mod tests {
query_wrapped_asset_info(&deps).unwrap(),
WrappedAssetInfoResponse {
asset_chain: 1,
asset_address: vec![1; 32],
asset_address: vec![1; 32].into(),
bridge: creator.clone(),
}
);
Expand Down
4 changes: 2 additions & 2 deletions terra/contracts/cw20-wrapped/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cw20::Expiration;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct InitMsg {
pub asset_chain: u8,
pub asset_address: Vec<u8>,
pub asset_address: Binary,
pub decimals: u8,
pub mint: Option<InitMint>,
pub init_hook: Option<InitHook>,
Expand Down Expand Up @@ -105,6 +105,6 @@ pub enum QueryMsg {
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct WrappedAssetInfoResponse {
pub asset_chain: u8, // Asset chain id
pub asset_address: Vec<u8>, // Asset smart contract address in the original chain
pub asset_address: Binary, // Asset smart contract address in the original chain
pub bridge: HumanAddr, // Bridge address, authorized to mint and burn wrapped tokens
}
4 changes: 2 additions & 2 deletions terra/contracts/cw20-wrapped/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_std::{CanonicalAddr, ReadonlyStorage, Storage};
use cosmwasm_std::{CanonicalAddr, ReadonlyStorage, Storage, Binary};
use cosmwasm_storage::{singleton, singleton_read, ReadonlySingleton, Singleton};

pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset";
Expand All @@ -10,7 +10,7 @@ pub const KEY_WRAPPED_ASSET: &[u8] = b"wrappedAsset";
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct WrappedAssetInfo {
pub asset_chain: u8, // Asset chain id
pub asset_address: Vec<u8>, // Asset smart contract address on the original chain
pub asset_address: Binary, // Asset smart contract address on the original chain
pub bridge: CanonicalAddr, // Bridge address, authorized to mint and burn wrapped tokens
}

Expand Down
22 changes: 5 additions & 17 deletions terra/contracts/cw20-wrapped/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ static WASM: &[u8] =
include_bytes!("../../../target/wasm32-unknown-unknown/release/cw20_wrapped.wasm");

use cosmwasm_std::{
from_slice, Env, HandleResponse, HandleResult, HumanAddr, InitResponse, Uint128,
from_slice, Env, HandleResponse, HandleResult, HumanAddr, InitResponse, Uint128, Binary,
};
use cosmwasm_storage::to_length_prefixed;
use cosmwasm_vm::testing::{
Expand Down Expand Up @@ -51,7 +51,7 @@ fn do_init(height: u64) -> Instance<MockStorage, MockApi, MockQuerier> {
let mut deps = mock_instance(WASM, &[]);
let init_msg = InitMsg {
asset_chain: 1,
asset_address: vec![1; 32],
asset_address: vec![1; 32].into(),
decimals: 10,
mint: None,
init_hook: None,
Expand All @@ -67,7 +67,7 @@ fn do_init(height: u64) -> Instance<MockStorage, MockApi, MockQuerier> {
get_wrapped_asset_info(storage),
WrappedAssetInfo {
asset_chain: 1,
asset_address: vec![1; 32],
asset_address: vec![1; 32].into(),
bridge: api.canonical_address(&TestAddress::INITIALIZER.value()).0?,
}
);
Expand Down Expand Up @@ -141,18 +141,6 @@ fn check_token_details(deps: &mut Instance<MockStorage, MockApi, MockQuerier>, s
);
}

fn format_array(data: &Vec<u8>) -> String {
let mut result = String::new();

for num in &data[0..data.len() - 1] {
result.push_str(&num.to_string());
result.push_str(",");
}
result.push_str(&data[data.len() - 1].to_string());

result
}

#[test]
fn init_works() {
let mut deps = do_init(111);
Expand All @@ -168,9 +156,9 @@ fn query_works() {
query_response.as_slice(),
format!(
"{{\"asset_chain\":1,\
\"asset_address\":[{}],\
\"asset_address\":\"{}\",\
\"bridge\":\"{}\"}}",
format_array(&vec![1; 32]),
Binary::from(vec![1; 32]).to_base64(),
TestAddress::INITIALIZER.value().as_str()
)
.as_bytes()
Expand Down
20 changes: 10 additions & 10 deletions terra/contracts/wormhole/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ pub fn handle<S: Storage, A: Api, Q: Querier>(
msg: HandleMsg,
) -> StdResult<HandleResponse> {
match msg {
HandleMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, &vaa),
HandleMsg::RegisterAssetHook { asset_id } => handle_register_asset(deps, env, &asset_id),
HandleMsg::SubmitVAA { vaa } => handle_submit_vaa(deps, env, &vaa.as_slice()),
HandleMsg::RegisterAssetHook { asset_id } => handle_register_asset(deps, env, &asset_id.as_slice()),
HandleMsg::LockAssets {
asset,
recipient,
amount,
target_chain,
nonce,
} => handle_lock_assets(deps, env, asset, amount, recipient, target_chain, nonce),
} => handle_lock_assets(deps, env, asset, amount, recipient.as_slice(), target_chain, nonce),
HandleMsg::SetActive { is_active } => handle_set_active(deps, env, is_active),
}
}
Expand Down Expand Up @@ -249,7 +249,7 @@ fn vaa_update_guardian_set<S: Storage, A: Api, Q: Querier>(
let mut pos = 5;
for _ in 0..len {
new_guardian_set.addresses.push(GuardianAddress {
bytes: data[pos..pos + 20].to_vec(),
bytes: data[pos..pos + 20].to_vec().into(),
});
pos += 20;
}
Expand Down Expand Up @@ -351,7 +351,7 @@ fn vaa_transfer<S: Storage, A: Api, Q: Querier>(
code_id: state.wrapped_asset_code_id,
msg: to_binary(&WrappedInit {
asset_chain: token_chain,
asset_address: asset_address.to_vec(),
asset_address: asset_address.to_vec().into(),
decimals: data.get_u8(103),
mint: Some(InitMint {
recipient: deps.api.human_address(&target_address)?,
Expand All @@ -360,7 +360,7 @@ fn vaa_transfer<S: Storage, A: Api, Q: Querier>(
init_hook: Some(InitHook {
contract_addr: env.contract.address,
msg: to_binary(&HandleMsg::RegisterAssetHook {
asset_id: asset_id.to_vec(),
asset_id: asset_id.to_vec().into(),
})?,
}),
})?,
Expand Down Expand Up @@ -398,7 +398,7 @@ fn handle_lock_assets<S: Storage, A: Api, Q: Querier>(
env: Env,
asset: HumanAddr,
amount: Uint128,
recipient: Vec<u8>,
recipient: &[u8],
target_chain: u8,
nonce: u32,
) -> StdResult<HandleResponse> {
Expand Down Expand Up @@ -449,7 +449,7 @@ fn handle_lock_assets<S: Storage, A: Api, Q: Querier>(
let wrapped_token_info: WrappedAssetInfoResponse =
deps.querier.custom_query(&request)?;
asset_chain = wrapped_token_info.asset_chain;
asset_address = wrapped_token_info.asset_address;
asset_address = wrapped_token_info.asset_address.as_slice().to_vec();
}
Err(_) => {
// This is a regular asset, transfer its balance
Expand Down Expand Up @@ -544,7 +544,7 @@ fn keys_equal(a: &VerifyKey, b: &GuardianAddress) -> bool {
if a.len() != b.len() {
return false;
}
for (ai, bi) in a.iter().zip(b.iter()) {
for (ai, bi) in a.iter().zip(b.as_slice().iter()) {
if ai != bi {
return false;
}
Expand Down Expand Up @@ -594,7 +594,7 @@ mod tests {
vaa: &str,
) -> StdResult<HandleResponse> {
let msg = HandleMsg::SubmitVAA {
vaa: hex::decode(vaa).expect("Decoding failed"),
vaa: hex::decode(vaa).expect("Decoding failed").into(),
};
let env = mock_env(&HumanAddr::from("creator"), &[]);

Expand Down
8 changes: 4 additions & 4 deletions terra/contracts/wormhole/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use cosmwasm_std::{HumanAddr, Uint128};
use cosmwasm_std::{HumanAddr, Uint128, Binary};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

Expand All @@ -15,15 +15,15 @@ pub struct InitMsg {
#[serde(rename_all = "snake_case")]
pub enum HandleMsg {
SubmitVAA {
vaa: Vec<u8>,
vaa: Binary,
},
RegisterAssetHook {
asset_id: Vec<u8>,
asset_id: Binary,
},
LockAssets {
asset: HumanAddr,
amount: Uint128,
recipient: Vec<u8>,
recipient: Binary,
target_chain: u8,
nonce: u32,
},
Expand Down
6 changes: 3 additions & 3 deletions terra/contracts/wormhole/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use cosmwasm_std::{CanonicalAddr, HumanAddr, StdResult, Storage};
use cosmwasm_std::{CanonicalAddr, HumanAddr, StdResult, Storage, Binary};
use cosmwasm_storage::{
bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton,
Singleton,
Expand Down Expand Up @@ -34,7 +34,7 @@ pub struct ConfigInfo {
// Guardian address
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub struct GuardianAddress {
pub bytes: Vec<u8>, // 20-byte addresses
pub bytes: Binary, // 20-byte addresses
}

#[cfg(test)]
Expand All @@ -43,7 +43,7 @@ use hex;
impl GuardianAddress {
pub fn from(string: &str) -> GuardianAddress {
GuardianAddress {
bytes: hex::decode(string).expect("Decoding failed"),
bytes: hex::decode(string).expect("Decoding failed").into(),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion terra/contracts/wormhole/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn do_init(
#[test]
fn init_works() {
let guardians = vec![GuardianAddress::from(GuardianAddress {
bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe").expect("Decoding failed"),
bytes: hex::decode("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe").expect("Decoding failed").into(),
})];
let _deps = do_init(111, &guardians);
}
2 changes: 1 addition & 1 deletion terra/tools/lock-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function script() {
let lockResult = await execute_contract(wormhole_contract, {lock_assets: {
asset: token_contract,
amount,
recipient: [...Buffer.from('00000000000000000000000019a4437E2BA06bF1FA42C56Fb269Ca0d30f60716', 'hex')],
recipient: Buffer.from('00000000000000000000000019a4437E2BA06bF1FA42C56Fb269Ca0d30f60716', 'hex').toString('base64'),
target_chain: 2, // Ethereum
nonce: Date.now() % 1000000
}});
Expand Down
2 changes: 1 addition & 1 deletion terra/tools/prepare-wormhole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async function script() {
let contract_address = await instantiate_contract(wormhole_code_id, {
initial_guardian_set: {
addresses: [
{ bytes: [0xbe, 0xfa, 0x42, 0x9d, 0x57, 0xcd, 0x18, 0xb7, 0xf8, 0xa4, 0xd9, 0x1a, 0x2d, 0xa9, 0xab, 0x4a, 0xf0, 0x5d, 0x0f, 0xbe] }
{ bytes: Buffer.from('beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe', 'hex').toString('base64') }
],
expiration_time: 1000 * 60 * 60
},
Expand Down
2 changes: 1 addition & 1 deletion terra/tools/submit-vaa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ async function script() {

// Test VAA built using bridge/cmd/vaa-test
let vaaResult = await execute_contract(wormhole_contract, {submit_v_a_a: {
vaa: [...Buffer.from('010000000001005468beb21caff68710b2af2d60a986245bf85099509b6babe990a6c32456b44b3e2e9493e3056b7d5892957e14beab24be02dab77ed6c8915000e4a1267f78f400000007d01000000038018002010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000', 'hex')]
vaa: Buffer.from('010000000001001063f503dd308134e0f158537f54c5799719f4fa2687dd276c72ef60ae0c82c47d4fb560545afaabdf60c15918e221763fd1892c75f2098c0ffd5db4af254a4501000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000', 'hex').toString('base64')
}});
if (vaaResult == null) return;
console.log('Vaa submitted');
Expand Down

0 comments on commit ee5d07c

Please sign in to comment.