Skip to content

Commit

Permalink
solana: wormhole-gatway tests in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
a5-pickle committed Aug 2, 2023
1 parent 17ae475 commit 290a22a
Show file tree
Hide file tree
Showing 19 changed files with 395 additions and 23 deletions.
3 changes: 2 additions & 1 deletion cross-chain/solana/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ target
**/*.rs.bk
node_modules
test-ledger
.yarn
artifacts-mainnet
artifacts-testnet
1 change: 0 additions & 1 deletion cross-chain/solana/.yarnrc.yml

This file was deleted.

70 changes: 68 additions & 2 deletions cross-chain/solana/Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
[features]
seeds = false
skip-lint = false

[workspace]
members = [
"programs/tbtc",
"programs/wormhole-gateway",
]


[programs.localnet]
tbtc = "HksEtDgsXJV1BqcuhzbLRTmXp5gHgHJktieJCtQd3pG"
wormhole-gateway = "8H9F5JGbEMyERycwaGuzLS5MQnV7dn2wm2h6egJ3Leiu"
Expand All @@ -10,7 +18,65 @@ url = "https://api.apr.dev"

[provider]
cluster = "Localnet"
wallet = "/home/eth/.config/solana/id.json"
wallet = "~/.config/solana/id.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
test = "npx ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

[test]
startup_wait = 10000

[test.validator]
url = "https://api.mainnet-beta.solana.com"

### MPL Token Metadata
[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"

### Wormhole Core Bridge
[[test.validator.clone]]
address = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth"

### Wormhole Token Bridge
[[test.validator.clone]]
address = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb"

### Token Bridge -- Wrapped tBTC Mint
[[test.validator.account]]
address = "25rXTx9zDZcHyTav5sRqM6YBvTGu9pPH9yv83uAEqbgG"
filename = "tests/accounts/wrapped_tbtc_mint.json"

### Token Bridge -- Wrapped tBTC Asset
[[test.validator.account]]
address = "5LEUZpBxUQmoxoNGqmYmFEGAPDuhWbAY5CGt519UixLo"
filename = "tests/accounts/wrapped_tbtc_asset.json"

### Token Bridge -- Ethereum Foreign Endpoint
[[test.validator.account]]
address = "DujfLgMKW71CT2W8pxknf42FT86VbcK5PjQ6LsutjWKC"
filename = "tests/accounts/ethereum_token_bridge.json"

### Token Bridge -- Config
[[test.validator.account]]
address = "DapiQYH3BGonhN8cngWcXQ6SrqSm3cwysoznoHr6Sbsx"
filename = "tests/accounts/token_bridge_config.json"

### Core Bridge -- Bridge
[[test.validator.clone]]
address = "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn"
filename = "tests/accounts/core_bridge.json"

### Core Bridge -- Emitter Sequence (Token Bridge's)
[[test.validator.account]]
address = "GF2ghkjwsR9CHkGk1RvuZrApPZGBZynxMm817VNi51Nf"
filename = "tests/accounts/core_emitter_sequence.json"

### Core Bridge -- Fee Collector
[[test.validator.account]]
address = "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy"
filename = "tests/accounts/core_fee_collector.json"

### Core Bridge -- Guardian Set (index == 3)
[[test.validator.account]]
address = "6d3w8mGjJauf6gCAg7WfLezbaPmUHYGuoNutnfYF1RYM"
filename = "tests/accounts/core_guardian_set.json"
26 changes: 26 additions & 0 deletions cross-chain/solana/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

out_solana-devnet=artifacts-testnet
out_mainnet=artifacts-mainnet

.PHONY: all clean build test

all: test

clean:
anchor clean
rm -rf node_modules artifacts-mainnet artifacts-testnet

node_modules:
npm ci

build: $(out_$(NETWORK))

$(out_$(NETWORK)):
ifdef out_$(NETWORK)
anchor build --arch sbf -- --features "$(NETWORK)" -- --no-default-features
mkdir -p $(out_$(NETWORK))
cp target/deploy/*.so $(out_$(NETWORK))/
endif

test: node_modules
anchor test --arch sbf
3 changes: 2 additions & 1 deletion cross-chain/solana/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion cross-chain/solana/programs/tbtc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ crate-type = ["cdylib", "lib"]
name = "tbtc"

[features]
default = []
mainnet = []
solana-devnet = []
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []

[dependencies]
anchor-lang = { version = "=0.28.0", features = ["derive", "init-if-needed"] }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ pub fn deposit_wormhole_tbtc(ctx: Context<DepositWormholeTbtc>, amount: u64) ->
amount,
)?;

let custodian = &ctx.accounts.custodian;

// Now mint.
tbtc::cpi::mint(
CpiContext::new_with_signer(
Expand All @@ -92,11 +94,11 @@ pub fn deposit_wormhole_tbtc(ctx: Context<DepositWormholeTbtc>, amount: u64) ->
mint: ctx.accounts.tbtc_mint.to_account_info(),
config: ctx.accounts.tbtc_config.to_account_info(),
minter_info: ctx.accounts.minter_info.to_account_info(),
minter: ctx.accounts.custodian.to_account_info(),
minter: custodian.to_account_info(),
recipient_token: ctx.accounts.recipient_token.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
},
&[&[Custodian::SEED_PREFIX, &[ctx.bumps["custodian"]]]],
&[&[Custodian::SEED_PREFIX, &[custodian.bump]]],
),
amount,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ const TBTC_FOREIGN_TOKEN_CHAIN: u8 = 2;

#[cfg(feature = "mainnet")]
const TBTC_FOREIGN_TOKEN_ADDRESS: [u8; 32] = [
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, 0xae, 0xba, 0xde, 0x92, 0x2d,
0xf7, 0x35, 0xc3, 0x8c, 0x80, 0xc7, 0xeb, 0xd7, 0x08, 0xaf, 0x50, 0x81, 0x5f, 0xaa,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x08, 0x4f, 0xbA, 0x66, 0x6a,
0x33, 0xd3, 0x75, 0x92, 0xfA, 0x26, 0x33, 0xfD, 0x49, 0xa7, 0x4D, 0xD9, 0x3a, 0x88,
];

/// TODO: Fix this to reflect testnet contract address.
#[cfg(feature = "solana-devnet")]
const TBTC_FOREIGN_TOKEN_ADDRESS: [u8; 32] = [
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d, 0xae, 0xba, 0xde, 0x92, 0x2d,
0xf7, 0x35, 0xc3, 0x8c, 0x80, 0xc7, 0xeb, 0xd7, 0x08, 0xaf, 0x50, 0x81, 0x5f, 0xaa,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x08, 0x4f, 0xbA, 0x66, 0x6a,
0x33, 0xd3, 0x75, 0x92, 0xfA, 0x26, 0x33, 0xfD, 0x49, 0xa7, 0x4D, 0xD9, 0x3a, 0x88,
];

#[derive(Accounts)]
Expand Down
24 changes: 13 additions & 11 deletions cross-chain/solana/tests/01__tbtc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as web3 from '@solana/web3.js';
import { Tbtc } from "../target/types/tbtc";
import { expect } from 'chai';
import { ASSOCIATED_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
import { transferLamports } from "./helpers/utils";

function maybeAuthorityAnd(
signer,
Expand Down Expand Up @@ -446,17 +447,18 @@ describe("tbtc", () => {
await checkState(program, authority, 1, 0, 0);

// Transfer lamports to imposter.
await web3.sendAndConfirmTransaction(
program.provider.connection,
new web3.Transaction().add(
web3.SystemProgram.transfer({
fromPubkey: authority.publicKey,
toPubkey: impostorKeys.publicKey,
lamports: 1000000000,
})
),
[authority.payer]
);
await transferLamports(program.provider.connection, authority.payer, impostorKeys.publicKey, 1000000000);
// await web3.sendAndConfirmTransaction(
// program.provider.connection,
// new web3.Transaction().add(
// web3.SystemProgram.transfer({
// fromPubkey: authority.publicKey,
// toPubkey: impostorKeys.publicKey,
// lamports: 1000000000,
// })
// ),
// [authority.payer]
// );

try {
await addMinter(program, impostorKeys, minter2Keys, authority);
Expand Down
116 changes: 116 additions & 0 deletions cross-chain/solana/tests/02__wormholeGateway.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import * as mock from "@certusone/wormhole-sdk/lib/cjs/mock";
import * as tokenBridge from "@certusone/wormhole-sdk/lib/cjs/solana/tokenBridge";
import * as coreBridge from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole";
import { NodeWallet } from "@certusone/wormhole-sdk/lib/cjs/solana";
import { parseTokenTransferVaa, postVaaSolana, redeemOnSolana, tryNativeToHexString } from "@certusone/wormhole-sdk";
import * as anchor from "@coral-xyz/anchor";
import { Program } from "@coral-xyz/anchor";
import * as spl from "@solana/spl-token";
import { expect } from 'chai';
import { WormholeGateway } from "../target/types/wormhole_gateway";
import { generatePayer, getOrCreateTokenAccount } from "./helpers/utils";
import { web3 } from "@coral-xyz/anchor";

const SOLANA_CORE_BRIDGE_ADDRESS = "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth";
const SOLANA_TOKEN_BRIDGE_ADDRESS = "wormDTUJ6AWPNvk59vGQbDvGJmqbDTdgWgAqcLBCgUb";
const ETHEREUM_TOKEN_BRIDGE_ADDRESS = "0x3ee18B2214AFF97000D974cf647E7C347E8fa585";
const ETHEREUM_TBTC_ADDRESS = "0x18084fbA666a33d37592fA2633fD49a74DD93a88";

const GUARDIAN_SET_INDEX = 3;

function getCustodianPDA(
program: Program<WormholeGateway>,
): [anchor.web3.PublicKey, number] {
return web3.PublicKey.findProgramAddressSync(
[
Buffer.from('custodian'),
],
program.programId
);
}


describe("wormhole-gateway", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());

const program = anchor.workspace.WormholeGateway as Program<WormholeGateway>;
const connection = program.provider.connection;

const authority = (program.provider as anchor.AnchorProvider).wallet as anchor.Wallet;
const newAuthority = anchor.web3.Keypair.generate();
const minterKeys = anchor.web3.Keypair.generate();
const minter2Keys = anchor.web3.Keypair.generate();
const impostorKeys = anchor.web3.Keypair.generate();
const guardianKeys = anchor.web3.Keypair.generate();
const guardian2Keys = anchor.web3.Keypair.generate();

const recipientKeys = anchor.web3.Keypair.generate();

const ethereumTokenBridge = new mock.MockEthereumTokenBridge(ETHEREUM_TOKEN_BRIDGE_ADDRESS);

it('check core bridge and token bridge', async () => {
// Check core bridge guardian set.
const guardianSetData = await coreBridge.getGuardianSet(connection, SOLANA_CORE_BRIDGE_ADDRESS, GUARDIAN_SET_INDEX);
expect(guardianSetData.keys).has.length(1);

// Set up new wallet
const payer = await generatePayer(connection, authority.payer);

// Check wrapped tBTC mint.
const wrappedTbtcMint = tokenBridge.deriveWrappedMintKey(SOLANA_TOKEN_BRIDGE_ADDRESS, 2, ETHEREUM_TBTC_ADDRESS);
const mintData = await spl.getMint(connection, wrappedTbtcMint);
expect(mintData.decimals).to.equal(8);
expect(mintData.supply).to.equal(BigInt(90));

const wrappedTbtcToken = await getOrCreateTokenAccount(connection, payer, wrappedTbtcMint, payer.publicKey);

// Bridge tbtc to token account.
const published = ethereumTokenBridge.publishTransferTokens(
tryNativeToHexString(ETHEREUM_TBTC_ADDRESS, "ethereum"),
2,
BigInt("100000000000"),
1,
wrappedTbtcToken.address.toBuffer().toString("hex"),
BigInt(0),
0,
0
);

const signedVaa = await mockSignAndPostVaa(connection, payer, published);

const tx = await redeemOnSolana(
connection,
SOLANA_CORE_BRIDGE_ADDRESS,
SOLANA_TOKEN_BRIDGE_ADDRESS,
payer.publicKey,
signedVaa,
);
await web3.sendAndConfirmTransaction(connection, tx, [payer]);
});

it('setup', async () => {
// await setup(program, authority);
// await checkState(program, authority, 0, 0, 0);
});
});

async function mockSignAndPostVaa(connection: web3.Connection, payer: web3.Keypair, published: Buffer) {
const guardians = new mock.MockGuardians(
GUARDIAN_SET_INDEX,
["cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0"]
);

// Add guardian signature.
const signedVaa = guardians.addSignatures(published, [0]);

// Verify and post VAA.
await postVaaSolana(connection,
new NodeWallet(payer).signTransaction,
SOLANA_CORE_BRIDGE_ADDRESS,
payer.publicKey,
signedVaa
);

return signedVaa;
}
13 changes: 13 additions & 0 deletions cross-chain/solana/tests/accounts/core_bridge.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"pubkey": "2yVjuQwpsvdsrywzsJJVs9Ueh4zayyo5DYJbBNc3DDpn",
"account": {
"lamports": 1057920,
"data": [
"AwAAAPhmKAUAAAAAgFEBAGQAAAAAAAAA",
"base64"
],
"owner": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
"executable": false,
"rentEpoch": 361
}
}
13 changes: 13 additions & 0 deletions cross-chain/solana/tests/accounts/core_emitter_sequence.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"pubkey": "GF2ghkjwsR9CHkGk1RvuZrApPZGBZynxMm817VNi51Nf",
"account": {
"lamports": 946560,
"data": [
"4KMEAAAAAAA=",
"base64"
],
"owner": "worm2ZoG2kUd4vFXhvjh93UUH596ayRfgQ2MgjNMTth",
"executable": false,
"rentEpoch": 361
}
}
13 changes: 13 additions & 0 deletions cross-chain/solana/tests/accounts/core_fee_collector.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"pubkey": "9bFNrXNb2WTx8fMHXCheaZqkLZ3YCCaiqTftHxeintHy",
"account": {
"lamports": 86533780,
"data": [
"",
"base64"
],
"owner": "11111111111111111111111111111111",
"executable": false,
"rentEpoch": 361
}
}
Loading

0 comments on commit 290a22a

Please sign in to comment.