add EVM contract for batched VAA development
This commit is contained in:
parent
99fb46d549
commit
d7b102df70
|
@ -53,7 +53,7 @@ spec:
|
||||||
command:
|
command:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
- -c
|
- -c
|
||||||
- "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_terra2_chain.js && npx truffle exec scripts/register_bsc_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0"
|
- "npm run migrate && npm run deploy-batched-vaa-sender && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_terra2_chain.js && npx truffle exec scripts/register_bsc_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0"
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
periodSeconds: 1
|
periodSeconds: 1
|
||||||
failureThreshold: 300
|
failureThreshold: 300
|
||||||
|
|
|
@ -57,3 +57,13 @@ wormhole/ethereum $ ../scripts/install-foundry
|
||||||
```
|
```
|
||||||
|
|
||||||
The installer script installs foundry and the appropriate solc version to build the contracts.
|
The installer script installs foundry and the appropriate solc version to build the contracts.
|
||||||
|
|
||||||
|
### Batched VAAs
|
||||||
|
|
||||||
|
To send a transaction that will create multiple VAAs, invoke the `sendMultipleMessages` method of [ethereum/contracts/mock/MockBatchedVAASender.sol](./contracts/mock/MockBatchedVAASender.sol) with the truffle script:
|
||||||
|
|
||||||
|
npx truffle exec scripts/send_batched_vaa.js
|
||||||
|
|
||||||
|
or invoke the same script in the tilt devnet:
|
||||||
|
|
||||||
|
minikube kubectl -- exec -n wormhole eth-devnet-0 -c tests -- npx truffle exec scripts/send_batched_vaa.js
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
// contracts/mock/MockBatchedVAASender.sol
|
||||||
|
// SPDX-License-Identifier: Apache 2
|
||||||
|
|
||||||
|
pragma solidity ^0.8.0;
|
||||||
|
|
||||||
|
import "../libraries/external/BytesLib.sol";
|
||||||
|
import "../interfaces/IWormhole.sol";
|
||||||
|
|
||||||
|
contract MockBatchedVAASender {
|
||||||
|
using BytesLib for bytes;
|
||||||
|
|
||||||
|
address wormholeCoreAddress;
|
||||||
|
|
||||||
|
function sendMultipleMessages(
|
||||||
|
uint32 nonce,
|
||||||
|
bytes memory payload,
|
||||||
|
uint8 consistencyLevel
|
||||||
|
)
|
||||||
|
public
|
||||||
|
payable
|
||||||
|
returns (
|
||||||
|
uint64 messageSequence0,
|
||||||
|
uint64 messageSequence1,
|
||||||
|
uint64 messageSequence2
|
||||||
|
)
|
||||||
|
{
|
||||||
|
messageSequence0 = wormholeCore().publishMessage{value: msg.value}(
|
||||||
|
nonce,
|
||||||
|
payload,
|
||||||
|
consistencyLevel
|
||||||
|
);
|
||||||
|
|
||||||
|
messageSequence1 = wormholeCore().publishMessage{value: msg.value}(
|
||||||
|
nonce,
|
||||||
|
payload,
|
||||||
|
consistencyLevel
|
||||||
|
);
|
||||||
|
|
||||||
|
messageSequence2 = wormholeCore().publishMessage{value: msg.value}(
|
||||||
|
nonce,
|
||||||
|
payload,
|
||||||
|
consistencyLevel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wormholeCore() private view returns (IWormhole) {
|
||||||
|
return IWormhole(wormholeCoreAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setup(address _wormholeCore) public {
|
||||||
|
wormholeCoreAddress = _wormholeCore;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
require('dotenv').config({ path: "../.env" });
|
||||||
|
|
||||||
|
const Wormhole = artifacts.require("Wormhole");
|
||||||
|
const MockBatchedVAASender = artifacts.require("MockBatchedVAASender");
|
||||||
|
|
||||||
|
module.exports = async function (deployer, network, accounts) {
|
||||||
|
|
||||||
|
await deployer.deploy(MockBatchedVAASender)
|
||||||
|
|
||||||
|
const contract = new web3.eth.Contract(MockBatchedVAASender.abi, MockBatchedVAASender.address);
|
||||||
|
|
||||||
|
await contract.methods.setup(
|
||||||
|
Wormhole.address
|
||||||
|
).send({from: accounts[0]})
|
||||||
|
};
|
|
@ -25,6 +25,7 @@
|
||||||
"deploy-bridge-implementation-only": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 6 --to 6",
|
"deploy-bridge-implementation-only": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 6 --to 6",
|
||||||
"deploy-read-only": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 1 --to 2",
|
"deploy-read-only": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 1 --to 2",
|
||||||
"deploy_weth9": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 9",
|
"deploy_weth9": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 9",
|
||||||
|
"deploy-batched-vaa-sender": "mkdir -p build/contracts && cp node_modules/@openzeppelin/contracts/build/contracts/* build/contracts/ && truffle migrate --f 10 --to 10",
|
||||||
"verify": "patch -u -f node_modules/truffle-plugin-verify/constants.js -i truffle-verify-constants.patch; truffle run verify $npm_config_module@$npm_config_contract_address --network $npm_config_network",
|
"verify": "patch -u -f node_modules/truffle-plugin-verify/constants.js -i truffle-verify-constants.patch; truffle run verify $npm_config_module@$npm_config_contract_address --network $npm_config_network",
|
||||||
"verify-token": "patch -u -f node_modules/truffle-plugin-verify/constants.js -i truffle-verify-constants.patch; truffle run verify BridgeToken@$npm_config_contract_address --forceConstructorArgs string:$npm_config_constructor_args --network $npm_config_network",
|
"verify-token": "patch -u -f node_modules/truffle-plugin-verify/constants.js -i truffle-verify-constants.patch; truffle run verify BridgeToken@$npm_config_contract_address --forceConstructorArgs string:$npm_config_constructor_args --network $npm_config_network",
|
||||||
"abigen": "truffle run abigen"
|
"abigen": "truffle run abigen"
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
const Wormhole = artifacts.require("Wormhole");
|
||||||
|
const MockBatchedVAASender = artifacts.require("MockBatchedVAASender");
|
||||||
|
|
||||||
|
module.exports = async function(callback) {
|
||||||
|
try {
|
||||||
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
|
||||||
|
await MockBatchedVAASender.deploy();
|
||||||
|
|
||||||
|
const batchedSender = new web3.eth.Contract(MockBatchedVAASender.abi, MockBatchedVAASender.address);
|
||||||
|
await batchedSender.methods.setup(Wormhole.address).send({from: accounts[0]});
|
||||||
|
|
||||||
|
callback();
|
||||||
|
} catch (e) {
|
||||||
|
callback(e);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
const MockBatchedVAASender = artifacts.require("MockBatchedVAASender");
|
||||||
|
|
||||||
|
module.exports = async function(callback) {
|
||||||
|
try {
|
||||||
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
|
||||||
|
const batchedSender = await MockBatchedVAASender.deployed()
|
||||||
|
|
||||||
|
const contract = new web3.eth.Contract(MockBatchedVAASender.abi, batchedSender.address);
|
||||||
|
|
||||||
|
const nonce = Math.round(Date.now() / 1000);
|
||||||
|
const nonceHex = nonce.toString(16)
|
||||||
|
|
||||||
|
const res = await contract.methods.sendMultipleMessages(
|
||||||
|
"0x" + nonceHex,
|
||||||
|
"0x1",
|
||||||
|
32
|
||||||
|
).send({
|
||||||
|
value: 0,
|
||||||
|
from: accounts[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('sendMultipleMessages response', res)
|
||||||
|
|
||||||
|
callback();
|
||||||
|
} catch (e) {
|
||||||
|
callback(e);
|
||||||
|
}
|
||||||
|
};
|
|
@ -5,6 +5,7 @@ const path = require('path');
|
||||||
const Wormhole = artifacts.require("Wormhole");
|
const Wormhole = artifacts.require("Wormhole");
|
||||||
const MockImplementation = artifacts.require("MockImplementation");
|
const MockImplementation = artifacts.require("MockImplementation");
|
||||||
const Implementation = artifacts.require("Implementation");
|
const Implementation = artifacts.require("Implementation");
|
||||||
|
const MockBatchedVAASender = artifacts.require("MockBatchedVAASender");
|
||||||
|
|
||||||
const testSigner1PK = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
|
const testSigner1PK = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
|
||||||
const testSigner2PK = "892330666a850761e7370376430bb8c2aa1494072d3bfeaed0c4fa3d5a9135fe";
|
const testSigner2PK = "892330666a850761e7370376430bb8c2aa1494072d3bfeaed0c4fa3d5a9135fe";
|
||||||
|
@ -114,6 +115,34 @@ contract("Wormhole", function () {
|
||||||
assert.equal(log.events.LogMessagePublished.returnValues.consistencyLevel, 32);
|
assert.equal(log.events.LogMessagePublished.returnValues.consistencyLevel, 32);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should log sequential sequence numbers for multi-VAA transactions", async function () {
|
||||||
|
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||||
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
|
||||||
|
const mockIntegration = new web3.eth.Contract(MockBatchedVAASender.abi, MockBatchedVAASender.address);
|
||||||
|
|
||||||
|
await mockIntegration.methods.sendMultipleMessages(
|
||||||
|
"0x1",
|
||||||
|
"0x1",
|
||||||
|
32
|
||||||
|
).send({
|
||||||
|
value: 0, // fees are set to 0 initially
|
||||||
|
from: accounts[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
const events = (await initialized.getPastEvents('LogMessagePublished', {
|
||||||
|
fromBlock: 'latest'
|
||||||
|
}))
|
||||||
|
|
||||||
|
let firstSequence = Number(events[0].returnValues.sequence.toString())
|
||||||
|
|
||||||
|
let secondSequence = Number(events[1].returnValues.sequence.toString())
|
||||||
|
assert.equal(secondSequence, firstSequence + 1);
|
||||||
|
|
||||||
|
let thirdSequence = Number(events[2].returnValues.sequence.toString())
|
||||||
|
assert.equal(thirdSequence, secondSequence + 1);
|
||||||
|
})
|
||||||
|
|
||||||
it("should increase the sequence for an account", async function () {
|
it("should increase the sequence for an account", async function () {
|
||||||
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||||
const accounts = await web3.eth.getAccounts();
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
@ -130,6 +159,33 @@ contract("Wormhole", function () {
|
||||||
assert.equal(log.events.LogMessagePublished.returnValues.sequence.toString(), "1");
|
assert.equal(log.events.LogMessagePublished.returnValues.sequence.toString(), "1");
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should get the same nonce from all VAAs produced by a transaction", async function () {
|
||||||
|
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||||
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
|
||||||
|
const mockIntegration = new web3.eth.Contract(MockBatchedVAASender.abi, MockBatchedVAASender.address);
|
||||||
|
|
||||||
|
const nonce = Math.round(Date.now() / 1000);
|
||||||
|
const nonceHex = nonce.toString(16)
|
||||||
|
|
||||||
|
await mockIntegration.methods.sendMultipleMessages(
|
||||||
|
"0x" + nonceHex,
|
||||||
|
"0x1",
|
||||||
|
32
|
||||||
|
).send({
|
||||||
|
value: 0, // fees are set to 0 initially
|
||||||
|
from: accounts[0]
|
||||||
|
});
|
||||||
|
|
||||||
|
const events = (await initialized.getPastEvents('LogMessagePublished', {
|
||||||
|
fromBlock: 'latest'
|
||||||
|
}))
|
||||||
|
|
||||||
|
assert.equal(events[0].returnValues.nonce, nonce);
|
||||||
|
assert.equal(events[1].returnValues.nonce, nonce);
|
||||||
|
assert.equal(events[2].returnValues.nonce, nonce);
|
||||||
|
})
|
||||||
|
|
||||||
it("parses VMs correctly", async function () {
|
it("parses VMs correctly", async function () {
|
||||||
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue