tokenbridge: implement new governance packet spec
Change-Id: Iee4b596b6a8ca9dfc9c6ee8c6188a4083a05edeb
This commit is contained in:
parent
c819165d5c
commit
14e892300c
|
@ -20,17 +20,21 @@ import "../interfaces/IWormhole.sol";
|
||||||
contract BridgeGovernance is BridgeGetters, BridgeSetters, ERC1967Upgrade {
|
contract BridgeGovernance is BridgeGetters, BridgeSetters, ERC1967Upgrade {
|
||||||
using BytesLib for bytes;
|
using BytesLib for bytes;
|
||||||
|
|
||||||
|
// "TokenBridge" (left padded)
|
||||||
|
bytes32 constant module = 0x000000000000000000000000000000000000000000546f6b656e427269646765;
|
||||||
|
|
||||||
// Execute a RegisterChain governance message
|
// Execute a RegisterChain governance message
|
||||||
function registerChain(bytes memory encodedVM) public {
|
function registerChain(bytes memory encodedVM) public {
|
||||||
(IWormhole.VM memory vm, bool valid, string memory reason) = verifyGovernanceVM(encodedVM);
|
(IWormhole.VM memory vm, bool valid, string memory reason) = verifyGovernanceVM(encodedVM);
|
||||||
require(valid, reason);
|
require(valid, reason);
|
||||||
|
|
||||||
|
|
||||||
setGovernanceActionConsumed(vm.hash);
|
setGovernanceActionConsumed(vm.hash);
|
||||||
|
|
||||||
BridgeStructs.RegisterChain memory chain = parseRegisterChain(vm.payload);
|
BridgeStructs.RegisterChain memory chain = parseRegisterChain(vm.payload);
|
||||||
|
|
||||||
setBridgeImplementation(chain.chainID, chain.emitterAddress);
|
require(chain.chainId == chainId() || chain.chainId == 0, "invalid chain id");
|
||||||
|
|
||||||
|
setBridgeImplementation(chain.emitterChainID, chain.emitterAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a UpgradeContract governance message
|
// Execute a UpgradeContract governance message
|
||||||
|
@ -42,7 +46,7 @@ contract BridgeGovernance is BridgeGetters, BridgeSetters, ERC1967Upgrade {
|
||||||
|
|
||||||
BridgeStructs.UpgradeContract memory implementation = parseUpgrade(vm.payload);
|
BridgeStructs.UpgradeContract memory implementation = parseUpgrade(vm.payload);
|
||||||
|
|
||||||
require(implementation.chainID == chainId(), "wrong chain id");
|
require(implementation.chainId == chainId(), "wrong chain id");
|
||||||
|
|
||||||
upgradeImplementation(address(uint160(uint256(implementation.newContract))));
|
upgradeImplementation(address(uint160(uint256(implementation.newContract))));
|
||||||
}
|
}
|
||||||
|
@ -85,34 +89,51 @@ contract BridgeGovernance is BridgeGetters, BridgeSetters, ERC1967Upgrade {
|
||||||
function parseRegisterChain(bytes memory encoded) public pure returns(BridgeStructs.RegisterChain memory chain) {
|
function parseRegisterChain(bytes memory encoded) public pure returns(BridgeStructs.RegisterChain memory chain) {
|
||||||
uint index = 0;
|
uint index = 0;
|
||||||
|
|
||||||
chain.payloadID = encoded.toUint8(index);
|
// governance header
|
||||||
|
|
||||||
|
chain.module = encoded.toBytes32(index);
|
||||||
|
index += 32;
|
||||||
|
require(chain.module == module, "invalid RegisterChain: wrong module");
|
||||||
|
|
||||||
|
chain.action = encoded.toUint8(index);
|
||||||
index += 1;
|
index += 1;
|
||||||
|
require(chain.action == 1, "invalid RegisterChain: wrong action");
|
||||||
|
|
||||||
require(chain.payloadID == 3, "invalid RegisterChain");
|
chain.chainId = encoded.toUint16(index);
|
||||||
|
index += 2;
|
||||||
|
|
||||||
chain.chainID = encoded.toUint16(index);
|
// payload
|
||||||
|
|
||||||
|
chain.emitterChainID = encoded.toUint16(index);
|
||||||
index += 2;
|
index += 2;
|
||||||
|
|
||||||
chain.emitterAddress = encoded.toBytes32(index);
|
chain.emitterAddress = encoded.toBytes32(index);
|
||||||
index += 32;
|
index += 32;
|
||||||
|
|
||||||
require(encoded.length == index, "invalid RegisterChain");
|
require(encoded.length == index, "invalid RegisterChain: wrong length");
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseUpgrade(bytes memory encoded) public pure returns(BridgeStructs.UpgradeContract memory chain) {
|
function parseUpgrade(bytes memory encoded) public pure returns(BridgeStructs.UpgradeContract memory chain) {
|
||||||
uint index = 0;
|
uint index = 0;
|
||||||
|
|
||||||
chain.payloadID = encoded.toUint8(index);
|
// governance header
|
||||||
|
|
||||||
|
chain.module = encoded.toBytes32(index);
|
||||||
|
index += 32;
|
||||||
|
require(chain.module == module, "invalid UpgradeContract: wrong module");
|
||||||
|
|
||||||
|
chain.action = encoded.toUint8(index);
|
||||||
index += 1;
|
index += 1;
|
||||||
|
require(chain.action == 2, "invalid UpgradeContract: wrong action");
|
||||||
|
|
||||||
require(chain.payloadID == 4, "invalid UpgradeContract");
|
chain.chainId = encoded.toUint16(index);
|
||||||
|
|
||||||
chain.chainID = encoded.toUint16(index);
|
|
||||||
index += 2;
|
index += 2;
|
||||||
|
|
||||||
|
// payload
|
||||||
|
|
||||||
chain.newContract = encoded.toBytes32(index);
|
chain.newContract = encoded.toBytes32(index);
|
||||||
index += 32;
|
index += 32;
|
||||||
|
|
||||||
require(encoded.length == index, "invalid UpgradeContract");
|
require(encoded.length == index, "invalid UpgradeContract: wrong length");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,19 +37,29 @@ contract BridgeStructs {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RegisterChain {
|
struct RegisterChain {
|
||||||
// PayloadID uint8 = 3
|
// Governance Header
|
||||||
uint8 payloadID;
|
// module: "TokenBridge" left-padded
|
||||||
|
bytes32 module;
|
||||||
|
// governance action: 1
|
||||||
|
uint8 action;
|
||||||
|
// governance paket chain id: this or 0
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
// Chain ID
|
// Chain ID
|
||||||
uint16 chainID;
|
uint16 emitterChainID;
|
||||||
// Emitter address. Left-zero-padded if shorter than 32 bytes
|
// Emitter address. Left-zero-padded if shorter than 32 bytes
|
||||||
bytes32 emitterAddress;
|
bytes32 emitterAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UpgradeContract {
|
struct UpgradeContract {
|
||||||
// PayloadID uint8 = 4
|
// Governance Header
|
||||||
uint8 payloadID;
|
// module: "TokenBridge" left-padded
|
||||||
// Chain ID
|
bytes32 module;
|
||||||
uint16 chainID;
|
// governance action: 2
|
||||||
|
uint8 action;
|
||||||
|
// governance paket chain id
|
||||||
|
uint16 chainId;
|
||||||
|
|
||||||
// Address of the new contract
|
// Address of the new contract
|
||||||
bytes32 newContract;
|
bytes32 newContract;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,10 @@ contract("Bridge", function () {
|
||||||
const accounts = await web3.eth.getAccounts();
|
const accounts = await web3.eth.getAccounts();
|
||||||
|
|
||||||
let data = [
|
let data = [
|
||||||
"0x03",
|
"0x",
|
||||||
|
"000000000000000000000000000000000000000000546f6b656e427269646765",
|
||||||
|
"01",
|
||||||
|
"0000",
|
||||||
web3.eth.abi.encodeParameter("uint16", testForeignChainId).substring(2 + (64 - 4)),
|
web3.eth.abi.encodeParameter("uint16", testForeignChainId).substring(2 + (64 - 4)),
|
||||||
web3.eth.abi.encodeParameter("bytes32", testForeignBridgeContract).substring(2),
|
web3.eth.abi.encodeParameter("bytes32", testForeignBridgeContract).substring(2),
|
||||||
].join('')
|
].join('')
|
||||||
|
@ -121,7 +124,9 @@ contract("Bridge", function () {
|
||||||
const mock = await MockBridgeImplementation.new();
|
const mock = await MockBridgeImplementation.new();
|
||||||
|
|
||||||
let data = [
|
let data = [
|
||||||
"0x04",
|
"0x",
|
||||||
|
"000000000000000000000000000000000000000000546f6b656e427269646765",
|
||||||
|
"02",
|
||||||
web3.eth.abi.encodeParameter("uint16", testChainId).substring(2 + (64 - 4)),
|
web3.eth.abi.encodeParameter("uint16", testChainId).substring(2 + (64 - 4)),
|
||||||
web3.eth.abi.encodeParameter("address", mock.address).substring(2),
|
web3.eth.abi.encodeParameter("address", mock.address).substring(2),
|
||||||
].join('')
|
].join('')
|
||||||
|
|
Loading…
Reference in New Issue