add EVM contract for batched VAA development
This commit is contained in:
parent
99fb46d549
commit
d7b102df70
|
@ -53,7 +53,7 @@ spec:
|
|||
command:
|
||||
- /bin/sh
|
||||
- -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:
|
||||
periodSeconds: 1
|
||||
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.
|
||||
|
||||
### 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-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-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-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"
|
||||
|
|
|
@ -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 MockImplementation = artifacts.require("MockImplementation");
|
||||
const Implementation = artifacts.require("Implementation");
|
||||
const MockBatchedVAASender = artifacts.require("MockBatchedVAASender");
|
||||
|
||||
const testSigner1PK = "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0";
|
||||
const testSigner2PK = "892330666a850761e7370376430bb8c2aa1494072d3bfeaed0c4fa3d5a9135fe";
|
||||
|
@ -114,6 +115,34 @@ contract("Wormhole", function () {
|
|||
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 () {
|
||||
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||
const accounts = await web3.eth.getAccounts();
|
||||
|
@ -130,6 +159,33 @@ contract("Wormhole", function () {
|
|||
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 () {
|
||||
const initialized = new web3.eth.Contract(ImplementationFullABI, Wormhole.address);
|
||||
|
||||
|
|
Loading…
Reference in New Issue