Browse Source

Automatically register eth and solana token bridges

Change-Id: I35efef8d53f999f85ca2e8c4f58cc6cbf8193b2d
Hendrik Hofstadt 4 years ago
parent
commit
597aae7cd7

+ 2 - 1
.dockerignore

@@ -2,4 +2,5 @@ target
 bin
 solana/bridge/target
 solana/solitaire/target
-solana/modules/token_bridge/target
+solana/modules/token_bridge/target
+node_modules

+ 10 - 2
Dockerfile.client

@@ -1,15 +1,23 @@
 # syntax=docker.io/docker/dockerfile:experimental@sha256:de85b2f3a3e8a2f7fe48e8e84a65f6fdd5cd5183afa6412fff9caa6871649c44
 FROM docker.io/library/rust:1.49@sha256:a50165ea96983c21832578afb1c8c028674c965bc1ed43b607871b1f362e06a5
 
-RUN apt-get update && apt-get install -y libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang ncat
+RUN apt-get update && apt-get install -yq libssl-dev libudev-dev pkg-config zlib1g-dev llvm clang ncat
+RUN curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
 RUN rustup default nightly
 RUN rustup component add rustfmt
 
-WORKDIR /usr/src/solana
+ADD clients/token_bridge /usr/src/clients/token_bridge
+ADD ethereum /usr/src/ethereum
+
+WORKDIR /usr/src/clients/token_bridge
+RUN npm install
+RUN npm run build-contracts
+RUN npm run build
 
 ADD solana /usr/src/solana
 ADD proto  /usr/src/proto
 
+WORKDIR /usr/src/solana
 ENV EMITTER_ADDRESS="11111111111111111111111111111115"
 
 RUN --mount=type=cache,target=/usr/local/cargo,from=rust,source=/usr/local/cargo \

+ 1 - 1
Tiltfile

@@ -117,7 +117,7 @@ k8s_resource(
 docker_build(
     ref = "solana-client",
     context = ".",
-    only = ["./proto", "./solana"],
+    only = ["./proto", "./solana", "./ethereum", "./clients/token_bridge"],
     dockerfile = "Dockerfile.client",
 
     # Ignore target folders from local (non-container) development.

+ 1 - 0
clients/token_bridge/package.json

@@ -14,6 +14,7 @@
   },
   "scripts": {
     "start": "tsc && node main.js",
+    "build": "tsc",
     "test": "echo \"Error: no test specified\" && exit 1",
     "build-contracts": "npm run build --prefix ../../ethereum && node scripts/copyContracts.js && typechain --target=ethers-v5 --out-dir=src/ethers-contracts contracts/*.json"
   },

+ 1 - 1
devnet/eth-devnet.yaml

@@ -52,7 +52,7 @@ spec:
           command:
             - /bin/sh
             - -c
-            - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && nc -lkp 2000 0.0.0.0"
+            - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && nc -lkp 2000 0.0.0.0"
           readinessProbe:
             periodSeconds: 1
             failureThreshold: 300

+ 19 - 0
ethereum/scripts/register_solana_chain.js

@@ -0,0 +1,19 @@
+// run this script with truffle exec
+
+const jsonfile = require("jsonfile");
+const TokenBridge = artifacts.require("TokenBridge");
+const TokenImplementation = artifacts.require("TokenImplementation");
+const BridgeImplementationFullABI = jsonfile.readFileSync("../build/contracts/BridgeImplementation.json").abi
+
+module.exports = async function (callback) {
+    const initialized = new web3.eth.Contract(BridgeImplementationFullABI, TokenBridge.address);
+
+    // Register the Solana endpoint
+    await initialized.methods.registerChain("0x01000000000100c9f4230109e378f7efc0605fb40f0e1869f2d82fda5b1dfad8a5a2dafee85e033d155c18641165a77a2db6a7afbf2745b458616cb59347e89ae0c7aa3e7cc2d400000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000001c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f").send({
+        value: 0,
+        from: accounts[0],
+        gasLimit: 2000000
+    });
+
+    callback();
+}

+ 11 - 0
solana/bridge/program/src/types.rs

@@ -41,6 +41,7 @@ use std::{
         Deref,
         DerefMut,
     },
+    str::FromStr,
 };
 
 #[derive(Default, BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
@@ -196,12 +197,22 @@ pub struct PostedMessageData {
     pub payload: Vec<u8>,
 }
 
+#[cfg(not(feature = "cpi"))]
 impl Owned for PostedMessage {
     fn owner(&self) -> AccountOwner {
         AccountOwner::This
     }
 }
 
+#[cfg(feature = "cpi")]
+impl Owned for PostedMessage {
+    fn owner(&self) -> AccountOwner {
+        AccountOwner::Other(
+            Pubkey::from_str("Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o").unwrap(),
+        )
+    }
+}
+
 #[derive(Default, Clone, Copy, BorshDeserialize, BorshSerialize)]
 pub struct SequenceTracker {
     pub sequence: u64,

+ 3 - 0
solana/devnet_setup.sh

@@ -50,5 +50,8 @@ retry client create-bridge "$bridge_address" "$initial_guardian" 86400 100
 # Initialize the token bridge
 retry token-bridge-client create-bridge "$token_bridge_address" "$bridge_address"
 
+# Register the Solana Endpoint on ETH
+node /usr/src/clients/token_bridge/main.js solana execute_governance_vaa 01000000000100a1f5ebf9d460dbbbaf0b72df36b37139baac61bb3128eec2d77f2e53a57c15592f4c97521f8eb3a7279299219be0342877960a8bfa7da9782313bb0ff5855aba01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000002000000000000000000000000e982e462b094850f12af94d21d470e21be9d0e9c
+
 # Let k8s startup probe succeed
 nc -k -l -p 2000

+ 9 - 0
solana/modules/token_bridge/program/src/wasm.rs

@@ -47,6 +47,7 @@ use solitaire::{
 };
 use std::str::FromStr;
 use wasm_bindgen::prelude::*;
+use crate::accounts::EmitterAccount;
 
 #[wasm_bindgen]
 pub fn attest_ix(
@@ -387,6 +388,14 @@ pub fn register_chain_ix(
     return JsValue::from_serde(&ix).unwrap();
 }
 
+#[wasm_bindgen]
+pub fn emitter_address(program_id: String) -> Vec<u8> {
+    let program_id = Pubkey::from_str(program_id.as_str()).unwrap();
+    let emitter = EmitterAccount::key(None, &program_id);
+
+    emitter.to_bytes().to_vec()
+}
+
 #[wasm_bindgen]
 pub fn approval_authority_address(program_id: String) -> Vec<u8> {
     let program_id = Pubkey::from_str(program_id.as_str()).unwrap();