ci: switch from ganache to anvil

This commit is contained in:
Evan Gray 2024-04-04 11:44:02 -04:00 committed by Evan Gray
parent fcabf0c99e
commit 77b4ddc812
36 changed files with 352 additions and 422 deletions

View File

@ -34,8 +34,7 @@ jobs:
kubectl config set-context ci --namespace=$DEPLOY_NS kubectl config set-context ci --namespace=$DEPLOY_NS
kubectl config use-context ci kubectl config use-context ci
# temporarily set --guardiand_loglevel=info to debug https://github.com/wormhole-foundation/wormhole/issues/3052 - run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2
- run: tilt ci --timeout 45m0s -- --ci --namespace=$DEPLOY_NS --num=2 --guardiand_loglevel=info
timeout-minutes: 60 timeout-minutes: 60
# Clean up k8s resources # Clean up k8s resources

View File

@ -37,7 +37,7 @@ Launch the devnet:
tilt up tilt up
By default this runs a network consisting of one guardian, two ganache (Eth) chains, a Solana test validator, an Algorand sandbox, and LocalTerra for both Terra Classic and Terra 2. If you want to work on non-consensus parts of the code, running with a single guardian is easiest since you won't have to wait for k8s to restart all pods. See the usage guide below for arguments to customize the tilt network. By default this runs a network consisting of one guardian, two anvil (Eth) chains, a Solana test validator, an Algorand sandbox, and LocalTerra for both Terra Classic and Terra 2. If you want to work on non-consensus parts of the code, running with a single guardian is easiest since you won't have to wait for k8s to restart all pods. See the usage guide below for arguments to customize the tilt network.
## Usage ## Usage
@ -140,28 +140,40 @@ To re-generate these files run `rm -rf node/pkg/proto && docker build --target g
### Call gRPC services ### Call gRPC services
<!-- cspell:disable-next-line --> <!-- cspell:disable -->
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) -plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) -plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
<!-- cspell:enable -->
With parameters (using proto json encoding): With parameters (using proto json encoding):
<!-- cspell:disable-next-line --> <!-- cspell:disable -->
tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) \ tools/bin/grpcurl -protoset <(tools/bin/buf build -o -) \
-d '{"filters": [{"emitter_filter": {"emitter_address": "574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d", "chain_id": "CHAIN_ID_SOLANA"}}]}' \ -d '{"filters": [{"emitter_filter": {"emitter_address": "574108aed69daf7e625a361864b1f74d13702f2ca56de9660e566d1d8691848d", "chain_id": "CHAIN_ID_SOLANA"}}]}' \
-plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA -plaintext localhost:7072 spy.v1.SpyRPCService/SubscribeSignedVAA
<!-- cspell:enable -->
### Post messages ### Post messages
To Solana: To Solana:
<!-- cspell:disable-next-line --> <!-- cspell:disable -->
kubectl exec solana-devnet-0 -c setup -- client post-message Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff kubectl exec solana-devnet-0 -c setup -- client post-message Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
<!-- cspell:enable -->
To Solana as CPI instruction: To Solana as CPI instruction:
<!-- cspell:disable-next-line --> <!-- cspell:disable -->
kubectl exec solana-devnet-0 -c setup -- client post-message --proxy CP1co2QMMoDPbsmV7PGcUTLFwyhgCgTXt25gLQ5LewE1 Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff kubectl exec solana-devnet-0 -c setup -- client post-message --proxy CP1co2QMMoDPbsmV7PGcUTLFwyhgCgTXt25gLQ5LewE1 Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o 1 confirmed ffff
<!-- cspell:enable -->
### Observation Requests ### Observation Requests
kubectl exec -it guardian-0 -- /guardiand admin send-observation-request --socket /tmp/admin.sock 1 4636d8f7593c78a5092bed13dec765cc705752653db5eb1498168c92345cd389 kubectl exec -it guardian-0 -- /guardiand admin send-observation-request --socket /tmp/admin.sock 1 4636d8f7593c78a5092bed13dec765cc705752653db5eb1498168c92345cd389

View File

@ -534,7 +534,7 @@ k8s_yaml_with_ns("devnet/eth-devnet.yaml")
k8s_resource( k8s_resource(
"eth-devnet", "eth-devnet",
port_forwards = [ port_forwards = [
port_forward(8545, name = "Ganache RPC [:8545]", host = webHost), port_forward(8545, name = "Anvil RPC [:8545]", host = webHost),
], ],
labels = ["evm"], labels = ["evm"],
trigger_mode = trigger_mode, trigger_mode = trigger_mode,
@ -546,7 +546,7 @@ if evm2:
k8s_resource( k8s_resource(
"eth-devnet2", "eth-devnet2",
port_forwards = [ port_forwards = [
port_forward(8546, name = "Ganache RPC [:8546]", host = webHost), port_forward(8546, 8545, name = "Anvil RPC [:8546]", host = webHost),
], ],
labels = ["evm"], labels = ["evm"],
trigger_mode = trigger_mode, trigger_mode = trigger_mode,

View File

@ -31,19 +31,16 @@ spec:
spec: spec:
terminationGracePeriodSeconds: 1 terminationGracePeriodSeconds: 1
containers: containers:
- name: ganache - name: anvil
image: eth-node image: eth-node
command: command:
- npx - anvil
- ganache-cli - --silent
- --logging.quiet - --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect
- --wallet.defaultBalance=10000 - --block-time=1
- --wallet.deterministic
- --chain.time="1970-01-01T00:00:00+00:00"
- --host=0.0.0.0 - --host=0.0.0.0
- --wallet.totalAccounts=13 - --accounts=13
- --chain.chainId=1337 - --chain-id=1337
- --chain.asyncRequestProcessing=false
ports: ports:
- containerPort: 8545 - containerPort: 8545
name: rpc name: rpc
@ -64,11 +61,5 @@ spec:
initialDelaySeconds: 90 initialDelaySeconds: 90
tcpSocket: tcpSocket:
port: 2000 port: 2000
- name: mine
image: eth-node
command:
- /bin/sh
- -c
- "cd ../../ethereum && npx truffle exec mine.js"
--- ---

View File

@ -32,19 +32,16 @@ spec:
spec: spec:
terminationGracePeriodSeconds: 1 terminationGracePeriodSeconds: 1
containers: containers:
- name: ganache - name: anvil
image: eth-node image: eth-node
command: command:
- npx - anvil
- ganache-cli - --silent
- --logging.quiet - --mnemonic=myth like bonus scare over problem client lizard pioneer submit female collect
- --wallet.defaultBalance=10000 - --block-time=1
- --wallet.deterministic
- --chain.time="1970-01-01T00:00:00+00:00"
- --host=0.0.0.0 - --host=0.0.0.0
- --wallet.totalAccounts=13 - --accounts=13
- --chain.chainId=1397 - --chain-id=1397
- --chain.asyncRequestProcessing=false
ports: ports:
- containerPort: 8545 - containerPort: 8545
name: rpc name: rpc
@ -65,9 +62,3 @@ spec:
initialDelaySeconds: 90 initialDelaySeconds: 90
tcpSocket: tcpSocket:
port: 2000 port: 2000
- name: mine
image: eth-node
command:
- /bin/sh
- -c
- "cd ../../ethereum && npx truffle exec mine.js"

View File

@ -14,6 +14,7 @@ RUN $HOME/.foundry/bin/foundryup
RUN ls $HOME/.foundry/bin RUN ls $HOME/.foundry/bin
# Run as user, otherwise, npx explodes. # Run as user, otherwise, npx explodes.
RUN mv /root/.foundry/bin/anvil /bin/anvil
RUN mv /root/.foundry/bin/forge /bin/forge RUN mv /root/.foundry/bin/forge /bin/forge
USER 1000 USER 1000

View File

@ -1,6 +0,0 @@
#!/usr/bin/env bash
# This script copies package{-lock}.json from a running container.
set -e
kubectl cp -c ganache eth-devnet-0:package.json package.json
kubectl cp -c ganache eth-devnet-0:package-lock.json package-lock.json

View File

@ -1,36 +0,0 @@
/*
This script advances Ganache network state. It runs as a sidecar pod alongside the devnet and
ensures that manual token transfers triggered through the web UI will be able to be confirmed.
*/
advanceBlock = () => {
return new Promise((resolve, reject) => {
web3.currentProvider.send({
jsonrpc: "2.0",
method: "evm_mine",
id: new Date().getTime()
}, (err, result) => {
if (err) {
return reject(err);
}
const newBlockHash = web3.eth.getBlock('latest').hash;
return resolve(newBlockHash)
});
});
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
module.exports = function(callback) {
const fn = async () => {
while (true) {
await advanceBlock();
await sleep(1000);
}
}
fn().catch(reason => console.error(reason))
}

View File

@ -19,6 +19,9 @@ type (
// maxCacheSize is used to trim the cache. // maxCacheSize is used to trim the cache.
maxCacheSize int maxCacheSize int
// unsafeDevMode is used to suppress warnings in dev mode.
unsafeDevMode bool
// mutex is used to protect the cache. // mutex is used to protect the cache.
mutex sync.Mutex mutex sync.Mutex
} }
@ -32,10 +35,11 @@ type (
) )
// NewBlocksByTimestamp creates an empty cache of blocks by timestamp. // NewBlocksByTimestamp creates an empty cache of blocks by timestamp.
func NewBlocksByTimestamp(maxCacheSize int) *BlocksByTimestamp { func NewBlocksByTimestamp(maxCacheSize int, unsafeDevMode bool) *BlocksByTimestamp {
return &BlocksByTimestamp{ return &BlocksByTimestamp{
cache: Blocks{}, cache: Blocks{},
maxCacheSize: maxCacheSize, maxCacheSize: maxCacheSize,
unsafeDevMode: unsafeDevMode,
} }
} }
@ -55,12 +59,15 @@ func (bts *BlocksByTimestamp) AddLatest(logger *zap.Logger, timestamp uint64, bl
} }
} }
logger.Warn("rollback detected in timestamp cache", // Anvil trips this when using `anvil_mine`
zap.Uint64("oldLatestBlockNum", bts.cache[l-1].BlockNum), if !bts.unsafeDevMode {
zap.Uint64("oldLatestTimestamp", bts.cache[l-1].Timestamp), logger.Warn("rollback detected in timestamp cache",
zap.Uint64("newLatestBlockNum", blockNum), zap.Uint64("oldLatestBlockNum", bts.cache[l-1].BlockNum),
zap.Uint64("newLatestTimestamp", timestamp), zap.Uint64("oldLatestTimestamp", bts.cache[l-1].Timestamp),
) zap.Uint64("newLatestBlockNum", blockNum),
zap.Uint64("newLatestTimestamp", timestamp),
)
}
bts.cache = bts.cache[:idx+1] bts.cache = bts.cache[:idx+1]
} }

View File

@ -24,7 +24,7 @@ func cacheIsValid(t *testing.T, bts *BlocksByTimestamp) bool {
} }
func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) { func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) {
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS) bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
// Empty cache is valid. // Empty cache is valid.
assert.True(t, cacheIsValid(t, bts)) assert.True(t, cacheIsValid(t, bts))
@ -61,7 +61,7 @@ func TestBlocksByTimestamp_TestCacheIsValid(t *testing.T) {
func TestBlocksByTimestamp_AddLatest(t *testing.T) { func TestBlocksByTimestamp_AddLatest(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS) bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
bts.AddLatest(logger, 1698621628, 420) bts.AddLatest(logger, 1698621628, 420)
bts.AddLatest(logger, 1698621628, 421) bts.AddLatest(logger, 1698621628, 421)
@ -89,7 +89,7 @@ func TestBlocksByTimestamp_AddLatest(t *testing.T) {
func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) { func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS) bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
bts.AddLatest(logger, 1698621628, 420) bts.AddLatest(logger, 1698621628, 420)
require.Equal(t, 1, len(bts.cache)) require.Equal(t, 1, len(bts.cache))
@ -138,7 +138,7 @@ func TestBlocksByTimestamp_AddLatestRollbackEverything(t *testing.T) {
func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) { func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(5) bts := NewBlocksByTimestamp(5, false)
bts.AddLatest(logger, 1698621628, 420) bts.AddLatest(logger, 1698621628, 420)
bts.AddLatest(logger, 1698621628, 421) bts.AddLatest(logger, 1698621628, 421)
@ -161,7 +161,7 @@ func TestBlocksByTimestamp_AddLatestShouldTrimTheCache(t *testing.T) {
func TestBlocksByTimestamp_AddBatch(t *testing.T) { func TestBlocksByTimestamp_AddBatch(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS) bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
// First create a cache with some gaps in it. // First create a cache with some gaps in it.
bts.AddLatest(logger, 1698621628, 420) bts.AddLatest(logger, 1698621628, 420)
@ -192,7 +192,7 @@ func TestBlocksByTimestamp_AddBatch(t *testing.T) {
func TestBlocksByTimestamp_AddBatchShouldTrim(t *testing.T) { func TestBlocksByTimestamp_AddBatchShouldTrim(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(8) bts := NewBlocksByTimestamp(8, false)
// First create a cache with some gaps in it. // First create a cache with some gaps in it.
bts.AddLatest(logger, 1698621628, 420) bts.AddLatest(logger, 1698621628, 420)
@ -249,7 +249,7 @@ func TestBlocksByTimestamp_SearchForTimestamp(t *testing.T) {
func TestBlocksByTimestamp_LookUp(t *testing.T) { func TestBlocksByTimestamp_LookUp(t *testing.T) {
logger := zap.NewNop() logger := zap.NewNop()
bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS) bts := NewBlocksByTimestamp(BTS_MAX_BLOCKS, false)
// Empty cache. // Empty cache.
prev, next, found := bts.LookUp(1698621627) prev, next, found := bts.LookUp(1698621627)

View File

@ -260,7 +260,7 @@ func (w *Watcher) Run(parentCtx context.Context) error {
} }
if w.ccqConfig.TimestampCacheSupported { if w.ccqConfig.TimestampCacheSupported {
w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS) w.ccqTimestampCache = NewBlocksByTimestamp(BTS_MAX_BLOCKS, w.unsafeDevMode)
} }
errC := make(chan error) errC := make(chan error)
@ -702,7 +702,6 @@ func (w *Watcher) getFinality(ctx context.Context) (bool, bool, error) {
finalized := false finalized := false
safe := false safe := false
if w.unsafeDevMode { if w.unsafeDevMode {
// Devnet supports finalized and safe (although they returns the same value as latest).
finalized = true finalized = true
safe = true safe = true
} else if w.chainID == vaa.ChainIDAcala || } else if w.chainID == vaa.ChainIDAcala ||

View File

@ -1,3 +1,13 @@
process.env.CI = true; process.env.CI = true;
const warn = console.warn;
console.warn = function (x) {
if (
x !==
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)"
) {
warn(x);
}
};
module.exports = {}; module.exports = {};

View File

@ -1,34 +1,26 @@
import { import { beforeAll, describe, expect, jest, test } from "@jest/globals";
afterAll, import axios, { AxiosResponse } from "axios";
beforeAll,
describe,
expect,
jest,
test,
} from "@jest/globals";
import Web3, { ETH_DATA_FORMAT } from "web3"; import Web3, { ETH_DATA_FORMAT } from "web3";
import axios from "axios";
import { AxiosResponse } from "axios";
import { import {
ChainQueryType, ChainQueryType,
EthCallByTimestampQueryRequest,
EthCallByTimestampQueryResponse,
EthCallData, EthCallData,
EthCallQueryRequest, EthCallQueryRequest,
EthCallByTimestampQueryRequest, EthCallQueryResponse,
EthCallWithFinalityQueryRequest, EthCallWithFinalityQueryRequest,
EthCallWithFinalityQueryResponse,
PerChainQueryRequest, PerChainQueryRequest,
QueryRequest, QueryRequest,
sign,
QueryResponse, QueryResponse,
EthCallQueryResponse, sign,
EthCallByTimestampQueryResponse,
EthCallWithFinalityQueryResponse,
} from ".."; } from "..";
jest.setTimeout(125000); jest.setTimeout(125000);
const CI = process.env.CI; const CI = process.env.CI;
const ENV = "DEVNET"; const ENV = "DEVNET";
const ETH_NODE_URL = CI ? "ws://eth-devnet:8545" : "ws://localhost:8545"; const ETH_NODE_URL = CI ? "http://eth-devnet:8545" : "http://localhost:8545";
const SERVER_URL = CI ? "http://query-server:" : "http://localhost:"; const SERVER_URL = CI ? "http://query-server:" : "http://localhost:";
const CCQ_SERVER_URL = SERVER_URL + "6069/v1"; const CCQ_SERVER_URL = SERVER_URL + "6069/v1";
@ -44,10 +36,6 @@ beforeAll(() => {
web3 = new Web3(ETH_NODE_URL); web3 = new Web3(ETH_NODE_URL);
}); });
afterAll(() => {
web3.provider?.disconnect();
});
function createTestEthCallData( function createTestEthCallData(
to: string, to: string,
name: string, name: string,
@ -162,7 +150,7 @@ describe("eth call", () => {
); );
const ecr = queryResponse.responses[0].response as EthCallQueryResponse; const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
expect(ecr.blockNumber).toEqual(BigInt(blockNumber)); expect(ecr.blockNumber.toString()).toEqual(BigInt(blockNumber).toString());
expect(ecr.blockHash).toEqual( expect(ecr.blockHash).toEqual(
(await web3.eth.getBlock(BigInt(blockNumber))).hash (await web3.eth.getBlock(BigInt(blockNumber))).hash
); );
@ -176,8 +164,7 @@ describe("eth call", () => {
"0x0000000000000000000000000000000000000000000000000000000000000012" "0x0000000000000000000000000000000000000000000000000000000000000012"
); );
}); });
// TODO: This test works in Goerli testnet but not devnet. Try it again after PR #3395 lands. test("get block by hash should work", async () => {
test.skip("get block by hash should work", async () => {
const nameCallData = createTestEthCallData(WETH_ADDRESS, "name", "string"); const nameCallData = createTestEthCallData(WETH_ADDRESS, "name", "string");
const decimalsCallData = createTestEthCallData( const decimalsCallData = createTestEthCallData(
WETH_ADDRESS, WETH_ADDRESS,
@ -461,11 +448,15 @@ describe("eth call", () => {
const ecr = queryResponse.responses[0] const ecr = queryResponse.responses[0]
.response as EthCallByTimestampQueryResponse; .response as EthCallByTimestampQueryResponse;
expect(ecr.targetBlockNumber).toEqual(BigInt(targetBlockNumber)); expect(ecr.targetBlockNumber.toString()).toEqual(
BigInt(targetBlockNumber).toString()
);
expect(ecr.targetBlockHash).toEqual( expect(ecr.targetBlockHash).toEqual(
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash (await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
); );
expect(ecr.followingBlockNumber).toEqual(BigInt(followingBlockNumber)); expect(ecr.followingBlockNumber.toString()).toEqual(
BigInt(followingBlockNumber).toString()
);
expect(ecr.followingBlockHash).toEqual( expect(ecr.followingBlockHash).toEqual(
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash (await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
); );
@ -523,11 +514,15 @@ describe("eth call", () => {
const ecr = queryResponse.responses[0] const ecr = queryResponse.responses[0]
.response as EthCallByTimestampQueryResponse; .response as EthCallByTimestampQueryResponse;
expect(ecr.targetBlockNumber).toEqual(BigInt(targetBlockNumber)); expect(ecr.targetBlockNumber.toString()).toEqual(
BigInt(targetBlockNumber).toString()
);
expect(ecr.targetBlockHash).toEqual( expect(ecr.targetBlockHash).toEqual(
(await web3.eth.getBlock(BigInt(targetBlockNumber))).hash (await web3.eth.getBlock(BigInt(targetBlockNumber))).hash
); );
expect(ecr.followingBlockNumber).toEqual(BigInt(followingBlockNumber)); expect(ecr.followingBlockNumber.toString()).toEqual(
BigInt(followingBlockNumber).toString()
);
expect(ecr.followingBlockHash).toEqual( expect(ecr.followingBlockHash).toEqual(
(await web3.eth.getBlock(BigInt(followingBlockNumber))).hash (await web3.eth.getBlock(BigInt(followingBlockNumber))).hash
); );
@ -703,9 +698,9 @@ describe("eth call", () => {
"decimals", "decimals",
"uint8" "uint8"
); );
// Jump into the future a bit so the watcher has to wait for finality. const blockNumber = Number(
const blockNumber = (await web3.eth.getBlock("finalized", false, ETH_DATA_FORMAT)).number
Number(await web3.eth.getBlockNumber(ETH_DATA_FORMAT)) + 10; );
const ethCall = new EthCallWithFinalityQueryRequest( const ethCall = new EthCallWithFinalityQueryRequest(
blockNumber.toString(16), blockNumber.toString(16),
"finalized", "finalized",
@ -740,7 +735,7 @@ describe("eth call", () => {
const ecr = queryResponse.responses[0] const ecr = queryResponse.responses[0]
.response as EthCallWithFinalityQueryResponse; .response as EthCallWithFinalityQueryResponse;
expect(ecr.blockNumber).toEqual(BigInt(blockNumber)); expect(ecr.blockNumber.toString()).toEqual(BigInt(blockNumber).toString());
expect(ecr.blockHash).toEqual( expect(ecr.blockHash).toEqual(
(await web3.eth.getBlock(BigInt(blockNumber))).hash (await web3.eth.getBlock(BigInt(blockNumber))).hash
); );
@ -881,7 +876,9 @@ describe("eth call", () => {
); );
const ecr = queryResponse.responses[0].response as EthCallQueryResponse; const ecr = queryResponse.responses[0].response as EthCallQueryResponse;
expect(ecr.blockNumber).toEqual(BigInt(blockNumber)); expect(ecr.blockNumber.toString()).toEqual(
BigInt(blockNumber).toString()
);
expect(ecr.blockHash).toEqual( expect(ecr.blockHash).toEqual(
(await web3.eth.getBlock(BigInt(blockNumber))).hash (await web3.eth.getBlock(BigInt(blockNumber))).hash
); );

View File

@ -1,3 +1,28 @@
process.env.CI = true; process.env.CI = true;
const info = console.info;
console.info = function (x) {
if (x !== "secp256k1 unavailable, reverting to browser version") {
info(x);
}
};
const warn = console.warn;
console.warn = function (x) {
if (
x !==
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)" &&
!(
typeof x === "object" &&
x
.toString()
.includes(
"RPC Validation Error: The response returned from RPC server does not match the TypeScript definition. This is likely because the SDK version is not compatible with the RPC server."
)
)
) {
warn(x);
}
};
export default {}; export default {};

View File

@ -5,5 +5,5 @@
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
"testPathIgnorePatterns": ["__tests__/utils"], "testPathIgnorePatterns": ["__tests__/utils"],
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"], "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"testTimeout": 60000 "testTimeout": 300000
} }

View File

@ -18,10 +18,10 @@
"build-lib": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && node scripts/copyEthersTypes.js", "build-lib": "tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && node scripts/copyEthersTypes.js",
"build-all": "npm run build-deps && npm run build-lib", "build-all": "npm run build-deps && npm run build-lib",
"docs": "typedoc src/index.ts", "docs": "typedoc src/index.ts",
"test": "DEV=true NETWORK=DEVNET jest --config jestconfig.json --verbose", "test": "DEV=true NETWORK=DEVNET jest --verbose",
"test-ci": "NETWORK=DEVNET NEAR_NO_LOGS=true jest --config jestconfig.json --verbose --setupFiles ./ci-config.js --forceExit", "test-ci": "NETWORK=DEVNET NEAR_NO_LOGS=true jest --verbose --setupFiles ./ci-config.js --forceExit",
"test-relayer-mainnet": "ENV=mainnet NETWORK=MAINNET npx jest --config jestconfig.json --verbose ./src/relayer/", "test-relayer-mainnet": "ENV=mainnet NETWORK=MAINNET npx jest --verbose ./src/relayer/",
"test-relayer-testnet": "ENV=testnet NETWORK=TESTNET npx jest --config jestconfig.json --verbose ./src/relayer/", "test-relayer-testnet": "ENV=testnet NETWORK=TESTNET npx jest --verbose ./src/relayer/",
"build": "npm run build-all", "build": "npm run build-all",
"format": "echo \"disabled: prettier --write \"src/**/*.ts\"\"", "format": "echo \"disabled: prettier --write \"src/**/*.ts\"\"",
"lint": "tslint -p tsconfig.json", "lint": "tslint -p tsconfig.json",

View File

@ -27,8 +27,6 @@ import { PopulateData, TmplSig } from "../TmplSig";
const CORE_ID = BigInt(1004); const CORE_ID = BigInt(1004);
const TOKEN_BRIDGE_ID = BigInt(1006); const TOKEN_BRIDGE_ID = BigInt(1006);
jest.setTimeout(120000);
describe("Unit Tests", () => { describe("Unit Tests", () => {
describe("Algorand unit tests", () => { describe("Algorand unit tests", () => {
test("Test TmplSig populate()", (done) => { test("Test TmplSig populate()", (done) => {

View File

@ -16,7 +16,7 @@ import {
getSignedVAABySequence, getSignedVAABySequence,
waitForTerraExecution, waitForTerraExecution,
} from "../../token_bridge/__tests__/utils/helpers"; } from "../../token_bridge/__tests__/utils/helpers";
import { CHAIN_ID_SEI, CHAIN_ID_TERRA2 } from "../../utils/consts"; import { CHAIN_ID_SEI } from "../../utils/consts";
const TERRA2_PRIVATE_KEY_4 = const TERRA2_PRIVATE_KEY_4 =
"bounce success option birth apple portion aunt rural episode solution hockey pencil lend session cause hedgehog slender journey system canvas decorate razor catch empty"; "bounce success option birth apple portion aunt rural episode solution hockey pencil lend session cause hedgehog slender journey system canvas decorate razor catch empty";
@ -58,7 +58,6 @@ const terraBroadcastTxAndGetSignedVaa = async (
if (!txSequence) { if (!txSequence) {
throw new Error("tx sequence not found"); throw new Error("tx sequence not found");
} }
console.log(`${CHAIN_ID_SEI}/${emitter}/${txSequence}`);
return await getSignedVAABySequence(CHAIN_ID_SEI, txSequence, emitter); return await getSignedVAABySequence(CHAIN_ID_SEI, txSequence, emitter);
}; };
@ -79,6 +78,5 @@ describe("IBC Watcher Integration Tests", () => {
terraWallet, terraWallet,
await getEmitterAddressTerra(terraWalletAddress) await getEmitterAddressTerra(terraWalletAddress)
); );
console.log(postedVaa);
}); });
}); });

View File

@ -55,8 +55,6 @@ import {
getSignedVaaSolana, getSignedVaaSolana,
} from "./utils/getSignedVaa"; } from "./utils/getSignedVaa";
jest.setTimeout(120000);
const APTOS_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.aptos.nft_bridge; const APTOS_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.aptos.nft_bridge;
const ETH_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.nft_bridge; const ETH_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.nft_bridge;
const SOLANA_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.solana.nft_bridge; const SOLANA_NFT_BRIDGE_ADDRESS = CONTRACTS.DEVNET.solana.nft_bridge;
@ -69,7 +67,7 @@ let faucet: FaucetClient;
// ethereum setup // ethereum setup
const web3 = new Web3(ETH_NODE_URL); const web3 = new Web3(ETH_NODE_URL);
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY8, ethProvider); const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY8, ethProvider);
// solana setup // solana setup
@ -86,7 +84,6 @@ beforeEach(async () => {
afterAll(async () => { afterAll(async () => {
(web3.currentProvider as any).disconnect(); (web3.currentProvider as any).disconnect();
await ethProvider.destroy();
}); });
describe("Aptos NFT SDK tests", () => { describe("Aptos NFT SDK tests", () => {
@ -112,6 +109,7 @@ describe("Aptos NFT SDK tests", () => {
CHAIN_ID_APTOS, CHAIN_ID_APTOS,
aptosAccount.address().toUint8Array() aptosAccount.address().toUint8Array()
); );
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// observe tx and get vaa // observe tx and get vaa
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx); const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
@ -313,6 +311,7 @@ describe("Aptos NFT SDK tests", () => {
tryNativeToUint8Array(aptosAccount.address().toString(), CHAIN_ID_APTOS) tryNativeToUint8Array(aptosAccount.address().toString(), CHAIN_ID_APTOS)
); );
expect(ethTransferTx.status).toBe(1); expect(ethTransferTx.status).toBe(1);
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// observe tx and get vaa // observe tx and get vaa
const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx); const ethTransferVaa = await getSignedVaaEthereum(ethTransferTx);
@ -455,6 +454,7 @@ describe("Aptos NFT SDK tests", () => {
CHAIN_ID_APTOS, CHAIN_ID_APTOS,
aptosAccount.address().toUint8Array() aptosAccount.address().toUint8Array()
); );
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// observe txs and get vaas // observe txs and get vaas
const ethTransferVaa1 = await getSignedVaaEthereum(ethTransferTx1); const ethTransferVaa1 = await getSignedVaaEthereum(ethTransferTx1);

View File

@ -1,11 +1,4 @@
import { import { beforeEach, describe, expect, jest, test } from "@jest/globals";
afterEach,
beforeEach,
describe,
expect,
jest,
test,
} from "@jest/globals";
import { getAssociatedTokenAddress } from "@solana/spl-token"; import { getAssociatedTokenAddress } from "@solana/spl-token";
import { import {
Connection, Connection,
@ -16,10 +9,10 @@ import {
import { BigNumberish, ethers } from "ethers"; import { BigNumberish, ethers } from "ethers";
import Web3 from "web3"; import Web3 from "web3";
import { import {
ChainId,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CHAIN_ID_SOLANA, CHAIN_ID_SOLANA,
CONTRACTS, CONTRACTS,
ChainId,
nft_bridge, nft_bridge,
} from "../.."; } from "../..";
import { postVaaSolanaWithRetry } from "../../solana"; import { postVaaSolanaWithRetry } from "../../solana";
@ -34,11 +27,9 @@ import {
} from "./utils/consts"; } from "./utils/consts";
import { getSignedVaaEthereum, getSignedVaaSolana } from "./utils/getSignedVaa"; import { getSignedVaaEthereum, getSignedVaaSolana } from "./utils/getSignedVaa";
jest.setTimeout(120000);
// ethereum setup // ethereum setup
const web3 = new Web3(ETH_NODE_URL); const web3 = new Web3(ETH_NODE_URL);
let provider: ethers.providers.WebSocketProvider; let provider: ethers.providers.JsonRpcProvider;
let signer: ethers.Wallet; let signer: ethers.Wallet;
// solana setup // solana setup
@ -47,14 +38,10 @@ const keypair = Keypair.fromSecretKey(SOLANA_PRIVATE_KEY);
const payerAddress = keypair.publicKey.toString(); const payerAddress = keypair.publicKey.toString();
beforeEach(() => { beforeEach(() => {
provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); // corresponds to accounts[1] signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); // corresponds to accounts[1]
}); });
afterEach(() => {
provider.destroy();
});
describe("Integration Tests", () => { describe("Integration Tests", () => {
test("Send Solana SPL to Ethereum and back", (done) => { test("Send Solana SPL to Ethereum and back", (done) => {
(async () => { (async () => {
@ -93,6 +80,7 @@ describe("Integration Tests", () => {
fromAddress.toString(), fromAddress.toString(),
CHAIN_ID_SOLANA CHAIN_ID_SOLANA
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
signedVAA = await getSignedVaaEthereum(transaction3); signedVAA = await getSignedVaaEthereum(transaction3);
const { name, symbol } = parseNftTransferVaa(signedVAA); const { name, symbol } = parseNftTransferVaa(signedVAA);

View File

@ -4,7 +4,9 @@ import { Connection, PublicKey } from "@solana/web3.js";
const ci = !!process.env.CI; const ci = !!process.env.CI;
// see devnet.md // see devnet.md
export const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545"; export const ETH_NODE_URL = ci
? "http://eth-devnet:8545"
: "http://localhost:8545";
export const ETH_PRIVATE_KEY = export const ETH_PRIVATE_KEY =
"0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // account 1 "0x6cbed15c793ce57650b9877cf6fa156fbef513c4e6134f022a85b1ffdd59b2a1"; // account 1
export const ETH_PRIVATE_KEY8 = export const ETH_PRIVATE_KEY8 =

View File

@ -1,34 +1,33 @@
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { describe, expect, test } from "@jest/globals"; import { describe, expect, test } from "@jest/globals";
import { ContractReceipt, ethers } from "ethers"; import { ContractReceipt, ethers } from "ethers";
import { import {
getNetwork,
isCI,
waitForRelay,
PRIVATE_KEY,
getGuardianRPC,
GUARDIAN_KEYS,
GUARDIAN_SET_INDEX,
GOVERNANCE_EMITTER_ADDRESS,
getArbitraryBytes32,
} from "./utils/utils";
import { getAddressInfo } from "../consts";
import { getDefaultProvider } from "../relayer/helpers";
import {
relayer,
ethers_contracts,
ethers_relayer_contracts,
tryNativeToUint8Array,
ChainId,
CHAINS, CHAINS,
CONTRACTS, CONTRACTS,
ChainId,
ChainName, ChainName,
Network, Network,
ethers_relayer_contracts,
relayer,
tryNativeToUint8Array,
} from "../../../"; } from "../../../";
import { GovernanceEmitter, MockGuardians } from "../../../src/mock"; import { GovernanceEmitter, MockGuardians } from "../../../src/mock";
import { Implementation__factory } from "../../ethers-contracts"; import { Implementation__factory } from "../../ethers-contracts";
import { getAddressInfo } from "../consts";
import { manualDelivery } from "../relayer"; import { manualDelivery } from "../relayer";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; import { getDefaultProvider } from "../relayer/helpers";
import { packEVMExecutionInfoV1 } from "../structs"; import { packEVMExecutionInfoV1 } from "../structs";
import {
GOVERNANCE_EMITTER_ADDRESS,
GUARDIAN_KEYS,
GUARDIAN_SET_INDEX,
PRIVATE_KEY,
getArbitraryBytes32,
getGuardianRPC,
getNetwork,
isCI,
waitForRelay,
} from "./utils/utils";
const network: Network = getNetwork(); const network: Network = getNetwork();
const ci: boolean = isCI(); const ci: boolean = isCI();
@ -42,7 +41,7 @@ const testIfNotDevnet = () => (network != "DEVNET" ? test : test.skip);
type TestChain = { type TestChain = {
chainId: ChainId; chainId: ChainId;
name: ChainName; name: ChainName;
provider: ethers.providers.Provider; provider: ethers.providers.StaticJsonRpcProvider;
wallet: ethers.Wallet; wallet: ethers.Wallet;
wormholeRelayerAddress: string; wormholeRelayerAddress: string;
mockIntegrationAddress: string; mockIntegrationAddress: string;
@ -160,7 +159,7 @@ const testSend = async (
notEnoughValue ? TOO_LOW_GAS_LIMIT : REASONABLE_GAS_LIMIT, notEnoughValue ? TOO_LOW_GAS_LIMIT : REASONABLE_GAS_LIMIT,
optionalParams optionalParams
); );
console.log(`Quoted gas delivery fee: ${value}`); !ci && console.log(`Quoted gas delivery fee: ${value}`);
const tx = await source.mockIntegration.sendMessage( const tx = await source.mockIntegration.sendMessage(
payload, payload,
sendToSourceChain ? source.chainId : target.chainId, sendToSourceChain ? source.chainId : target.chainId,
@ -168,9 +167,9 @@ const testSend = async (
0, 0,
{ value, gasLimit: REASONABLE_GAS_LIMIT } { value, gasLimit: REASONABLE_GAS_LIMIT }
); );
console.log(`Sent delivery request! Transaction hash ${tx.hash}`); !ci && console.log(`Sent delivery request! Transaction hash ${tx.hash}`);
await tx.wait(); await tx.wait();
console.log("Message confirmed!"); !ci && console.log("Message confirmed!");
return tx.wait(); return tx.wait();
}; };
@ -178,20 +177,20 @@ const testSend = async (
describe("Wormhole Relayer Tests", () => { describe("Wormhole Relayer Tests", () => {
test("Executes a Delivery Success", async () => { test("Executes a Delivery Success", async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const rx = await testSend(arbitraryPayload); const rx = await testSend(arbitraryPayload);
await waitForRelay(); await waitForRelay();
console.log("Checking if message was relayed"); !ci && console.log("Checking if message was relayed");
const message = await target.mockIntegration.getMessage(); const message = await target.mockIntegration.getMessage();
expect(message).toBe(arbitraryPayload); expect(message).toBe(arbitraryPayload);
}); });
test("Executes a Delivery Success With Additional VAAs", async () => { test("Executes a Delivery Success With Additional VAAs", async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const wormhole = Implementation__factory.connect( const wormhole = Implementation__factory.connect(
CONTRACTS[network][sourceChain].core || "", CONTRACTS[network][sourceChain].core || "",
@ -207,7 +206,7 @@ describe("Wormhole Relayer Tests", () => {
REASONABLE_GAS_LIMIT * 2, REASONABLE_GAS_LIMIT * 2,
optionalParams optionalParams
); );
console.log(`Quoted gas delivery fee: ${value}`); !ci && console.log(`Quoted gas delivery fee: ${value}`);
const tx = await source.mockIntegration.sendMessageWithAdditionalVaas( const tx = await source.mockIntegration.sendMessageWithAdditionalVaas(
[], [],
@ -224,13 +223,13 @@ describe("Wormhole Relayer Tests", () => {
{ value } { value }
); );
console.log(`Sent tx hash: ${tx.hash}`); !ci && console.log(`Sent tx hash: ${tx.hash}`);
const rx = await tx.wait(); const rx = await tx.wait();
await waitForRelay(); await waitForRelay();
console.log("Checking if message was relayed"); !ci && console.log("Checking if message was relayed");
const message = (await target.mockIntegration.getDeliveryData()) const message = (await target.mockIntegration.getDeliveryData())
.additionalVaas[0]; .additionalVaas[0];
const parsedMessage = await wormhole.parseVM(message); const parsedMessage = await wormhole.parseVM(message);
@ -241,7 +240,7 @@ describe("Wormhole Relayer Tests", () => {
"Executes a Delivery Success with manual delivery", "Executes a Delivery Success with manual delivery",
async () => { async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const deliverySeq = await Implementation__factory.connect( const deliverySeq = await Implementation__factory.connect(
CONTRACTS[network][sourceChain].core || "", CONTRACTS[network][sourceChain].core || "",
@ -286,7 +285,10 @@ describe("Wormhole Relayer Tests", () => {
} }
); );
console.log(`Price: ${priceInfo.quote} of ${priceInfo.targetChain} wei`); !ci &&
console.log(
`Price: ${priceInfo.quote} of ${priceInfo.targetChain} wei`
);
const deliveryRx = await manualDelivery( const deliveryRx = await manualDelivery(
sourceChain, sourceChain,
@ -310,9 +312,9 @@ describe("Wormhole Relayer Tests", () => {
}, },
target.wallet target.wallet
); );
console.log("Manual delivery tx hash", deliveryRx.txHash); !ci && console.log("Manual delivery tx hash", deliveryRx.txHash);
console.log("Checking if message was relayed"); !ci && console.log("Checking if message was relayed");
const message = await target.mockIntegration.getMessage(); const message = await target.mockIntegration.getMessage();
expect(message).toBe(arbitraryPayload); expect(message).toBe(arbitraryPayload);
} }
@ -330,14 +332,14 @@ describe("Wormhole Relayer Tests", () => {
test("Executes a delivery with a Cross Chain Refund", async () => { test("Executes a delivery with a Cross Chain Refund", async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const value = await relayer.getPrice( const value = await relayer.getPrice(
sourceChain, sourceChain,
targetChain, targetChain,
REASONABLE_GAS_LIMIT, REASONABLE_GAS_LIMIT,
optionalParams optionalParams
); );
console.log(`Quoted gas delivery fee: ${value}`); !ci && console.log(`Quoted gas delivery fee: ${value}`);
const startingBalance = await source.wallet.getBalance(); const startingBalance = await source.wallet.getBalance();
const tx = await relayer.sendToEvm( const tx = await relayer.sendToEvm(
@ -350,11 +352,13 @@ describe("Wormhole Relayer Tests", () => {
{ value, gasLimit: REASONABLE_GAS_LIMIT }, { value, gasLimit: REASONABLE_GAS_LIMIT },
optionalParams optionalParams
); );
console.log("Sent delivery request!"); !ci && console.log("Sent delivery request!");
await tx.wait(); await tx.wait();
console.log("Message confirmed!"); !ci && console.log("Message confirmed!");
const endingBalance = await source.wallet.getBalance(); const endingBalance = await source.wallet.getBalance();
await source.provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
await waitForRelay(); await waitForRelay();
const info = (await relayer.getWormholeRelayerInfo(sourceChain, tx.hash, { const info = (await relayer.getWormholeRelayerInfo(sourceChain, tx.hash, {
@ -362,30 +366,34 @@ describe("Wormhole Relayer Tests", () => {
...optionalParams, ...optionalParams,
})) as relayer.DeliveryInfo; })) as relayer.DeliveryInfo;
await target.provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
await waitForRelay(); await waitForRelay();
const newEndingBalance = await source.wallet.getBalance(); const newEndingBalance = await source.wallet.getBalance();
console.log(`Quoted gas delivery fee: ${value}`); !ci && console.log(`Quoted gas delivery fee: ${value}`);
console.log( !ci &&
`Cost (including gas) ${startingBalance.sub(endingBalance).toString()}` console.log(
); `Cost (including gas) ${startingBalance.sub(endingBalance).toString()}`
);
const refund = newEndingBalance.sub(endingBalance); const refund = newEndingBalance.sub(endingBalance);
console.log(`Refund: ${refund.toString()}`); !ci && console.log(`Refund: ${refund.toString()}`);
console.log( !ci &&
`As a percentage of original value: ${newEndingBalance console.log(
.sub(endingBalance) `As a percentage of original value: ${newEndingBalance
.mul(100) .sub(endingBalance)
.div(value) .mul(100)
.toString()}%` .div(value)
); .toString()}%`
console.log("Confirming refund is nonzero"); );
!ci && console.log("Confirming refund is nonzero");
expect(refund.gt(0)).toBe(true); expect(refund.gt(0)).toBe(true);
}); });
test("Executes a Receiver Failure", async () => { test("Executes a Receiver Failure", async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const rx = await testSend(arbitraryPayload, false, true); const rx = await testSend(arbitraryPayload, false, true);
@ -397,7 +405,7 @@ describe("Wormhole Relayer Tests", () => {
test("Executes a receiver failure and then redelivery through SDK", async () => { test("Executes a receiver failure and then redelivery through SDK", async () => {
const arbitraryPayload = getArbitraryBytes32(); const arbitraryPayload = getArbitraryBytes32();
console.log(`Sent message: ${arbitraryPayload}`); !ci && console.log(`Sent message: ${arbitraryPayload}`);
const rx = await testSend(arbitraryPayload, false, true); const rx = await testSend(arbitraryPayload, false, true);
@ -419,7 +427,7 @@ describe("Wormhole Relayer Tests", () => {
{ wormholeRelayerAddresses, ...optionalParams } { wormholeRelayerAddresses, ...optionalParams }
)) as relayer.DeliveryInfo; )) as relayer.DeliveryInfo;
console.log("Redelivering message"); !ci && console.log("Redelivering message");
const redeliveryReceipt = await relayer.resend( const redeliveryReceipt = await relayer.resend(
source.wallet, source.wallet,
sourceChain, sourceChain,
@ -444,13 +452,13 @@ describe("Wormhole Relayer Tests", () => {
{ wormholeRelayerAddress: source.wormholeRelayerAddress } { wormholeRelayerAddress: source.wormholeRelayerAddress }
); );
console.log("redelivery tx:", redeliveryReceipt.hash); !ci && console.log("redelivery tx:", redeliveryReceipt.hash);
await redeliveryReceipt.wait(); await redeliveryReceipt.wait();
await waitForRelay(); await waitForRelay();
console.log("Checking if message was relayed after redelivery"); !ci && console.log("Checking if message was relayed after redelivery");
const message2 = await target.mockIntegration.getMessage(); const message2 = await target.mockIntegration.getMessage();
expect(message2).toBe(arbitraryPayload); expect(message2).toBe(arbitraryPayload);
@ -464,9 +472,10 @@ describe("Wormhole Relayer Tests", () => {
const currentAddress = const currentAddress =
await source.wormholeRelayer.getRegisteredWormholeRelayerContract(chain); await source.wormholeRelayer.getRegisteredWormholeRelayerContract(chain);
console.log( !ci &&
`For Chain ${source.chainId}, registered chain ${chain} address: ${currentAddress}` console.log(
); `For Chain ${source.chainId}, registered chain ${chain} address: ${currentAddress}`
);
const expectedNewRegisteredAddress = const expectedNewRegisteredAddress =
"0x0000000000000000000000001234567890123456789012345678901234567892"; "0x0000000000000000000000001234567890123456789012345678901234567892";
@ -501,9 +510,10 @@ describe("Wormhole Relayer Tests", () => {
async () => { async () => {
const currentAddress = const currentAddress =
await source.wormholeRelayer.getDefaultDeliveryProvider(); await source.wormholeRelayer.getDefaultDeliveryProvider();
console.log( !ci &&
`For Chain ${source.chainId}, default relay provider: ${currentAddress}` console.log(
); `For Chain ${source.chainId}, default relay provider: ${currentAddress}`
);
const expectedNewDefaultDeliveryProvider = const expectedNewDefaultDeliveryProvider =
"0x1234567890123456789012345678901234567892"; "0x1234567890123456789012345678901234567892";
@ -567,9 +577,10 @@ describe("Wormhole Relayer Tests", () => {
IMPLEMENTATION_STORAGE_SLOT IMPLEMENTATION_STORAGE_SLOT
); );
console.log( !ci &&
`Current Implementation address: ${await getImplementationAddress()}` console.log(
); `Current Implementation address: ${await getImplementationAddress()}`
);
const wormholeAddress = CONTRACTS[network][sourceChain].core || ""; const wormholeAddress = CONTRACTS[network][sourceChain].core || "";
@ -579,10 +590,11 @@ describe("Wormhole Relayer Tests", () => {
.then((x) => x.deployed()) .then((x) => x.deployed())
).address; ).address;
console.log(`Deployed!`); !ci && console.log(`Deployed!`);
console.log( !ci &&
`New core relayer implementation: ${newWormholeRelayerImplementationAddress}` console.log(
); `New core relayer implementation: ${newWormholeRelayerImplementationAddress}`
);
const timestamp = (await source.wallet.provider.getBlock("latest")) const timestamp = (await source.wallet.provider.getBlock("latest"))
.timestamp; .timestamp;
@ -598,6 +610,7 @@ describe("Wormhole Relayer Tests", () => {
); );
let tx = await source.wormholeRelayer.submitContractUpgrade(firstSignedVaa); let tx = await source.wormholeRelayer.submitContractUpgrade(firstSignedVaa);
await tx.wait();
expect( expect(
ethers.utils.getAddress((await getImplementationAddress()).substring(26)) ethers.utils.getAddress((await getImplementationAddress()).substring(26))
@ -613,7 +626,7 @@ describe("Wormhole Relayer Tests", () => {
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, { const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
environment, environment,
}); });
console.log(info.stringified); !ci && console.log(info.stringified);
}); });
testIfNotDevnet()("Tests custom manual delivery", async () => { testIfNotDevnet()("Tests custom manual delivery", async () => {
@ -626,7 +639,7 @@ describe("Wormhole Relayer Tests", () => {
const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, { const info = await relayer.getWormholeRelayerInfo(mySourceChain, txHash, {
environment, environment,
}); });
console.log(info.stringified); !ci && console.log(info.stringified);
const priceInfo = await manualDelivery( const priceInfo = await manualDelivery(
mySourceChain, mySourceChain,
@ -634,7 +647,7 @@ describe("Wormhole Relayer Tests", () => {
{ environment }, { environment },
true true
); );
console.log(`Price info: ${JSON.stringify(priceInfo)}`); !ci && console.log(`Price info: ${JSON.stringify(priceInfo)}`);
const signer = new ethers.Wallet( const signer = new ethers.Wallet(
PRIVATE_KEY, PRIVATE_KEY,
@ -643,17 +656,19 @@ describe("Wormhole Relayer Tests", () => {
: getDefaultProvider(environment, priceInfo.targetChain) : getDefaultProvider(environment, priceInfo.targetChain)
); );
console.log( !ci &&
`Price: ${ethers.utils.formatEther(priceInfo.quote)} of ${ console.log(
priceInfo.targetChain `Price: ${ethers.utils.formatEther(priceInfo.quote)} of ${
} currency` priceInfo.targetChain
); } currency`
);
const balance = await signer.getBalance(); const balance = await signer.getBalance();
console.log( !ci &&
`My balance: ${ethers.utils.formatEther(balance)} of ${ console.log(
priceInfo.targetChain `My balance: ${ethers.utils.formatEther(balance)} of ${
} currency` priceInfo.targetChain
); } currency`
);
const deliveryRx = await manualDelivery( const deliveryRx = await manualDelivery(
mySourceChain, mySourceChain,
@ -663,7 +678,7 @@ describe("Wormhole Relayer Tests", () => {
undefined, undefined,
signer signer
); );
console.log("Manual delivery tx hash", deliveryRx.txHash); !ci && console.log("Manual delivery tx hash", deliveryRx.txHash);
}); });
}); });

View File

@ -3,20 +3,21 @@ import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"
import { describe, expect, jest, test } from "@jest/globals"; import { describe, expect, jest, test } from "@jest/globals";
import algosdk, { import algosdk, {
Account, Account,
OnApplicationComplete,
decodeAddress, decodeAddress,
getApplicationAddress, getApplicationAddress,
makeApplicationCallTxnFromObject, makeApplicationCallTxnFromObject,
OnApplicationComplete,
waitForConfirmation, waitForConfirmation,
} from "algosdk"; } from "algosdk";
import { BigNumber, ethers, utils } from "ethers"; import { BigNumber, ethers, utils } from "ethers";
import { import {
approveEth,
attestFromAlgorand,
attestFromEth,
CHAIN_ID_ALGORAND, CHAIN_ID_ALGORAND,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CONTRACTS, CONTRACTS,
WormholeWrappedInfo,
approveEth,
attestFromAlgorand,
attestFromEth,
createWrappedOnAlgorand, createWrappedOnAlgorand,
createWrappedOnEth, createWrappedOnEth,
getEmitterAddressAlgorand, getEmitterAddressAlgorand,
@ -36,9 +37,7 @@ import {
transferFromEth, transferFromEth,
uint8ArrayToHex, uint8ArrayToHex,
updateWrappedOnEth, updateWrappedOnEth,
WormholeWrappedInfo,
} from "../.."; } from "../..";
import { TokenImplementation__factory } from "../../ethers-contracts";
import { _parseVAAAlgorand } from "../../algorand"; import { _parseVAAAlgorand } from "../../algorand";
import { import {
createAsset, createAsset,
@ -49,6 +48,7 @@ import {
getTempAccounts, getTempAccounts,
signSendAndConfirmAlgorand, signSendAndConfirmAlgorand,
} from "../../algorand/__tests__/testHelpers"; } from "../../algorand/__tests__/testHelpers";
import { TokenImplementation__factory } from "../../ethers-contracts";
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry"; import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
import { safeBigIntToNumber } from "../../utils/bigint"; import { safeBigIntToNumber } from "../../utils/bigint";
import { import {
@ -61,8 +61,6 @@ import {
const CORE_ID = BigInt(1004); const CORE_ID = BigInt(1004);
const TOKEN_BRIDGE_ID = BigInt(1006); const TOKEN_BRIDGE_ID = BigInt(1006);
jest.setTimeout(120000);
describe("Algorand tests", () => { describe("Algorand tests", () => {
test("Algorand transfer native ALGO to Eth and back again", (done) => { test("Algorand transfer native ALGO to Eth and back again", (done) => {
(async () => { (async () => {
@ -115,7 +113,7 @@ describe("Algorand tests", () => {
{ transport: NodeHttpTransport() } { transport: NodeHttpTransport() }
); );
const pvaa = _parseVAAAlgorand(vaaBytes); const pvaa = _parseVAAAlgorand(vaaBytes);
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
@ -262,6 +260,7 @@ describe("Algorand tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
@ -297,8 +296,6 @@ describe("Algorand tests", () => {
if (!secondFinalAlgoBal) { if (!secondFinalAlgoBal) {
throw new Error("secondFinalAlgoBal is undefined"); throw new Error("secondFinalAlgoBal is undefined");
} }
provider.destroy();
} catch (e) { } catch (e) {
console.error("Algorand ALGO transfer error:", e); console.error("Algorand ALGO transfer error:", e);
done("Algorand ALGO transfer error"); done("Algorand ALGO transfer error");
@ -358,7 +355,7 @@ describe("Algorand tests", () => {
attestSn, attestSn,
{ transport: NodeHttpTransport() } { transport: NodeHttpTransport() }
); );
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
@ -501,6 +498,7 @@ describe("Algorand tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
@ -537,7 +535,6 @@ describe("Algorand tests", () => {
throw new Error("secondFinalAlgoBal is undefined"); throw new Error("secondFinalAlgoBal is undefined");
} }
expect(secondFinalAlgoBal - finalAlgoBal).toBe(parseInt(Amount) * 100); expect(secondFinalAlgoBal - finalAlgoBal).toBe(parseInt(Amount) * 100);
provider.destroy();
} catch (e) { } catch (e) {
console.error("Algorand chuckNorium transfer error:", e); console.error("Algorand chuckNorium transfer error:", e);
done("Algorand chuckNorium transfer error"); done("Algorand chuckNorium transfer error");
@ -559,7 +556,7 @@ describe("Algorand tests", () => {
const algoWallet: Account = tempAccts[0]; const algoWallet: Account = tempAccts[0];
const Amount = "10"; const Amount = "10";
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
// attest the test token // attest the test token
const attestReceipt = await attestFromEth( const attestReceipt = await attestFromEth(
@ -575,6 +572,7 @@ describe("Algorand tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: attestSignedVaa } = await getSignedVAAWithRetry( const { vaaBytes: attestSignedVaa } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -651,6 +649,7 @@ describe("Algorand tests", () => {
receipt, receipt,
CONTRACTS.DEVNET.ethereum.core CONTRACTS.DEVNET.ethereum.core
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: transferSignedVaa } = await getSignedVAAWithRetry( const { vaaBytes: transferSignedVaa } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -776,7 +775,6 @@ describe("Algorand tests", () => {
); );
expect(info.chainId).toBe(CHAIN_ID_ETH); expect(info.chainId).toBe(CHAIN_ID_ETH);
expect(info.isWrapped).toBe(true); expect(info.isWrapped).toBe(true);
provider.destroy();
} catch (e) { } catch (e) {
console.error("Eth <=> Algorand error:", e); console.error("Eth <=> Algorand error:", e);
done("Eth <=> Algorand error"); done("Eth <=> Algorand error");
@ -809,7 +807,7 @@ describe("Algorand tests", () => {
// ETH setup to transfer LUNA to Algorand // ETH setup to transfer LUNA to Algorand
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY7, provider);
// attest the test token // attest the test token
const receipt = await attestFromEth( const receipt = await attestFromEth(
@ -825,6 +823,7 @@ describe("Algorand tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -880,6 +879,7 @@ describe("Algorand tests", () => {
const ethEmitterAddress = getEmitterAddressEth( const ethEmitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: firstHalfVaa } = await getSignedVAAWithRetry( const { vaaBytes: firstHalfVaa } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -925,6 +925,7 @@ describe("Algorand tests", () => {
secondHalfReceipt, secondHalfReceipt,
CONTRACTS.DEVNET.ethereum.core CONTRACTS.DEVNET.ethereum.core
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: secondHalfVaa } = await getSignedVAAWithRetry( const { vaaBytes: secondHalfVaa } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -952,7 +953,6 @@ describe("Algorand tests", () => {
secondHalfVaa secondHalfVaa
) )
).toBe(true); ).toBe(true);
provider.destroy();
} catch (e) { } catch (e) {
console.error("new test error:", e); console.error("new test error:", e);
done("new test error"); done("new test error");

View File

@ -10,13 +10,13 @@ import {
import { ethers } from "ethers"; import { ethers } from "ethers";
import { parseUnits } from "ethers/lib/utils"; import { parseUnits } from "ethers/lib/utils";
import { import {
approveEth,
APTOS_TOKEN_BRIDGE_EMITTER_ADDRESS, APTOS_TOKEN_BRIDGE_EMITTER_ADDRESS,
attestFromAptos,
attestFromEth,
CHAIN_ID_APTOS, CHAIN_ID_APTOS,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CONTRACTS, CONTRACTS,
approveEth,
attestFromAptos,
attestFromEth,
createWrappedOnAptos, createWrappedOnAptos,
createWrappedOnEth, createWrappedOnEth,
createWrappedTypeOnAptos, createWrappedTypeOnAptos,
@ -56,8 +56,6 @@ import {
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
} from "./utils/consts"; } from "./utils/consts";
jest.setTimeout(120000);
describe("Aptos SDK tests", () => { describe("Aptos SDK tests", () => {
test("Transfer native token from Aptos to Ethereum", async () => { test("Transfer native token from Aptos to Ethereum", async () => {
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge; const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
@ -99,7 +97,7 @@ describe("Aptos SDK tests", () => {
expect(attestVAA).toBeTruthy(); expect(attestVAA).toBeTruthy();
// setup ethereum // setup ethereum
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider); const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
const recipientAddress = await recipient.getAddress(); const recipientAddress = await recipient.getAddress();
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge; const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
@ -196,13 +194,10 @@ describe("Aptos SDK tests", () => {
expect( expect(
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber() balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
).toEqual(10_000_000); ).toEqual(10_000_000);
// clean up
provider.destroy();
}); });
test("Transfer native ERC-20 from Ethereum to Aptos", async () => { test("Transfer native ERC-20 from Ethereum to Aptos", async () => {
// setup ethereum // setup ethereum
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const sender = new ethers.Wallet(ETH_PRIVATE_KEY6, provider); const sender = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge; const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
const ethCoreBridge = CONTRACTS.DEVNET.ethereum.core; const ethCoreBridge = CONTRACTS.DEVNET.ethereum.core;
@ -218,6 +213,7 @@ describe("Aptos SDK tests", () => {
let sequence = parseSequenceFromLogEth(attestReceipt, ethCoreBridge); let sequence = parseSequenceFromLogEth(attestReceipt, ethCoreBridge);
expect(sequence).toBeTruthy(); expect(sequence).toBeTruthy();
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const { vaaBytes: attestVAA } = await getSignedVAAWithRetry( const { vaaBytes: attestVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
CHAIN_ID_ETH, CHAIN_ID_ETH,
@ -322,6 +318,7 @@ describe("Aptos SDK tests", () => {
sequence = parseSequenceFromLogEth(transferReceipt, ethCoreBridge); sequence = parseSequenceFromLogEth(transferReceipt, ethCoreBridge);
expect(sequence).toBeTruthy(); expect(sequence).toBeTruthy();
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const { vaaBytes: transferVAA } = await getSignedVAAWithRetry( const { vaaBytes: transferVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
CHAIN_ID_ETH, CHAIN_ID_ETH,
@ -367,9 +364,6 @@ describe("Aptos SDK tests", () => {
expect( expect(
balanceBeforeTransferEth.sub(balanceAfterTransferEth).toString() balanceBeforeTransferEth.sub(balanceAfterTransferEth).toString()
).toEqual(amount.toString()); ).toEqual(amount.toString());
// clean up
provider.destroy();
}); });
test("Transfer native token with payload from Aptos to Ethereum", async () => { test("Transfer native token with payload from Aptos to Ethereum", async () => {
const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge; const APTOS_TOKEN_BRIDGE = CONTRACTS.DEVNET.aptos.token_bridge;
@ -411,7 +405,7 @@ describe("Aptos SDK tests", () => {
expect(attestVAA).toBeTruthy(); expect(attestVAA).toBeTruthy();
// setup ethereum // setup ethereum
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider); const recipient = new ethers.Wallet(ETH_PRIVATE_KEY6, provider);
const recipientAddress = await recipient.getAddress(); const recipientAddress = await recipient.getAddress();
const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge; const ethTokenBridge = CONTRACTS.DEVNET.ethereum.token_bridge;
@ -513,9 +507,6 @@ describe("Aptos SDK tests", () => {
expect( expect(
balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber() balanceAfterTransferEth.sub(balanceBeforeTransferEth).toNumber()
).toEqual(10_000_000); ).toEqual(10_000_000);
// clean up
provider.destroy();
}); });
}); });

View File

@ -2,10 +2,9 @@ import { formatUnits, parseUnits } from "@ethersproject/units";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { describe, expect, jest, test } from "@jest/globals"; import { describe, expect, jest, test } from "@jest/globals";
import { import {
ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID,
createAssociatedTokenAccountInstruction, createAssociatedTokenAccountInstruction,
getAssociatedTokenAddress, getAssociatedTokenAddress,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token"; } from "@solana/spl-token";
import { import {
Connection, Connection,
@ -16,11 +15,11 @@ import {
} from "@solana/web3.js"; } from "@solana/web3.js";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { import {
approveEth,
attestFromEth,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CHAIN_ID_SOLANA, CHAIN_ID_SOLANA,
CONTRACTS, CONTRACTS,
approveEth,
attestFromEth,
createWrappedOnSolana, createWrappedOnSolana,
getEmitterAddressEth, getEmitterAddressEth,
getForeignAssetSolana, getForeignAssetSolana,
@ -43,8 +42,6 @@ import {
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
} from "./utils/consts"; } from "./utils/consts";
jest.setTimeout(120000);
async function transferFromEthToSolana(): Promise<string> { async function transferFromEthToSolana(): Promise<string> {
// create a keypair for Solana // create a keypair for Solana
const connection = new Connection(SOLANA_HOST, "confirmed"); const connection = new Connection(SOLANA_HOST, "confirmed");
@ -82,7 +79,7 @@ async function transferFromEthToSolana(): Promise<string> {
await connection.confirmTransaction(txid); await connection.confirmTransaction(txid);
} }
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
const amount = parseUnits("1", 18); const amount = parseUnits("1", 18);
// approve the bridge to spend tokens // approve the bridge to spend tokens
@ -106,7 +103,6 @@ async function transferFromEthToSolana(): Promise<string> {
receipt, receipt,
CONTRACTS.DEVNET.ethereum.core CONTRACTS.DEVNET.ethereum.core
); );
provider.destroy();
return sequence; return sequence;
} }
@ -115,7 +111,7 @@ describe("Ethereum to Solana and Back", () => {
(async () => { (async () => {
try { try {
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
// attest the test token // attest the test token
const receipt = await attestFromEth( const receipt = await attestFromEth(
@ -131,6 +127,7 @@ describe("Ethereum to Solana and Back", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -174,7 +171,6 @@ describe("Ethereum to Solana and Back", () => {
} catch (e) { } catch (e) {
// this could fail because the token is already attested (in an unclean env) // this could fail because the token is already attested (in an unclean env)
} }
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -238,7 +234,7 @@ describe("Ethereum to Solana and Back", () => {
await connection.confirmTransaction(txid); await connection.confirmTransaction(txid);
} }
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY, provider);
const amount = parseUnits("1", DECIMALS); const amount = parseUnits("1", DECIMALS);
@ -294,6 +290,7 @@ describe("Ethereum to Solana and Back", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -373,7 +370,6 @@ describe("Ethereum to Solana and Back", () => {
} }
} }
expect(finalSolanaBalance - initialSolanaBalance === 1).toBe(true); expect(finalSolanaBalance - initialSolanaBalance === 1).toBe(true);
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -393,6 +389,8 @@ describe("Ethereum to Solana and Back", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -466,6 +464,8 @@ describe("Ethereum to Solana and Back", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,

View File

@ -1,6 +1,13 @@
import { beforeAll, afterAll, expect, jest, test } from "@jest/globals"; import { beforeAll, expect, jest, test } from "@jest/globals";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { parseUnits } from "ethers/lib/utils"; import { parseUnits } from "ethers/lib/utils";
import { Account, KeyPair, Near, connect, keyStores } from "near-api-js";
import {
FinalExecutionOutcome,
Provider,
getTransactionLastResult,
} from "near-api-js/lib/providers";
import { parseNearAmount } from "near-api-js/lib/utils/format";
import { import {
createWrappedOnEth, createWrappedOnEth,
createWrappedOnNear, createWrappedOnNear,
@ -28,15 +35,6 @@ import {
TEST_ERC20, TEST_ERC20,
} from "./utils/consts"; } from "./utils/consts";
import { getSignedVAABySequence } from "./utils/helpers"; import { getSignedVAABySequence } from "./utils/helpers";
import { Account, connect, KeyPair, keyStores, Near } from "near-api-js";
import {
FinalExecutionOutcome,
getTransactionLastResult,
Provider,
} from "near-api-js/lib/providers";
import { parseNearAmount } from "near-api-js/lib/utils/format";
jest.setTimeout(120000);
let near: Near; let near: Near;
let nearProvider: Provider; let nearProvider: Provider;
@ -46,7 +44,7 @@ const accountId = "devnet.test.near";
const PRIVATE_KEY = const PRIVATE_KEY =
"ed25519:nCW2EsTn91b7ettRqQX6ti8ZBNwo7tbMsenBu9nmSVG9aDhNB7hgw7S9w5M9CZu1bF23FbvhKZPfDmh2Gbs45Fs"; "ed25519:nCW2EsTn91b7ettRqQX6ti8ZBNwo7tbMsenBu9nmSVG9aDhNB7hgw7S9w5M9CZu1bF23FbvhKZPfDmh2Gbs45Fs";
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY5, ethProvider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY5, ethProvider);
const ethEmitterAddress = getEmitterAddressEth( const ethEmitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
@ -72,10 +70,6 @@ beforeAll(async () => {
ethWalletAddress = await signer.getAddress(); ethWalletAddress = await signer.getAddress();
}); });
afterAll(async () => {
ethProvider.destroy();
});
const nearParseLogAndGetSignedVaa = async (outcome: FinalExecutionOutcome) => { const nearParseLogAndGetSignedVaa = async (outcome: FinalExecutionOutcome) => {
const sequence = parseSequenceFromLogNear(outcome); const sequence = parseSequenceFromLogNear(outcome);
if (sequence === null) { if (sequence === null) {
@ -155,6 +149,7 @@ test("Attest and transfer token from Ethereum to Near", async () => {
signer, signer,
TEST_ERC20 TEST_ERC20
); );
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt); const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
const createWrappedMsgs = await createWrappedOnNear( const createWrappedMsgs = await createWrappedOnNear(
nearProvider, nearProvider,
@ -193,6 +188,7 @@ test("Attest and transfer token from Ethereum to Near", async () => {
"near", "near",
hexToUint8Array(accountHash) hexToUint8Array(accountHash)
); );
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt); const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
const redeemMsgs = await redeemOnNear( const redeemMsgs = await redeemOnNear(
nearProvider, nearProvider,

View File

@ -2,10 +2,9 @@ import { formatUnits, parseUnits } from "@ethersproject/units";
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { describe, expect, jest, test } from "@jest/globals"; import { describe, expect, jest, test } from "@jest/globals";
import { import {
ASSOCIATED_TOKEN_PROGRAM_ID,
getAssociatedTokenAddress,
NATIVE_MINT, NATIVE_MINT,
TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID,
getAssociatedTokenAddress,
} from "@solana/spl-token"; } from "@solana/spl-token";
import { import {
Connection, Connection,
@ -15,10 +14,11 @@ import {
} from "@solana/web3.js"; } from "@solana/web3.js";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { import {
attestFromSolana,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CHAIN_ID_SOLANA, CHAIN_ID_SOLANA,
CONTRACTS, CONTRACTS,
WSOL_ADDRESS,
attestFromSolana,
createWrappedOnEth, createWrappedOnEth,
getEmitterAddressSolana, getEmitterAddressSolana,
getForeignAssetEth, getForeignAssetEth,
@ -30,7 +30,6 @@ import {
transferNativeSol, transferNativeSol,
tryNativeToHexString, tryNativeToHexString,
tryNativeToUint8Array, tryNativeToUint8Array,
WSOL_ADDRESS,
} from "../.."; } from "../..";
import { TokenImplementation__factory } from "../../ethers-contracts"; import { TokenImplementation__factory } from "../../ethers-contracts";
import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry"; import getSignedVAAWithRetry from "../../rpc/getSignedVAAWithRetry";
@ -43,8 +42,6 @@ import {
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
} from "./utils/consts"; } from "./utils/consts";
jest.setTimeout(120000);
describe("Solana to Ethereum", () => { describe("Solana to Ethereum", () => {
test("Attest Solana SPL to Ethereum", (done) => { test("Attest Solana SPL to Ethereum", (done) => {
(async () => { (async () => {
@ -89,7 +86,7 @@ describe("Solana to Ethereum", () => {
} }
); );
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
try { try {
await createWrappedOnEth( await createWrappedOnEth(
@ -100,7 +97,6 @@ describe("Solana to Ethereum", () => {
} catch (e) { } catch (e) {
// this could fail because the token is already attested (in an unclean env) // this could fail because the token is already attested (in an unclean env)
} }
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -111,7 +107,7 @@ describe("Solana to Ethereum", () => {
})(); })();
}); });
test("Solana SPL is attested on Ethereum", async () => { test("Solana SPL is attested on Ethereum", async () => {
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const address = getForeignAssetEth( const address = getForeignAssetEth(
CONTRACTS.DEVNET.ethereum.token_bridge, CONTRACTS.DEVNET.ethereum.token_bridge,
provider, provider,
@ -120,13 +116,12 @@ describe("Solana to Ethereum", () => {
); );
expect(address).toBeTruthy(); expect(address).toBeTruthy();
expect(address).not.toBe(ethers.constants.AddressZero); expect(address).not.toBe(ethers.constants.AddressZero);
provider.destroy();
}); });
test("Send Solana SPL to Ethereum", (done) => { test("Send Solana SPL to Ethereum", (done) => {
(async () => { (async () => {
try { try {
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
const targetAddress = await signer.getAddress(); const targetAddress = await signer.getAddress();
// create a keypair for Solana // create a keypair for Solana
@ -267,7 +262,6 @@ describe("Solana to Ethereum", () => {
parseInt(initialBalOnEthFormatted) === parseInt(initialBalOnEthFormatted) ===
1 1
).toBe(true); ).toBe(true);
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -318,7 +312,7 @@ describe("Solana to Ethereum", () => {
} }
); );
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
try { try {
await createWrappedOnEth( await createWrappedOnEth(
@ -329,7 +323,6 @@ describe("Solana to Ethereum", () => {
} catch (e) { } catch (e) {
// this could fail because the token is already attested (in an unclean env) // this could fail because the token is already attested (in an unclean env)
} }
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -343,7 +336,7 @@ describe("Solana to Ethereum", () => {
(async () => { (async () => {
try { try {
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY3, provider);
const targetAddress = await signer.getAddress(); const targetAddress = await signer.getAddress();
// create a keypair for Solana // create a keypair for Solana
@ -443,7 +436,6 @@ describe("Solana to Ethereum", () => {
parseInt(initialBalOnEthFormatted) === parseInt(initialBalOnEthFormatted) ===
1 1
).toBe(true); ).toBe(true);
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);

View File

@ -1,12 +1,5 @@
import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport"; import { NodeHttpTransport } from "@improbable-eng/grpc-web-node-http-transport";
import { import { beforeAll, describe, expect, jest, test } from "@jest/globals";
afterAll,
beforeAll,
describe,
expect,
jest,
test,
} from "@jest/globals";
import { import {
Connection, Connection,
Ed25519Keypair, Ed25519Keypair,
@ -35,9 +28,7 @@ import {
getSignedVAAWithRetry, getSignedVAAWithRetry,
parseAttestMetaVaa, parseAttestMetaVaa,
parseSequenceFromLogEth, parseSequenceFromLogEth,
parseTokenTransferPayload,
parseTokenTransferVaa, parseTokenTransferVaa,
parseVaa,
redeemOnEth, redeemOnEth,
redeemOnSui, redeemOnSui,
transferFromEth, transferFromEth,
@ -52,14 +43,12 @@ import {
getInnerType, getInnerType,
getPackageId, getPackageId,
getWrappedCoinType, getWrappedCoinType,
newEmitterCap,
} from "../../sui"; } from "../../sui";
import { import {
CHAIN_ID_ETH, CHAIN_ID_ETH,
CHAIN_ID_SUI, CHAIN_ID_SUI,
CONTRACTS, CONTRACTS,
hexToUint8Array, hexToUint8Array,
parseTransferPayload,
tryNativeToHexString, tryNativeToHexString,
tryNativeToUint8Array, tryNativeToUint8Array,
} from "../../utils"; } from "../../utils";
@ -78,8 +67,6 @@ import {
mintAndTransferCoinSui, mintAndTransferCoinSui,
} from "./utils/helpers"; } from "./utils/helpers";
jest.setTimeout(120000);
// Sui constants // Sui constants
const SUI_CORE_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.core; const SUI_CORE_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.core;
const SUI_TOKEN_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.token_bridge; const SUI_TOKEN_BRIDGE_STATE_OBJECT_ID = CONTRACTS.DEVNET.sui.token_bridge;
@ -101,7 +88,7 @@ const suiSigner: RawSigner = new RawSigner(suiKeypair, suiProvider);
const ETH_CORE_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.core; const ETH_CORE_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.core;
const ETH_TOKEN_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.token_bridge; const ETH_TOKEN_BRIDGE_ADDRESS = CONTRACTS.DEVNET.ethereum.token_bridge;
const ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY10, ethProvider); const ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY10, ethProvider);
let suiCoreBridgePackageId: string; let suiCoreBridgePackageId: string;
@ -118,10 +105,6 @@ beforeAll(async () => {
); );
}); });
afterAll(async () => {
await ethProvider.destroy();
});
// Modify the VAA to only have 1 guardian signature // Modify the VAA to only have 1 guardian signature
// TODO: remove this when we can deploy the devnet core contract // TODO: remove this when we can deploy the devnet core contract
// deterministically with multiple guardians in the initial guardian set // deterministically with multiple guardians in the initial guardian set
@ -165,6 +148,7 @@ describe("Sui SDK tests", () => {
ETH_CORE_BRIDGE_ADDRESS ETH_CORE_BRIDGE_ADDRESS
); );
expect(attestSequence).toBeTruthy(); expect(attestSequence).toBeTruthy();
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
let { vaaBytes: attestVAA }: { vaaBytes: Uint8Array } = let { vaaBytes: attestVAA }: { vaaBytes: Uint8Array } =
await getSignedVAAWithRetry( await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -176,7 +160,6 @@ describe("Sui SDK tests", () => {
} }
); );
const slicedAttestVAA = sliceVAASignatures(attestVAA); const slicedAttestVAA = sliceVAASignatures(attestVAA);
console.log(Buffer.from(slicedAttestVAA).toString("hex"));
expect(slicedAttestVAA).toBeTruthy(); expect(slicedAttestVAA).toBeTruthy();
// Start create wrapped on Sui // Start create wrapped on Sui
@ -331,6 +314,7 @@ describe("Sui SDK tests", () => {
transferReceipt, transferReceipt,
ETH_CORE_BRIDGE_ADDRESS ETH_CORE_BRIDGE_ADDRESS
); );
await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
let { vaaBytes: transferFromEthVAA } = await getSignedVAAWithRetry( let { vaaBytes: transferFromEthVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
CHAIN_ID_ETH, CHAIN_ID_ETH,
@ -381,7 +365,6 @@ describe("Sui SDK tests", () => {
coinType: coinType, coinType: coinType,
}) })
).data; ).data;
console.log({ coins, coinType });
const suiTransferTxPayload = await transferFromSui( const suiTransferTxPayload = await transferFromSui(
suiProvider, suiProvider,
SUI_CORE_BRIDGE_STATE_OBJECT_ID, SUI_CORE_BRIDGE_STATE_OBJECT_ID,
@ -495,7 +478,6 @@ describe("Sui SDK tests", () => {
transport: NodeHttpTransport(), transport: NodeHttpTransport(),
} }
); );
console.log(parseAttestMetaVaa(attestVAA));
expect(attestVAA).toBeTruthy(); expect(attestVAA).toBeTruthy();
// // Create wrapped on Ethereum // // Create wrapped on Ethereum

View File

@ -10,12 +10,12 @@ import {
} from "@terra-money/terra.js"; } from "@terra-money/terra.js";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { import {
approveEth,
attestFromEth,
attestFromTerra,
CHAIN_ID_ETH, CHAIN_ID_ETH,
CHAIN_ID_TERRA, CHAIN_ID_TERRA,
CONTRACTS, CONTRACTS,
approveEth,
attestFromEth,
attestFromTerra,
createWrappedOnEth, createWrappedOnEth,
createWrappedOnTerra, createWrappedOnTerra,
getEmitterAddressEth, getEmitterAddressEth,
@ -53,8 +53,6 @@ import {
waitForTerraExecution, waitForTerraExecution,
} from "./utils/helpers"; } from "./utils/helpers";
jest.setTimeout(120000);
function sleep(ms: number) { function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }
@ -106,7 +104,7 @@ describe("Terra Classic Integration Tests", () => {
}); });
await broadcastAndWait(lcd, tx); await broadcastAndWait(lcd, tx);
} }
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
// attempt to transfer more than we've deposited // attempt to transfer more than we've deposited
const transfer = new MsgExecuteContract( const transfer = new MsgExecuteContract(
@ -186,7 +184,6 @@ describe("Terra Classic Integration Tests", () => {
fee: feeEstimate, fee: feeEstimate,
}); });
await broadcastAndWait(lcd, tx); await broadcastAndWait(lcd, tx);
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -202,7 +199,7 @@ describe("Terra Classic Integration Tests", () => {
(async () => { (async () => {
try { try {
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
// attest the test token // attest the test token
const receipt = await attestFromEth( const receipt = await attestFromEth(
@ -218,6 +215,7 @@ describe("Terra Classic Integration Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -265,7 +263,6 @@ describe("Terra Classic Integration Tests", () => {
} catch (e) { } catch (e) {
// this could fail because the token is already attested (in an unclean env) // this could fail because the token is already attested (in an unclean env)
} }
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -293,7 +290,7 @@ describe("Terra Classic Integration Tests", () => {
(async () => { (async () => {
try { try {
// create a signer for Eth // create a signer for Eth
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
@ -381,6 +378,7 @@ describe("Terra Classic Integration Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -451,7 +449,6 @@ describe("Terra Classic Integration Tests", () => {
tokenDefinition.decimals tokenDefinition.decimals
); );
// let finalCW20BalOnTerra: number = parseInt(balAmount); // let finalCW20BalOnTerra: number = parseInt(balAmount);
provider.destroy();
done(); done();
} catch (e) { } catch (e) {
console.error(e); console.error(e);
@ -516,7 +513,7 @@ describe("Terra Classic Integration Tests", () => {
sequence, sequence,
emitterAddress emitterAddress
); );
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
@ -538,7 +535,6 @@ describe("Terra Classic Integration Tests", () => {
); );
success = true; success = true;
} }
provider.destroy();
} catch (e) { } catch (e) {
console.error("Attestation failure: ", e); console.error("Attestation failure: ", e);
} }
@ -567,7 +563,7 @@ describe("Terra Classic Integration Tests", () => {
// const initialFeeBalance: number = await queryBalanceOnTerra(FeeAsset); // const initialFeeBalance: number = await queryBalanceOnTerra(FeeAsset);
// Get initial balance of wrapped luna on Eth // Get initial balance of wrapped luna on Eth
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
@ -678,7 +674,6 @@ describe("Terra Classic Integration Tests", () => {
expect(initialLunaBalOnEthInt + 1e6 === lunaBalOnEthAfterInt).toBe( expect(initialLunaBalOnEthInt + 1e6 === lunaBalOnEthAfterInt).toBe(
true true
); );
provider.destroy();
} catch (e) { } catch (e) {
console.error("Terra to Ethereum failure: ", e); console.error("Terra to Ethereum failure: ", e);
done("Terra to Ethereum Failure"); done("Terra to Ethereum Failure");
@ -701,7 +696,7 @@ describe("Terra Classic Integration Tests", () => {
}); });
const Asset: string = "uluna"; const Asset: string = "uluna";
const initialTerraBalance: number = await queryBalanceOnTerra(Asset); const initialTerraBalance: number = await queryBalanceOnTerra(Asset);
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
@ -755,7 +750,7 @@ describe("Terra Classic Integration Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -813,7 +808,6 @@ describe("Terra Classic Integration Tests", () => {
true true
); );
// const uusdBal = await queryBalanceOnTerra("uusd"); // const uusdBal = await queryBalanceOnTerra("uusd");
provider.destroy();
} catch (e) { } catch (e) {
console.error("Transfer back failure: ", e); console.error("Transfer back failure: ", e);
done("Transfer back Failure"); done("Transfer back Failure");
@ -890,7 +884,7 @@ describe("Terra Classic Integration Tests", () => {
sequence, sequence,
emitterAddress emitterAddress
); );
const provider = new ethers.providers.WebSocketProvider( const provider = new ethers.providers.JsonRpcProvider(
ETH_NODE_URL ETH_NODE_URL
) as any; ) as any;
const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY4, provider);
@ -1070,7 +1064,7 @@ describe("Terra Classic Integration Tests", () => {
emitterAddress = getEmitterAddressEth( emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
WORMHOLE_RPC_HOSTS, WORMHOLE_RPC_HOSTS,
@ -1132,7 +1126,6 @@ describe("Terra Classic Integration Tests", () => {
finalCW20BalOnTerra = parseInt(amount); finalCW20BalOnTerra = parseInt(amount);
expect(finalCW20BalOnTerra - initialCW20BalOnTerra === 1).toBe(true); expect(finalCW20BalOnTerra - initialCW20BalOnTerra === 1).toBe(true);
// Done checking wallet balances // Done checking wallet balances
provider.destroy();
} catch (e) { } catch (e) {
console.error("CW20 Transfer failure: ", e); console.error("CW20 Transfer failure: ", e);
done("CW20 Transfer Failure"); done("CW20 Transfer Failure");

View File

@ -1,10 +1,10 @@
import { beforeAll, afterAll, describe, expect, test } from "@jest/globals"; import { beforeAll, describe, expect, test } from "@jest/globals";
import { import {
isTxError,
LCDClient, LCDClient,
MnemonicKey, MnemonicKey,
Msg, Msg,
Wallet, Wallet,
isTxError,
} from "@terra-money/terra.js"; } from "@terra-money/terra.js";
import { ethers } from "ethers"; import { ethers } from "ethers";
import { parseUnits } from "ethers/lib/utils"; import { parseUnits } from "ethers/lib/utils";
@ -61,7 +61,7 @@ const terraClassicWallet = lcdClassic.wallet(
); );
const terraClassicWalletAddress = terraClassicWallet.key.accAddress; const terraClassicWalletAddress = terraClassicWallet.key.accAddress;
const provider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); const provider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
const signer = new ethers.Wallet(ETH_PRIVATE_KEY2, provider); const signer = new ethers.Wallet(ETH_PRIVATE_KEY2, provider);
const ethEmitterAddress = getEmitterAddressEth( const ethEmitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
@ -78,10 +78,6 @@ beforeAll(async () => {
); );
}); });
afterAll(async () => {
provider.destroy();
});
const terraBroadcastAndWaitForExecution = async ( const terraBroadcastAndWaitForExecution = async (
msgs: Msg[], msgs: Msg[],
wallet: Wallet, wallet: Wallet,
@ -179,6 +175,7 @@ describe("Terra Integration Tests", () => {
signer, signer,
TEST_ERC20 TEST_ERC20
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt); const attestSignedVaa = await ethParseLogAndGetSignedVaa(attestReceipt);
const createWrappedMsg = await createWrappedOnTerra( const createWrappedMsg = await createWrappedOnTerra(
CONTRACTS.DEVNET.terra2.token_bridge, CONTRACTS.DEVNET.terra2.token_bridge,
@ -201,6 +198,7 @@ describe("Terra Integration Tests", () => {
CHAIN_ID_TERRA2, CHAIN_ID_TERRA2,
tryNativeToUint8Array(terraWalletAddress, CHAIN_ID_TERRA2) tryNativeToUint8Array(terraWalletAddress, CHAIN_ID_TERRA2)
); );
await provider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt); const transferSignedVaa = await ethParseLogAndGetSignedVaa(transferReceipt);
const redeemMsg = await redeemOnTerra( const redeemMsg = await redeemOnTerra(
CONTRACTS.DEVNET.terra2.token_bridge, CONTRACTS.DEVNET.terra2.token_bridge,

View File

@ -1,10 +1,9 @@
import { describe, expect, it } from "@jest/globals";
import { Connection, PublicKey } from "@solana/web3.js";
const ci = !!process.env.CI; const ci = !!process.env.CI;
// see devnet.md // see devnet.md
export const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545"; export const ETH_NODE_URL = ci
? "http://eth-devnet:8545"
: "http://localhost:8545";
export const ETH_PRIVATE_KEY = export const ETH_PRIVATE_KEY =
"0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // account 0 "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d"; // account 0
// account 1 used by NFT tests // account 1 used by NFT tests

View File

@ -52,8 +52,8 @@ const ci = !!process.env.CI;
const GUARDIAN_HOST = ci ? "guardian" : "localhost"; const GUARDIAN_HOST = ci ? "guardian" : "localhost";
const GUARDIAN_RPCS = [`http://${GUARDIAN_HOST}:7071`]; const GUARDIAN_RPCS = [`http://${GUARDIAN_HOST}:7071`];
const GUARDIAN_METRICS = `http://${GUARDIAN_HOST}:6060/metrics`; const GUARDIAN_METRICS = `http://${GUARDIAN_HOST}:6060/metrics`;
const ETH_NODE_URL = ci ? "ws://eth-devnet:8545" : "ws://localhost:8545"; const ETH_NODE_URL = ci ? "http://eth-devnet:8545" : "http://localhost:8545";
const BSC_NODE_URL = ci ? "ws://eth-devnet2:8545" : "ws://localhost:8546"; const BSC_NODE_URL = ci ? "http://eth-devnet2:8545" : "http://localhost:8546";
const ETH_PRIVATE_KEY9 = const ETH_PRIVATE_KEY9 =
"0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773"; "0xb0057716d5917badaf911b193b12b910811c1497b5bada8d7711f758981c3773";
const ETH_GA_TEST_TOKEN = const ETH_GA_TEST_TOKEN =
@ -70,25 +70,23 @@ function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }
let ethProvider: ethers.providers.WebSocketProvider; let ethProvider: ethers.providers.JsonRpcProvider;
let ethSigner: ethers.Wallet; let ethSigner: ethers.Wallet;
let bscProvider: ethers.providers.WebSocketProvider; let bscProvider: ethers.providers.JsonRpcProvider;
let bscSigner: ethers.Wallet; let bscSigner: ethers.Wallet;
let cosmWasmClient: CosmWasmClient; let cosmWasmClient: CosmWasmClient;
beforeAll(async () => { beforeAll(async () => {
// create a signer for Eth // create a signer for Eth
ethProvider = new ethers.providers.WebSocketProvider(ETH_NODE_URL); ethProvider = new ethers.providers.JsonRpcProvider(ETH_NODE_URL);
ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, ethProvider); ethSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, ethProvider);
// create a signer for BSC // create a signer for BSC
bscProvider = new ethers.providers.WebSocketProvider(BSC_NODE_URL); bscProvider = new ethers.providers.JsonRpcProvider(BSC_NODE_URL);
bscSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, bscProvider); bscSigner = new ethers.Wallet(ETH_PRIVATE_KEY9, bscProvider);
cosmWasmClient = await CosmWasmClient.connect(TENDERMINT_URL); cosmWasmClient = await CosmWasmClient.connect(TENDERMINT_URL);
}); });
afterAll(async () => { afterAll(async () => {
await ethProvider.destroy();
await bscProvider.destroy();
cosmWasmClient.disconnect(); cosmWasmClient.disconnect();
}); });
@ -165,9 +163,8 @@ describe("Global Accountant Tests", () => {
tryNativeToUint8Array(ETH_GA_TEST_TOKEN, CHAIN_ID_ETH) tryNativeToUint8Array(ETH_GA_TEST_TOKEN, CHAIN_ID_ETH)
); );
if (attestedAddress && attestedAddress !== ethers.constants.AddressZero) { if (attestedAddress && attestedAddress !== ethers.constants.AddressZero) {
console.log("already attested"); // already attested
} else { } else {
console.log("attesting...");
// attest the test token // attest the test token
const receipt = await attestFromEth( const receipt = await attestFromEth(
CONTRACTS.DEVNET.ethereum.token_bridge, CONTRACTS.DEVNET.ethereum.token_bridge,
@ -182,7 +179,7 @@ describe("Global Accountant Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
console.log(`fetching vaa ${sequence}...`); await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
GUARDIAN_RPCS, GUARDIAN_RPCS,
@ -193,7 +190,6 @@ describe("Global Accountant Tests", () => {
transport: NodeHttpTransport(), transport: NodeHttpTransport(),
} }
); );
console.log("creating...");
await createWrappedOnEth( await createWrappedOnEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
bscSigner, bscSigner,
@ -225,7 +221,6 @@ describe("Global Accountant Tests", () => {
); );
const amount = parseUnits("1", DECIMALS); const amount = parseUnits("1", DECIMALS);
// approve the bridge to spend tokens // approve the bridge to spend tokens
console.log("approving...");
await approveEth( await approveEth(
CONTRACTS.DEVNET.ethereum.token_bridge, CONTRACTS.DEVNET.ethereum.token_bridge,
ETH_GA_TEST_TOKEN, ETH_GA_TEST_TOKEN,
@ -233,7 +228,6 @@ describe("Global Accountant Tests", () => {
amount amount
); );
// transfer tokens out // transfer tokens out
console.log("transferring...");
const receipt = await transferFromEth( const receipt = await transferFromEth(
CONTRACTS.DEVNET.ethereum.token_bridge, CONTRACTS.DEVNET.ethereum.token_bridge,
ethSigner, ethSigner,
@ -250,7 +244,7 @@ describe("Global Accountant Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.ethereum.token_bridge CONTRACTS.DEVNET.ethereum.token_bridge
); );
console.log(`fetching vaa ${sequence}...`); await ethProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
GUARDIAN_RPCS, GUARDIAN_RPCS,
@ -261,18 +255,12 @@ describe("Global Accountant Tests", () => {
transport: NodeHttpTransport(), transport: NodeHttpTransport(),
} }
); );
console.log("redeeming...");
await redeemOnEth( await redeemOnEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
bscSigner, bscSigner,
signedVAA signedVAA
); );
const afterMetrics = await fetchGlobalAccountantMetrics(); const afterMetrics = await fetchGlobalAccountantMetrics();
console.log(
"approved b/a:",
beforeMetrics.global_accountant_transfer_vaas_submitted_and_approved,
afterMetrics.global_accountant_transfer_vaas_submitted_and_approved
);
if ( if (
afterMetrics.global_accountant_events_received <= afterMetrics.global_accountant_events_received <=
beforeMetrics.global_accountant_events_received || beforeMetrics.global_accountant_events_received ||
@ -333,7 +321,6 @@ describe("Global Accountant Tests", () => {
); );
const amount = parseUnits("1", DECIMALS); const amount = parseUnits("1", DECIMALS);
// approve the bridge to spend tokens // approve the bridge to spend tokens
console.log("approving...");
await approveEth( await approveEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
attestedAddress, attestedAddress,
@ -341,7 +328,6 @@ describe("Global Accountant Tests", () => {
amount amount
); );
// transfer tokens out // transfer tokens out
console.log("transferring...");
const receipt = await transferFromEth( const receipt = await transferFromEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
bscSigner, bscSigner,
@ -358,7 +344,7 @@ describe("Global Accountant Tests", () => {
const emitterAddress = getEmitterAddressEth( const emitterAddress = getEmitterAddressEth(
CONTRACTS.DEVNET.bsc.token_bridge CONTRACTS.DEVNET.bsc.token_bridge
); );
console.log(`fetching vaa ${sequence}...`); await bscProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
// poll until the guardian(s) witness and sign the vaa // poll until the guardian(s) witness and sign the vaa
const { vaaBytes: signedVAA } = await getSignedVAAWithRetry( const { vaaBytes: signedVAA } = await getSignedVAAWithRetry(
GUARDIAN_RPCS, GUARDIAN_RPCS,
@ -369,18 +355,12 @@ describe("Global Accountant Tests", () => {
transport: NodeHttpTransport(), transport: NodeHttpTransport(),
} }
); );
console.log("redeeming...");
await redeemOnEth( await redeemOnEth(
CONTRACTS.DEVNET.ethereum.token_bridge, CONTRACTS.DEVNET.ethereum.token_bridge,
ethSigner, ethSigner,
signedVAA signedVAA
); );
const afterMetrics = await fetchGlobalAccountantMetrics(); const afterMetrics = await fetchGlobalAccountantMetrics();
console.log(
"approved b/a:",
beforeMetrics.global_accountant_transfer_vaas_submitted_and_approved,
afterMetrics.global_accountant_transfer_vaas_submitted_and_approved
);
if ( if (
afterMetrics.global_accountant_events_received <= afterMetrics.global_accountant_events_received <=
beforeMetrics.global_accountant_events_received || beforeMetrics.global_accountant_events_received ||
@ -428,7 +408,6 @@ describe("Global Accountant Tests", () => {
// STEP 3a - redeem spoofed tokens // STEP 3a - redeem spoofed tokens
// //
{ {
console.log("redeeming spoofed tokens");
let vaa: VAA<TokenBridgeTransfer> = { let vaa: VAA<TokenBridgeTransfer> = {
version: 1, version: 1,
guardianSetIndex: 0, guardianSetIndex: 0,
@ -471,7 +450,6 @@ describe("Global Accountant Tests", () => {
const beforeMetrics = await fetchGlobalAccountantMetrics(); const beforeMetrics = await fetchGlobalAccountantMetrics();
const amount = parseUnits("9000", DECIMALS); const amount = parseUnits("9000", DECIMALS);
// approve the bridge to spend tokens // approve the bridge to spend tokens
console.log("approving...");
await approveEth( await approveEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
attestedAddress, attestedAddress,
@ -479,7 +457,6 @@ describe("Global Accountant Tests", () => {
amount amount
); );
// transfer tokens out // transfer tokens out
console.log("transferring...");
const receipt = await transferFromEth( const receipt = await transferFromEth(
CONTRACTS.DEVNET.bsc.token_bridge, CONTRACTS.DEVNET.bsc.token_bridge,
bscSigner, bscSigner,
@ -492,14 +469,9 @@ describe("Global Accountant Tests", () => {
receipt, receipt,
CONTRACTS.DEVNET.bsc.core CONTRACTS.DEVNET.bsc.core
); );
console.log("waiting 30s to fetch metrics..."); await bscProvider.send("anvil_mine", ["0x40"]); // 64 blocks should get the above block to `finalized`
await sleep(30 * 1000); // give the guardian a few seconds to pick up the transfers and attempt to submit them await sleep(30 * 1000); // give the guardian a few seconds to pick up the transfers and attempt to submit them
const afterMetrics = await fetchGlobalAccountantMetrics(); const afterMetrics = await fetchGlobalAccountantMetrics();
console.log(
"balance errors b/a:",
beforeMetrics.global_accountant_total_balance_errors,
afterMetrics.global_accountant_total_balance_errors
);
if ( if (
afterMetrics.global_accountant_error_events_received <= afterMetrics.global_accountant_error_events_received <=
beforeMetrics.global_accountant_error_events_received || beforeMetrics.global_accountant_error_events_received ||
@ -529,6 +501,5 @@ describe("Global Accountant Tests", () => {
).rejects.toThrow(); ).rejects.toThrow();
} }
} }
console.log("success!");
}); });
}); });

View File

@ -1506,7 +1506,7 @@ describe("NTT Global Accountant Tests", () => {
`0x${mockTransferPayload(8, 10, SPOKE_CHAIN_A)}`, `0x${mockTransferPayload(8, 10, SPOKE_CHAIN_A)}`,
0, 0,
{ value }, { value },
relayerOptionalParameters { ...relayerOptionalParameters, consistencyLevel: 200 }
); );
const receipt = await tx.wait(); const receipt = await tx.wait();
// get the sequence from the logs (needed to fetch the vaa) // get the sequence from the logs (needed to fetch the vaa)

View File

@ -0,0 +1,18 @@
process.env.CI = true;
const info = console.info;
console.info = function (x) {
if (x !== "secp256k1 unavailable, reverting to browser version") {
info(x);
}
};
const warn = console.warn;
console.warn = function (x) {
if (
x !==
"bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)"
) {
warn(x);
}
};

View File

@ -5,8 +5,8 @@
"main": "deploy_wormchain.ts", "main": "deploy_wormchain.ts",
"scripts": { "scripts": {
"deploy-wormchain": "ts-node deploy_wormchain.ts", "deploy-wormchain": "ts-node deploy_wormchain.ts",
"test-accountant": "jest test_accountant.ts --verbose", "test-accountant": "jest test_accountant.ts --verbose --setupFiles ./ci-config.js",
"test-ntt-accountant": "jest test_ntt_accountant.ts --verbose", "test-ntt-accountant": "jest test_ntt_accountant.ts --verbose --setupFiles ./ci-config.js",
"test-wormchain": "ts-node test_wormchain.ts", "test-wormchain": "ts-node test_wormchain.ts",
"deploy-and-test": "npm run deploy-wormchain && npm run test-wormchain" "deploy-and-test": "npm run deploy-wormchain && npm run test-wormchain"
}, },

View File

@ -9,7 +9,6 @@ export async function getWallet(
mnemonic: string, mnemonic: string,
options?: DirectSecp256k1HdWalletOptions options?: DirectSecp256k1HdWalletOptions
): Promise<DirectSecp256k1HdWallet> { ): Promise<DirectSecp256k1HdWallet> {
console.log("wallet");
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
prefix: ADDRESS_PREFIX, prefix: ADDRESS_PREFIX,
}); });