Skip to content

Commit

Permalink
near/upgradeCheck: upgrade test
Browse files Browse the repository at this point in the history
  • Loading branch information
jumpsiegel committed Sep 7, 2022
1 parent 0954830 commit 175131c
Show file tree
Hide file tree
Showing 4 changed files with 336 additions and 2 deletions.
4 changes: 3 additions & 1 deletion near/Dockerfile.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ FROM debian@sha256:2ce44bbc00a79113c296d9d25524e15d423b23303fdbbe20190d2f96e0aeb
RUN apt-get update && apt-get install apt-utils && apt-get install -y python3 npm curl --no-install-recommends
RUN apt-get install -y build-essential git

ADD . .
ADD setup-rust.sh .
RUN ./setup-rust.sh
ADD . .
RUN make clean
RUN ./build-contracts.sh

FROM scratch AS near-contracts-export
Expand Down
2 changes: 1 addition & 1 deletion near/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ run: nearcore

.PHONY: clean
clean:
rm -rf nearcore node_modules contracts/*/target
rm -rf nearcore contracts/*/target


.PHONY: reset-force
Expand Down
1 change: 1 addition & 0 deletions near/contracts/wormhole/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ impl Wormhole {
true
}

#[private]
#[init(ignore_state)]
pub fn migrate() -> Self {
env::log_str(&format!("wormhole/{}#{}: migrate", file!(), line!(),));
Expand Down
331 changes: 331 additions & 0 deletions near/test/upgrade_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
// npx pretty-quick

const nearAPI = require("near-api-js");
const BN = require("bn.js");
const fs = require("fs");
const fetch = require("node-fetch");
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { TestLib } from "./testlib";
const { createHash } = require("crypto");

import { ChainId, CHAIN_ID_NEAR } from "@certusone/wormhole-sdk/lib/cjs/utils";

function hash(string: any) {
return createHash("sha256").update(string).digest("hex");
}

function getConfig(env: any) {
switch (env) {
case "sandbox":
case "local":
return {
networkId: "sandbox",
nodeUrl: "http://localhost:3030",
masterAccount: "test.near",
wormholeAccount:
Math.floor(Math.random() * 10000).toString() + "wormhole.test.near",
tokenAccount:
Math.floor(Math.random() * 10000).toString() + "token.test.near",
};
case "testnet":
return {
networkId: "testnet",
nodeUrl: "https://rpc.testnet.near.org",
masterAccount: "wormhole.testnet",
wormholeAccount: "wormhole.wormhole.testnet",
tokenAccount: "token.wormhole.testnet",
};
case "mainnet":
return {
networkId: "mainnet",
nodeUrl: "https://rpc.mainnet.near.org",
wormholeMasterAccount: "wormhole_crypto.near",
wormholeAccount: "contract.wormhole_crypto.near",
portalMasterAccount: "portalbridge.near",
tokenAccount: "contract.portalbridge.near",
};
}
return {};
}

async function initNear() {
let e = process.env.NEAR_ENV || "sandbox";

let config = getConfig(e);
let p = process.env.PROD_ENV || "mainnet";
let prod_config = getConfig(p);

let masterKey: any;

if (e === "sandbox") {
// Retrieve the validator key directly in the Tilt environment
const response = await fetch("http://localhost:3031/validator_key.json");

const keyFile = await response.json();

masterKey = nearAPI.utils.KeyPair.fromString(
keyFile.secret_key || keyFile.private_key
);
} else {
masterKey = nearAPI.utils.KeyPair.fromString(process.env.NEAR_PK);
}
let masterPubKey = masterKey.getPublicKey();

let keyStore = new nearAPI.keyStores.InMemoryKeyStore();
keyStore.setKey(config.networkId, config.masterAccount, masterKey);
keyStore.setKey(config.networkId, config.wormholeAccount, masterKey);
keyStore.setKey(config.networkId, config.tokenAccount, masterKey);

let near = await nearAPI.connect({
deps: {
keyStore,
},
networkId: config.networkId,
nodeUrl: config.nodeUrl,
});

let masterAccount = new nearAPI.Account(
near.connection,
config.masterAccount
);

let prod_near = await nearAPI.connect({
deps: {
keyStore,
},
networkId: prod_config.networkId,
nodeUrl: prod_config.nodeUrl,
});

console.log(
"Finish init NEAR masterAccount: " +
JSON.stringify(await masterAccount.getAccountBalance())
);

console.log("reading local wasms we want to upgrade to...");

const wormholeContract = await fs.readFileSync(
"artifacts/near_wormhole.wasm"
);
const tokenContract = await fs.readFileSync(
"artifacts/near_token_bridge.wasm"
);

console.log("reading current production code ("+p+") we want to upgrade from..");

let wormhole_prod_code;
if (process.env.WORMHOLE_CONTRACT) {
console.log("Reading " + process.env.WORMHOLE_CONTRACT);
wormhole_prod_code = await fs.readFileSync(process.env.WORMHOLE_CONTRACT);
} else {
wormhole_prod_code = Buffer.from(
(
await prod_near.connection.provider.query({
request_type: "view_code",
finality: "final",
account_id: prod_config.wormholeAccount,
})
).code_base64,
"base64"
);
}

let token_prod_code;

if (process.env.TOKEN_CONTRACT) {
console.log("Reading " + process.env.TOKEN_CONTRACT);
token_prod_code = await fs.readFileSync(process.env.TOKEN_CONTRACT);
} else {
token_prod_code = Buffer.from(
(
await prod_near.connection.provider.query({
request_type: "view_code",
finality: "final",
account_id: prod_config.tokenAccount,
})
).code_base64,
"base64"
);
}

console.log(
"Deploying production ("+p+") wormhole contract to " + config.wormholeAccount
);
let wormholeAccount = await masterAccount.createAndDeployContract(
config.wormholeAccount,
masterKey.getPublicKey(),
wormhole_prod_code,
new BN("20000000000000000000000000")
);

await wormholeAccount.functionCall({
contractId: config.wormholeAccount,
methodName: "register_emitter",
args: { emitter: config.tokenAccount },
attachedDeposit: new BN("30000000000000000000000"),
gas: new BN("100000000000000"),
});

let tokenAccount: any;

console.log("Deploying production ("+p+") token contract to " + config.tokenAccount);
tokenAccount = await masterAccount.createAndDeployContract(
config.tokenAccount,
masterKey.getPublicKey(),
token_prod_code,
new BN("20000000000000000000000000")
);

let signers: any[] = [];

let vaasToken: any[] = [];
let vaasNFT: any[] = [];

let lines = fs.readFileSync(".env", "utf-8").split("\n");

lines.forEach((line: any) => {
let f = line.split("=");
if (f[0] === "INIT_SIGNERS") {
signers = eval(f[1]);
}
if (f[0].startsWith("REGISTER_") && f[0].endsWith("TOKEN_BRIDGE_VAA")) {
vaasToken.push(f[1]);
} else if (f[0].endsWith("TOKEN_BRIDGE_VAA_REGISTER")) {
vaasToken.push(f[1]);
}

if (f[0].startsWith("REGISTER_") && f[0].endsWith("NFT_BRIDGE_VAA")) {
vaasNFT.push(f[1]);
} else if (
f[0].endsWith("NFT_BRIDGE_VAA") ||
f[0].endsWith("NFT_BRIDGE_VAA_REGISTER")
) {
vaasNFT.push(f[1]);
}
});

if (e === "sandbox") {
let result = await masterAccount.functionCall({
contractId: config.wormholeAccount,
methodName: "boot_wormhole",
args: {
gset: 0,
addresses: signers,
},
gas: 100000000000000,
});

console.log("Booting up the token bridge");

result = await masterAccount.functionCall({
contractId: config.tokenAccount,
methodName: "boot_portal",
args: {
core: config.wormholeAccount,
},
gas: 100000000000000,
});
}

console.log("token bridge booted.. now the fun begins");

let ts = new TestLib();
let seq = 1;
let h = hash(wormholeContract);
console.log(h);
let vaa = ts.genCoreUpdate(
ts.singleGuardianPrivKey,
0,
0,
seq,
CHAIN_ID_NEAR,
h
);

console.log("submitting vaa to wormhole contract for upgrade");

let result;

result = await masterAccount.functionCall({
contractId: config.wormholeAccount,
methodName: "submit_vaa",
args: { vaa: vaa },
attachedDeposit: "12500000000000000000000",
gas: new BN("150000000000000"),
});

console.log("calling upgradeContract");

// result = await wormholeAccount.deployContract(wormholeContract);

result = await masterAccount.functionCall({
contractId: config.wormholeAccount,
methodName: "update_contract",
args: wormholeContract,
attachedDeposit: "5279790000000000000000000",
gas: 300000000000000,
});

console.log("---");
console.log("lets do a health check on the wormhole contract");

console.log(
"message_fee returned: " +
(await masterAccount.viewFunction(
config.wormholeAccount,
"message_fee",
{}
))
);

h = hash(tokenContract);
seq = seq + 1;
vaa = ts.genTokenUpdate(
ts.singleGuardianPrivKey,
0,
0,
seq,
CHAIN_ID_NEAR,
h
);

console.log("submitting vaa");
result = await masterAccount.functionCall({
contractId: config.tokenAccount,
methodName: "submit_vaa",
args: { vaa: vaa },
attachedDeposit: "12500000000000000000000",
gas: new BN("150000000000000"),
});

console.log("submitting vaa again");
result = await masterAccount.functionCall({
contractId: config.tokenAccount,
methodName: "submit_vaa",
args: { vaa: vaa },
attachedDeposit: "12500000000000000000000",
gas: new BN("150000000000000"),
});

console.log("calling upgradeContract on the token bridge");

// result = await tokenAccount.deployContract(tokenContract);

result = await masterAccount.functionCall({
contractId: config.tokenAccount,
methodName: "update_contract",
args: tokenContract,
attachedDeposit: "22797900000000000000000000",
gas: 300000000000000,
});

console.log("---");
console.log("lets do a health check on the token bridge contract");

console.log(
"emitter returned: " +
(await masterAccount.viewFunction(config.tokenAccount, "emitter", {}))
);
}

initNear();

0 comments on commit 175131c

Please sign in to comment.