Forráskód Böngészése

Fixes to VAA submission to Terra smart contract (#115)

* Terra smart contract binary interface changed from vector to base64 string

* Added initial guardian set submission to Terra
Yuriy Savchenko 5 éve
szülő
commit
ee5d07c929

+ 10 - 0
bridge/pkg/processor/processor.go

@@ -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"
 )
 
@@ -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
 		}

+ 1 - 15
bridge/pkg/terra/sender.go

@@ -3,8 +3,6 @@ package terra
 import (
 	"context"
 	"encoding/json"
-	"fmt"
-	"strings"
 	"time"
 
 	"github.com/certusone/wormhole/bridge/pkg/vaa"
@@ -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

+ 4 - 4
devnet/terra-configmaps.yaml

@@ -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
@@ -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",
@@ -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
@@ -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",

+ 2 - 2
terra/contracts/cw20-wrapped/src/contract.rs

@@ -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,
@@ -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(),
             }
         );

+ 2 - 2
terra/contracts/cw20-wrapped/src/msg.rs

@@ -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>,
@@ -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
 }

+ 2 - 2
terra/contracts/cw20-wrapped/src/state.rs

@@ -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";
@@ -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
 }
 

+ 5 - 17
terra/contracts/cw20-wrapped/tests/integration.rs

@@ -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::{
@@ -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,
@@ -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?,
             }
         );
@@ -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);
@@ -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()

+ 10 - 10
terra/contracts/wormhole/src/contract.rs

@@ -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),
     }
 }
@@ -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;
     }
@@ -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)?,
@@ -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(),
                             })?,
                         }),
                     })?,
@@ -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> {
@@ -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
@@ -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;
         }
@@ -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"), &[]);
 

+ 4 - 4
terra/contracts/wormhole/src/msg.rs

@@ -1,4 +1,4 @@
-use cosmwasm_std::{HumanAddr, Uint128};
+use cosmwasm_std::{HumanAddr, Uint128, Binary};
 use schemars::JsonSchema;
 use serde::{Deserialize, Serialize};
 
@@ -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,
     },

+ 3 - 3
terra/contracts/wormhole/src/state.rs

@@ -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,
@@ -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)]
@@ -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(),
         }
     }
 }

+ 1 - 1
terra/contracts/wormhole/tests/integration.rs

@@ -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);
 }

+ 1 - 1
terra/tools/lock-token.ts

@@ -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
         }});

+ 1 - 1
terra/tools/prepare-wormhole.ts

@@ -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
         },

+ 1 - 1
terra/tools/submit-vaa.ts

@@ -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');