From 799d8bfcc50a8717c37d22bbdd59a6c7cba39eed Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Fri, 15 Sep 2023 20:20:50 +0200 Subject: [PATCH 01/14] start signature accumulator --- src/errors/IPCErrors.sol | 2 ++ src/gateway/GatewayRouterFacet.sol | 43 +++++++++++++++++++++++++++++- src/lib/LibGatewayActorStorage.sol | 2 ++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/errors/IPCErrors.sol b/src/errors/IPCErrors.sol index 9cdac3648..015560040 100644 --- a/src/errors/IPCErrors.sol +++ b/src/errors/IPCErrors.sol @@ -23,6 +23,8 @@ error InvalidCrossMsgDstSubnet(); error InvalidCrossMsgFromSubnet(); error InvalidCrossMsgNonce(); error InvalidMajorityPercentage(); +error InvalidSignature(); +error InvalidSignatureLength(); error InvalidSubmissionPeriod(); error MessagesNotSorted(); error NoRewardToWithdraw(); diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index c278dfb47..7dd7fa098 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -8,7 +8,9 @@ import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {Status} from "../enums/Status.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; -import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch} from "../errors/IPCErrors.sol"; +import {IPCMsgType} from "../enums/IPCMsgType.sol"; +import {Membership} from "../structs/Validator.sol"; +import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, InvalidSignatureLength} from "../errors/IPCErrors.sol"; import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet} from "../errors/IPCErrors.sol"; import {MessagesNotSorted, NotInitialized, NotEnoughBalance, NotRegisteredSubnet} from "../errors/IPCErrors.sol"; import {NotValidator, SubnetNotActive} from "../errors/IPCErrors.sol"; @@ -21,6 +23,7 @@ import {StorableMsgHelper} from "../lib/StorableMsgHelper.sol"; import {FvmAddress} from "../structs/FvmAddress.sol"; import {FvmAddressHelper} from "../lib/FvmAddressHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; +import {ECDSA} from "openzeppelin-contracts/utils/cryptography/ECDSA.sol"; contract GatewayRouterFacet is GatewayActorModifiers { using FilAddress for address; @@ -30,6 +33,9 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; + event SignaturesUpdated(uint256 h, Membership membership, bytes signature); + event SignatureInvalid(uint256 h, Membership membership, bytes signature); + /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality /// @param n - the configuration number for the next membership @@ -179,4 +185,39 @@ contract GatewayRouterFacet is GatewayActorModifiers { } } } + + /// @notice checks whether the provided provided signature is valid and accumulates it. + /// The forwarder argument determines the previous subnet that submitted the checkpoint triggering the cross-net message execution. + /// @param h - height when the signature was created + /// @param membership - the membership at height `h` + /// @param signature - added signature + function newSignature( + uint256 h, + Membership calldata membership, + bytes calldata signature + ) external systemActorOnly { + if (signature.length != 65) { + revert InvalidSignatureLength(); + } + bytes32 hash = s.finalitiesMap[h].blockHash; + + (address signer, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature); + if (err != ECDSA.RecoverError.NoError) { + revert InvalidSignature(); + } + + uint256 len = membership.validators.length; + for (uint256 i = 0; i < len; ) { + if (signer == membership.validators[i].addr.extractEvmAddress().normalize()) { + s.signatures[h].push(signature); + emit SignaturesUpdated({h: h, membership: membership, signature: signature}); + return; + } + + unchecked { + ++i; + } + } + emit SignatureInvalid({h: h, membership: membership, signature: signature}); + } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index e6fd4bfad..f4c1b2e22 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -34,6 +34,8 @@ struct GatewayActorStorage { Membership currentMembership; /// @notice The last membership received from the parent and adopted Membership lastMembership; + /// @notice height => Signature[] + mapping(uint256 => bytes[]) signatures; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] mapping(uint64 => mapping(bytes32 => uint256[2])) children; /// @notice epoch => SubnetID => check => exists From d3381c86865ee926716029bbe69aeb1f74432bf2 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Sat, 16 Sep 2023 15:50:50 +0200 Subject: [PATCH 02/14] draft interfaces --- src/gateway/GatewayRouterFacet.sol | 18 +++++++++--------- src/lib/LibGatewayActorStorage.sol | 6 ++++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 7dd7fa098..1fd2e4060 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -33,8 +33,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; - event SignaturesUpdated(uint256 h, Membership membership, bytes signature); - event SignatureInvalid(uint256 h, Membership membership, bytes signature); + event SignaturesUpdated(uint256 h, bytes32 pof, Membership membership, bytes signature); + event SignatureInvalid(uint256 h, bytes32 pof, Membership membership, bytes signature); /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality @@ -186,22 +186,22 @@ contract GatewayRouterFacet is GatewayActorModifiers { } } - /// @notice checks whether the provided provided signature is valid and accumulates it. - /// The forwarder argument determines the previous subnet that submitted the checkpoint triggering the cross-net message execution. + /// @notice checks whether the provided proof-of-finality signature for a block at height `h ` is valid and accumulates it. /// @param h - height when the signature was created + /// @param pof - proof of finality /// @param membership - the membership at height `h` /// @param signature - added signature function newSignature( uint256 h, + bytes32 pof, Membership calldata membership, bytes calldata signature ) external systemActorOnly { if (signature.length != 65) { revert InvalidSignatureLength(); } - bytes32 hash = s.finalitiesMap[h].blockHash; - (address signer, ECDSA.RecoverError err, ) = ECDSA.tryRecover(hash, signature); + (address signer, ECDSA.RecoverError err, ) = ECDSA.tryRecover(pof, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } @@ -209,8 +209,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { uint256 len = membership.validators.length; for (uint256 i = 0; i < len; ) { if (signer == membership.validators[i].addr.extractEvmAddress().normalize()) { - s.signatures[h].push(signature); - emit SignaturesUpdated({h: h, membership: membership, signature: signature}); + s.collectedSignatures[h].push(signature); + emit SignaturesUpdated({h: h, pof: pof, membership: membership, signature: signature}); return; } @@ -218,6 +218,6 @@ contract GatewayRouterFacet is GatewayActorModifiers { ++i; } } - emit SignatureInvalid({h: h, membership: membership, signature: signature}); + emit SignatureInvalid({h: h, pof: pof, membership: membership, signature: signature}); } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index f4c1b2e22..017e5f841 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -34,8 +34,10 @@ struct GatewayActorStorage { Membership currentMembership; /// @notice The last membership received from the parent and adopted Membership lastMembership; - /// @notice height => Signature[] - mapping(uint256 => bytes[]) signatures; + /// @notice The signatures collected for the proof of finality at height `h` + mapping(uint256 => bytes[]) collectedSignatures; + /// @notice Bottom-up proof of finality for a block at height `h` + mapping(uint256 => bytes32) bottomUpProofOfFinalities; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] mapping(uint64 => mapping(bytes32 => uint256[2])) children; /// @notice epoch => SubnetID => check => exists From 742526840570dbb0878cf4b284a1e980bab040b7 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Sat, 16 Sep 2023 16:22:10 +0200 Subject: [PATCH 03/14] process signatures --- src/gateway/GatewayRouterFacet.sol | 28 +++++++++++++++++++++------- src/lib/LibGatewayActorStorage.sol | 4 +++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 1fd2e4060..4061009ec 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -35,6 +35,7 @@ contract GatewayRouterFacet is GatewayActorModifiers { event SignaturesUpdated(uint256 h, bytes32 pof, Membership membership, bytes signature); event SignatureInvalid(uint256 h, bytes32 pof, Membership membership, bytes signature); + event PoFThresholdReached(uint256 h, bytes32 pof, Membership membership, uint256 threshold); /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality @@ -206,18 +207,31 @@ contract GatewayRouterFacet is GatewayActorModifiers { revert InvalidSignature(); } - uint256 len = membership.validators.length; - for (uint256 i = 0; i < len; ) { - if (signer == membership.validators[i].addr.extractEvmAddress().normalize()) { - s.collectedSignatures[h].push(signature); + uint256 signersNumber = membership.validators.length; + uint256 signerIndex; + bool signerExists; + for (signerIndex = 0; signerIndex < signersNumber; ) { + if (signer == membership.validators[signerIndex].addr.extractEvmAddress().normalize()) { + s.bottomUpCollectedSignatures[h][pof].push(signature); emit SignaturesUpdated({h: h, pof: pof, membership: membership, signature: signature}); - return; + signerExists = true; + break; } unchecked { - ++i; + ++signerIndex; + } + } + + if (signerExists) { + uint256 threshold = s.bottomUpCollectedSignaturesThreshold[h][pof]; + threshold += membership.validators[signerIndex].weight; + + if (threshold >= membership.totalWeight) { + emit PoFThresholdReached({h: h, pof: pof, membership: membership, threshold: threshold}); } + } else { + emit SignatureInvalid({h: h, pof: pof, membership: membership, signature: signature}); } - emit SignatureInvalid({h: h, pof: pof, membership: membership, signature: signature}); } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index 017e5f841..8af08f4e4 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -35,7 +35,9 @@ struct GatewayActorStorage { /// @notice The last membership received from the parent and adopted Membership lastMembership; /// @notice The signatures collected for the proof of finality at height `h` - mapping(uint256 => bytes[]) collectedSignatures; + mapping(uint256 => mapping(bytes32 => bytes[])) bottomUpCollectedSignatures; + /// @notice The signatures collected for the proof of finality at height `h` + mapping(uint256 => mapping(bytes32 => uint256)) bottomUpCollectedSignaturesThreshold; /// @notice Bottom-up proof of finality for a block at height `h` mapping(uint256 => bytes32) bottomUpProofOfFinalities; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] From 6f4c1b3e6285eef896306ce8e3b218099538e553 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Mon, 18 Sep 2023 11:51:04 +0200 Subject: [PATCH 04/14] rename vars --- src/gateway/GatewayRouterFacet.sol | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 4061009ec..3d5ba15b1 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -188,30 +188,26 @@ contract GatewayRouterFacet is GatewayActorModifiers { } /// @notice checks whether the provided proof-of-finality signature for a block at height `h ` is valid and accumulates it. - /// @param h - height when the signature was created - /// @param pof - proof of finality + /// @param h - height + /// @param pof - proof of finality at height /// @param membership - the membership at height `h` - /// @param signature - added signature + /// @param signature - added signature as a vote for the pof function newSignature( uint256 h, bytes32 pof, Membership calldata membership, bytes calldata signature ) external systemActorOnly { - if (signature.length != 65) { - revert InvalidSignatureLength(); - } - (address signer, ECDSA.RecoverError err, ) = ECDSA.tryRecover(pof, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } - uint256 signersNumber = membership.validators.length; - uint256 signerIndex; + uint256 validatorsNumber = membership.validators.length; + uint256 validatorIndex; bool signerExists; - for (signerIndex = 0; signerIndex < signersNumber; ) { - if (signer == membership.validators[signerIndex].addr.extractEvmAddress().normalize()) { + for (validatorIndex = 0; validatorIndex < validatorsNumber; ) { + if (signer == membership.validators[validatorIndex].addr.extractEvmAddress().normalize()) { s.bottomUpCollectedSignatures[h][pof].push(signature); emit SignaturesUpdated({h: h, pof: pof, membership: membership, signature: signature}); signerExists = true; @@ -219,13 +215,13 @@ contract GatewayRouterFacet is GatewayActorModifiers { } unchecked { - ++signerIndex; + ++validatorIndex; } } if (signerExists) { uint256 threshold = s.bottomUpCollectedSignaturesThreshold[h][pof]; - threshold += membership.validators[signerIndex].weight; + threshold += membership.validators[validatorIndex].weight; if (threshold >= membership.totalWeight) { emit PoFThresholdReached({h: h, pof: pof, membership: membership, threshold: threshold}); From 5df4cf317b6896cc211bc4fc1219031edf56ca78 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Mon, 18 Sep 2023 18:08:01 +0200 Subject: [PATCH 05/14] fix comments --- src/errors/IPCErrors.sol | 2 + src/gateway/GatewayGetterFacet.sol | 3 +- src/gateway/GatewayRouterFacet.sol | 76 +++++++++++++++++------------- src/lib/LibGateway.sol | 3 +- src/lib/LibGatewayActorStorage.sol | 15 +++--- src/structs/Validator.sol | 5 ++ 6 files changed, 61 insertions(+), 43 deletions(-) diff --git a/src/errors/IPCErrors.sol b/src/errors/IPCErrors.sol index 015560040..6abcc8b1d 100644 --- a/src/errors/IPCErrors.sol +++ b/src/errors/IPCErrors.sol @@ -26,6 +26,7 @@ error InvalidMajorityPercentage(); error InvalidSignature(); error InvalidSignatureLength(); error InvalidSubmissionPeriod(); +error InvalidValidatorIndex(); error MessagesNotSorted(); error NoRewardToWithdraw(); error NoValidatorsInSubnet(); @@ -44,6 +45,7 @@ error NotSystemActor(); error NotRegisteredSubnet(); error NotValidator(); error PostboxNotExist(); +error RepliedSignature(); error SubnetAlreadyKilled(); error SubnetNotActive(); error ValidatorAlreadyVoted(); diff --git a/src/gateway/GatewayGetterFacet.sol b/src/gateway/GatewayGetterFacet.sol index 5c7aaffd1..6f868669b 100644 --- a/src/gateway/GatewayGetterFacet.sol +++ b/src/gateway/GatewayGetterFacet.sol @@ -50,8 +50,9 @@ contract GatewayGetterFacet { return s.networkName; } + // TODO: remove or add a new getter function bottomUpCheckpoints(uint64 e) external view returns (BottomUpCheckpoint memory) { - return s.bottomUpCheckpoints[e]; + return s.bottomUpCheckpointsLegacy[e]; } function getParentFinality(uint256 blockNumber) external view returns (ParentFinality memory) { diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 3d5ba15b1..0220f054d 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -9,8 +9,8 @@ import {Status} from "../enums/Status.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; -import {Membership} from "../structs/Validator.sol"; -import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, InvalidSignatureLength} from "../errors/IPCErrors.sol"; +import {Membership, CheckpointThreshold} from "../structs/Validator.sol"; +import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, InvalidValidatorIndex, RepliedSignature} from "../errors/IPCErrors.sol"; import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet} from "../errors/IPCErrors.sol"; import {MessagesNotSorted, NotInitialized, NotEnoughBalance, NotRegisteredSubnet} from "../errors/IPCErrors.sol"; import {NotValidator, SubnetNotActive} from "../errors/IPCErrors.sol"; @@ -33,9 +33,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; - event SignaturesUpdated(uint256 h, bytes32 pof, Membership membership, bytes signature); - event SignatureInvalid(uint256 h, bytes32 pof, Membership membership, bytes signature); - event PoFThresholdReached(uint256 h, bytes32 pof, Membership membership, uint256 threshold); + event CheckpointPassed(uint64 height, bytes32 checkpoint, Membership membership, uint256 threshold); + event CheckpointThresholdUpdated(uint64 height, bytes32 checkpoint, Membership membership, uint256 threshold); /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality @@ -187,47 +186,58 @@ contract GatewayRouterFacet is GatewayActorModifiers { } } - /// @notice checks whether the provided proof-of-finality signature for a block at height `h ` is valid and accumulates it. - /// @param h - height - /// @param pof - proof of finality at height + /// @notice checks whether the provided checkpoint signature for a block at height `h ` is valid and accumulates it. + /// @param height - height + /// @param checkpoint - proof of finality at height /// @param membership - the membership at height `h` + /// @param validatorIndex - the index of the validator in the membership that signed the checkpoint /// @param signature - added signature as a vote for the pof - function newSignature( - uint256 h, - bytes32 pof, + function addCheckpointSignature( + uint64 height, + bytes32 checkpoint, Membership calldata membership, + uint64 validatorIndex, bytes calldata signature ) external systemActorOnly { - (address signer, ECDSA.RecoverError err, ) = ECDSA.tryRecover(pof, signature); + (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpoint, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } - uint256 validatorsNumber = membership.validators.length; - uint256 validatorIndex; - bool signerExists; - for (validatorIndex = 0; validatorIndex < validatorsNumber; ) { - if (signer == membership.validators[validatorIndex].addr.extractEvmAddress().normalize()) { - s.bottomUpCollectedSignatures[h][pof].push(signature); - emit SignaturesUpdated({h: h, pof: pof, membership: membership, signature: signature}); - signerExists = true; - break; - } - - unchecked { - ++validatorIndex; - } + if (s.bottomUpCollectedSignatures[height][signature]) { + revert RepliedSignature(); } - if (signerExists) { - uint256 threshold = s.bottomUpCollectedSignaturesThreshold[h][pof]; - threshold += membership.validators[validatorIndex].weight; + if (validatorIndex >= membership.validators.length) { + revert InvalidValidatorIndex(); + } - if (threshold >= membership.totalWeight) { - emit PoFThresholdReached({h: h, pof: pof, membership: membership, threshold: threshold}); + address validator = membership.validators[validatorIndex].addr.extractEvmAddress().normalize(); + + if (validator == recoveredSignatory) { + s.bottomUpCollectedSignatures[height][signature] = true; + + CheckpointThreshold memory threshold = s.bottomUpCollectedSignaturesThreshold[height]; + threshold.weight += membership.validators[validatorIndex].weight; + + if (threshold.weight >= membership.totalWeight) { + if (!threshold.reached) { + threshold.reached = true; + emit CheckpointPassed({ + height: height, + checkpoint: checkpoint, + membership: membership, + threshold: threshold.weight + }); + } else { + emit CheckpointThresholdUpdated({ + height: height, + checkpoint: checkpoint, + membership: membership, + threshold: threshold.weight + }); + } } - } else { - emit SignatureInvalid({h: h, pof: pof, membership: membership, signature: signature}); } } } diff --git a/src/lib/LibGateway.sol b/src/lib/LibGateway.sol index 4bf203736..6c8203742 100644 --- a/src/lib/LibGateway.sol +++ b/src/lib/LibGateway.sol @@ -27,6 +27,7 @@ library LibGateway { event MembershipReceived(uint64 n, FvmAddress[] validators, uint256[] weights); event MembershipUpdated(uint64 n, Validator[] validators, uint256 totalWeight); + // TODO: remove or add a new getter /// @notice returns the current bottom-up checkpoint /// @return exists - whether the checkpoint exists /// @return epoch - the epoch of the checkpoint @@ -38,7 +39,7 @@ library LibGateway { { GatewayActorStorage storage s = LibGatewayActorStorage.appStorage(); epoch = LibVoting.getNextEpoch(block.number, s.bottomUpCheckPeriod); - checkpoint = s.bottomUpCheckpoints[epoch]; + checkpoint = s.bottomUpCheckpointsLegacy[epoch]; exists = !checkpoint.source.isEmpty(); } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index 8af08f4e4..23bd7259a 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -5,7 +5,7 @@ import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {NotEnoughFee, NotSystemActor} from "../errors/IPCErrors.sol"; import {BottomUpCheckpoint, CrossMsg, ParentFinality} from "../structs/Checkpoint.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; -import {Membership} from "../structs/Validator.sol"; +import {Membership, CheckpointThreshold} from "../structs/Validator.sol"; import {AccountHelper} from "../lib/AccountHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; @@ -24,9 +24,6 @@ struct GatewayActorStorage { /// an actor that need to be propagated further through the hierarchy. /// cross-net message id => CrossMsg mapping(bytes32 => CrossMsg) postbox; - /// @notice BottomUpCheckpoints in the GW per epoch - // slither-disable-next-line uninitialized-state - mapping(uint64 => BottomUpCheckpoint) bottomUpCheckpoints; /// @notice List of validators and how many votes of the total each validator has for top-down messages // configurationNumber => validator fvm address => weight mapping(uint64 => mapping(bytes32 => uint256)) validatorSetWeights; @@ -34,12 +31,14 @@ struct GatewayActorStorage { Membership currentMembership; /// @notice The last membership received from the parent and adopted Membership lastMembership; + mapping(uint64 => BottomUpCheckpoint) bottomUpCheckpointsLegacy; + /// @notice A mapping of block numbers to bottom-up checkpoints (proof of finality) + // slither-disable-next-line uninitialized-state + mapping(uint64 => bytes32) bottomUpCheckpoints; /// @notice The signatures collected for the proof of finality at height `h` - mapping(uint256 => mapping(bytes32 => bytes[])) bottomUpCollectedSignatures; + mapping(uint64 => mapping(bytes => bool)) bottomUpCollectedSignatures; /// @notice The signatures collected for the proof of finality at height `h` - mapping(uint256 => mapping(bytes32 => uint256)) bottomUpCollectedSignaturesThreshold; - /// @notice Bottom-up proof of finality for a block at height `h` - mapping(uint256 => bytes32) bottomUpProofOfFinalities; + mapping(uint64 => CheckpointThreshold) bottomUpCollectedSignaturesThreshold; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] mapping(uint64 => mapping(bytes32 => uint256[2])) children; /// @notice epoch => SubnetID => check => exists diff --git a/src/structs/Validator.sol b/src/structs/Validator.sol index 44f54861d..68eb27f91 100644 --- a/src/structs/Validator.sol +++ b/src/structs/Validator.sol @@ -25,3 +25,8 @@ struct Membership { uint64 configurationNumber; uint256 totalWeight; } + +struct CheckpointThreshold { + uint256 weight; + bool reached; +} From 7f64858a995dc260c2a1d0ab954096f697f3b78c Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Mon, 18 Sep 2023 23:25:24 +0200 Subject: [PATCH 06/14] fix comments --- src/gateway/GatewayRouterFacet.sol | 32 +++++++++++++++--------------- src/lib/LibGatewayActorStorage.sol | 8 ++++---- src/structs/Validator.sol | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 0220f054d..d5c1643e4 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -9,7 +9,7 @@ import {Status} from "../enums/Status.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; -import {Membership, CheckpointThreshold} from "../structs/Validator.sol"; +import {Membership, CheckpointQuorum} from "../structs/Validator.sol"; import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, InvalidValidatorIndex, RepliedSignature} from "../errors/IPCErrors.sol"; import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet} from "../errors/IPCErrors.sol"; import {MessagesNotSorted, NotInitialized, NotEnoughBalance, NotRegisteredSubnet} from "../errors/IPCErrors.sol"; @@ -33,8 +33,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; - event CheckpointPassed(uint64 height, bytes32 checkpoint, Membership membership, uint256 threshold); - event CheckpointThresholdUpdated(uint64 height, bytes32 checkpoint, Membership membership, uint256 threshold); + event QuorumReached(uint64 height, bytes32 checkpoint, Membership membership, uint256 weight); + event QuorumUpdated(uint64 height, bytes32 checkpoint, Membership membership, uint256 weight); /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality @@ -186,12 +186,12 @@ contract GatewayRouterFacet is GatewayActorModifiers { } } - /// @notice checks whether the provided checkpoint signature for a block at height `h ` is valid and accumulates it. - /// @param height - height - /// @param checkpoint - proof of finality at height + /// @notice checks whether the provided checkpoint signature for a block at height `h ` is valid and accumulates that it. + /// @param height - the height of the block in the checkpoint + /// @param checkpoint - the hash of the checkpoint at height `h` /// @param membership - the membership at height `h` /// @param validatorIndex - the index of the validator in the membership that signed the checkpoint - /// @param signature - added signature as a vote for the pof + /// @param signature - the signature of the checkpoint function addCheckpointSignature( uint64 height, bytes32 checkpoint, @@ -217,24 +217,24 @@ contract GatewayRouterFacet is GatewayActorModifiers { if (validator == recoveredSignatory) { s.bottomUpCollectedSignatures[height][signature] = true; - CheckpointThreshold memory threshold = s.bottomUpCollectedSignaturesThreshold[height]; - threshold.weight += membership.validators[validatorIndex].weight; + CheckpointQuorum memory quorum = s.bottomUpCheckpointQuorum[height]; + quorum.weight += membership.validators[validatorIndex].weight; - if (threshold.weight >= membership.totalWeight) { - if (!threshold.reached) { - threshold.reached = true; - emit CheckpointPassed({ + if (quorum.weight >= membership.totalWeight) { + if (!quorum.reached) { + quorum.reached = true; + emit QuorumReached({ height: height, checkpoint: checkpoint, membership: membership, - threshold: threshold.weight + weight: quorum.weight }); } else { - emit CheckpointThresholdUpdated({ + emit QuorumUpdated({ height: height, checkpoint: checkpoint, membership: membership, - threshold: threshold.weight + weight: quorum.weight }); } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index 23bd7259a..24ff29f74 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -5,7 +5,7 @@ import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {NotEnoughFee, NotSystemActor} from "../errors/IPCErrors.sol"; import {BottomUpCheckpoint, CrossMsg, ParentFinality} from "../structs/Checkpoint.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; -import {Membership, CheckpointThreshold} from "../structs/Validator.sol"; +import {Membership, CheckpointQuorum} from "../structs/Validator.sol"; import {AccountHelper} from "../lib/AccountHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; @@ -35,10 +35,10 @@ struct GatewayActorStorage { /// @notice A mapping of block numbers to bottom-up checkpoints (proof of finality) // slither-disable-next-line uninitialized-state mapping(uint64 => bytes32) bottomUpCheckpoints; - /// @notice The signatures collected for the proof of finality at height `h` + /// @notice The signatures collected for checkpoint at height `h` mapping(uint64 => mapping(bytes => bool)) bottomUpCollectedSignatures; - /// @notice The signatures collected for the proof of finality at height `h` - mapping(uint64 => CheckpointThreshold) bottomUpCollectedSignaturesThreshold; + /// @notice The signatures collected for the checkpoint at height `h` + mapping(uint64 => CheckpointQuorum) bottomUpCheckpointQuorum; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] mapping(uint64 => mapping(bytes32 => uint256[2])) children; /// @notice epoch => SubnetID => check => exists diff --git a/src/structs/Validator.sol b/src/structs/Validator.sol index 68eb27f91..fe031af3b 100644 --- a/src/structs/Validator.sol +++ b/src/structs/Validator.sol @@ -26,7 +26,7 @@ struct Membership { uint256 totalWeight; } -struct CheckpointThreshold { +struct CheckpointQuorum { uint256 weight; bool reached; } From ce58204e35ac79fb73196744028dcd4b8462638a Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Tue, 19 Sep 2023 18:03:42 +0200 Subject: [PATCH 07/14] drafting new impl --- src/errors/IPCErrors.sol | 4 +- src/gateway/GatewayRouterFacet.sol | 91 +++++++++++++++++------------- src/lib/LibGatewayActorStorage.sol | 15 +++-- src/structs/Checkpoint.sol | 20 +++++++ src/structs/Validator.sol | 5 ++ 5 files changed, 87 insertions(+), 48 deletions(-) diff --git a/src/errors/IPCErrors.sol b/src/errors/IPCErrors.sol index 6abcc8b1d..dd7c3fe42 100644 --- a/src/errors/IPCErrors.sol +++ b/src/errors/IPCErrors.sol @@ -26,7 +26,7 @@ error InvalidMajorityPercentage(); error InvalidSignature(); error InvalidSignatureLength(); error InvalidSubmissionPeriod(); -error InvalidValidatorIndex(); +error FailedToVerifyValidatorMembership(); error MessagesNotSorted(); error NoRewardToWithdraw(); error NoValidatorsInSubnet(); @@ -45,7 +45,7 @@ error NotSystemActor(); error NotRegisteredSubnet(); error NotValidator(); error PostboxNotExist(); -error RepliedSignature(); +error DuplicateSignature(); error SubnetAlreadyKilled(); error SubnetNotActive(); error ValidatorAlreadyVoted(); diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index d5c1643e4..5ff485965 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -3,14 +3,14 @@ pragma solidity 0.8.19; import {GatewayActorModifiers} from "../lib/LibGatewayActorStorage.sol"; import {EMPTY_HASH, METHOD_SEND} from "../constants/Constants.sol"; -import {CrossMsg, StorableMsg, ParentFinality, BottomUpCheckpoint} from "../structs/Checkpoint.sol"; +import {CrossMsg, StorableMsg, ParentFinality, BottomUpCheckpoint, BottomUpCheckpointNew} from "../structs/Checkpoint.sol"; import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {Status} from "../enums/Status.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; -import {Membership, CheckpointQuorum} from "../structs/Validator.sol"; -import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, InvalidValidatorIndex, RepliedSignature} from "../errors/IPCErrors.sol"; +import {Membership, CheckpointQuorum, CheckpointMembership} from "../structs/Validator.sol"; +import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, FailedToVerifyValidatorMembership, DuplicateSignature} from "../errors/IPCErrors.sol"; import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet} from "../errors/IPCErrors.sol"; import {MessagesNotSorted, NotInitialized, NotEnoughBalance, NotRegisteredSubnet} from "../errors/IPCErrors.sol"; import {NotValidator, SubnetNotActive} from "../errors/IPCErrors.sol"; @@ -24,6 +24,7 @@ import {FvmAddress} from "../structs/FvmAddress.sol"; import {FvmAddressHelper} from "../lib/FvmAddressHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; import {ECDSA} from "openzeppelin-contracts/utils/cryptography/ECDSA.sol"; +import {MerkleProof} from "openzeppelin-contracts/utils/cryptography/MerkleProof.sol"; contract GatewayRouterFacet is GatewayActorModifiers { using FilAddress for address; @@ -33,8 +34,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; - event QuorumReached(uint64 height, bytes32 checkpoint, Membership membership, uint256 weight); - event QuorumUpdated(uint64 height, bytes32 checkpoint, Membership membership, uint256 weight); + event QuorumReached(uint64 height, bytes32 checkpoint, uint256 quorumWeight); + event QuorumWeightUpdated(uint64 height, bytes32 checkpoint, uint256 newWeight); /// @notice commit the ipc parent finality into storage /// @param finality - the parent finality @@ -188,56 +189,66 @@ contract GatewayRouterFacet is GatewayActorModifiers { /// @notice checks whether the provided checkpoint signature for a block at height `h ` is valid and accumulates that it. /// @param height - the height of the block in the checkpoint - /// @param checkpoint - the hash of the checkpoint at height `h` - /// @param membership - the membership at height `h` - /// @param validatorIndex - the index of the validator in the membership that signed the checkpoint + /// @param proof - a Merkle proof that the validator was in the membership at height `h` + /// @param weight - the weight of the validator /// @param signature - the signature of the checkpoint function addCheckpointSignature( uint64 height, - bytes32 checkpoint, - Membership calldata membership, - uint64 validatorIndex, - bytes calldata signature + bytes32[] memory proof, + uint256 weight, + bytes memory signature ) external systemActorOnly { - (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpoint, signature); + BottomUpCheckpointNew memory checkpoint = s.bottomUpCheckpoints[height]; + + CheckpointMembership memory membership = s.bottomUpCheckpointMembership[height]; + + // TODO: do we need a helper here? + bytes32 checkpointHash = keccak256(abi.encode(checkpoint)); + + (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpointHash, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } - if (s.bottomUpCollectedSignatures[height][signature]) { - revert RepliedSignature(); + // Check whether the validator has already sent a valid signature + if (s.bottomUpCollectedSignatures[height][recoveredSignatory]) { + revert DuplicateSignature(); } - if (validatorIndex >= membership.validators.length) { - revert InvalidValidatorIndex(); + bytes32 leaf = keccak256(abi.encode(recoveredSignatory, weight)); + bool valid = MerkleProof.verify({proof: proof, root: membership.rootHash, leaf: leaf}); + if (!valid) { + revert FailedToVerifyValidatorMembership(); } - address validator = membership.validators[validatorIndex].addr.extractEvmAddress().normalize(); + s.bottomUpCollectedSignatures[height][recoveredSignatory] = true; - if (validator == recoveredSignatory) { - s.bottomUpCollectedSignatures[height][signature] = true; + CheckpointQuorum memory quorum = s.bottomUpCheckpointQuorum[height]; + quorum.weight += weight; - CheckpointQuorum memory quorum = s.bottomUpCheckpointQuorum[height]; - quorum.weight += membership.validators[validatorIndex].weight; - - if (quorum.weight >= membership.totalWeight) { - if (!quorum.reached) { - quorum.reached = true; - emit QuorumReached({ - height: height, - checkpoint: checkpoint, - membership: membership, - weight: quorum.weight - }); - } else { - emit QuorumUpdated({ - height: height, - checkpoint: checkpoint, - membership: membership, - weight: quorum.weight - }); - } + if (quorum.weight >= membership.totalWeight) { + if (!quorum.reached) { + quorum.reached = true; + emit QuorumReached({height: height, checkpoint: checkpointHash, quorumWeight: quorum.weight}); + } else { + emit QuorumWeightUpdated({height: height, checkpoint: checkpointHash, newWeight: quorum.weight}); } } } + + /// @notice creates a new bottom-up checkpoint + /// @param checkpoint - a bottom-up checkpoint + /// @param membershipRootHash - a root hash of the Merkle tree built from the validator public keys and their weight + /// @param totalWeight - the total weight of the membership + function createBottomUpCheckpoint( + BottomUpCheckpointNew calldata checkpoint, + bytes32 membershipRootHash, + uint256 totalWeight + ) external systemActorOnly { + s.bottomUpCheckpoints[checkpoint.blockHeight] = checkpoint; + s.bottomUpCheckpointMembership[checkpoint.blockHeight] = CheckpointMembership({ + rootHash: membershipRootHash, + totalWeight: totalWeight + }); + } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index 24ff29f74..28a74f279 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.19; import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {NotEnoughFee, NotSystemActor} from "../errors/IPCErrors.sol"; -import {BottomUpCheckpoint, CrossMsg, ParentFinality} from "../structs/Checkpoint.sol"; +import {BottomUpCheckpoint, BottomUpCheckpointNew, CrossMsg, ParentFinality} from "../structs/Checkpoint.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; -import {Membership, CheckpointQuorum} from "../structs/Validator.sol"; +import {Membership, CheckpointQuorum, CheckpointMembership} from "../structs/Validator.sol"; import {AccountHelper} from "../lib/AccountHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; @@ -32,11 +32,14 @@ struct GatewayActorStorage { /// @notice The last membership received from the parent and adopted Membership lastMembership; mapping(uint64 => BottomUpCheckpoint) bottomUpCheckpointsLegacy; - /// @notice A mapping of block numbers to bottom-up checkpoints (proof of finality) + /// @notice A mapping of block numbers to bottom-up checkpoints // slither-disable-next-line uninitialized-state - mapping(uint64 => bytes32) bottomUpCheckpoints; - /// @notice The signatures collected for checkpoint at height `h` - mapping(uint64 => mapping(bytes => bool)) bottomUpCollectedSignatures; + mapping(uint64 => BottomUpCheckpointNew) bottomUpCheckpoints; + /// @notice A mapping of block numbers to bottom-up checkpoint membership data + // slither-disable-next-line uninitialized-state + mapping(uint64 => CheckpointMembership) bottomUpCheckpointMembership; + /// @notice The validators have already sent signatures at height `h` + mapping(uint64 => mapping(address => bool)) bottomUpCollectedSignatures; /// @notice The signatures collected for the checkpoint at height `h` mapping(uint64 => CheckpointQuorum) bottomUpCheckpointQuorum; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] diff --git a/src/structs/Checkpoint.sol b/src/structs/Checkpoint.sol index bfa7b8fb5..943e95354 100644 --- a/src/structs/Checkpoint.sol +++ b/src/structs/Checkpoint.sol @@ -21,6 +21,26 @@ struct BottomUpCheckpoint { bytes proof; } +/// @notice A bottom-up checkpoint struct. +// TODO: Remove old BottomUpCheckpoint and update all the codebase. +struct BottomUpCheckpointNew { + /// @dev Child subnet ID, for replay protection from other subnets where the exact same validators operate. + /// Alternatively it can be appended to the hash before signing, similar to how we use the chain ID. + SubnetID subnetID; + /// @dev The height of the child subnet at which this checkpoint was cut. + /// Has to follow the previous checkpoint by bottom_up_checkpoint_period + uint64 blockHeight; + /// @dev The ID of the validator set which is going to sign the next checkpoint. + /// This one expected to be signed by the ID reported in the previous checkpoint. + /// 0 could mean "no change". + uint64 nextConfigurationNumber; + /// @dev Some kind of hash over the bottom-up messages. + /// By not including cross messages here directly, we can be compatible with IPLD Resolver based + /// approach where the messages are fetched with Bitswap and provided by Fendermint, or the full-fat + /// approach we need with Lotus, where the messages are part of the relayed transaction. + bytes32 crossMessagesHash; +} + struct TopDownCheckpoint { uint64 epoch; CrossMsg[] topDownMsgs; diff --git a/src/structs/Validator.sol b/src/structs/Validator.sol index fe031af3b..48184e2c8 100644 --- a/src/structs/Validator.sol +++ b/src/structs/Validator.sol @@ -26,6 +26,11 @@ struct Membership { uint256 totalWeight; } +struct CheckpointMembership { + bytes32 rootHash; + uint256 totalWeight; +} + struct CheckpointQuorum { uint256 weight; bool reached; From f232eb11c7cfe39020b82def8fa9a3cd05f61d38 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Tue, 19 Sep 2023 22:18:46 +0200 Subject: [PATCH 08/14] fix comments --- src/GatewayDiamond.sol | 5 ++ src/errors/IPCErrors.sol | 9 ++- src/gateway/GatewayRouterFacet.sol | 91 ++++++++++++++++++++---------- src/lib/CheckpointHelper.sol | 6 +- src/lib/LibGateway.sol | 6 ++ src/lib/LibGatewayActorStorage.sol | 12 ++-- src/structs/Checkpoint.sol | 25 ++++++-- src/structs/Validator.sol | 10 ---- 8 files changed, 110 insertions(+), 54 deletions(-) diff --git a/src/GatewayDiamond.sol b/src/GatewayDiamond.sol index 976c5a61a..acc6b4b27 100644 --- a/src/GatewayDiamond.sol +++ b/src/GatewayDiamond.sol @@ -36,6 +36,10 @@ contract GatewayDiamond { revert InvalidSubmissionPeriod(); } + if (params.majorityPercentage > 100) { + revert InvalidMajorityPercentage(); + } + LibDiamond.setContractOwner(msg.sender); LibDiamond.diamondCut({_diamondCut: _diamondCut, _init: address(0), _calldata: new bytes(0)}); @@ -44,6 +48,7 @@ contract GatewayDiamond { s.bottomUpCheckPeriod = params.bottomUpCheckPeriod; s.topDownCheckPeriod = params.topDownCheckPeriod; s.crossMsgFee = params.msgFee; + s.majorityPercentage = params.majorityPercentage; // the root doesn't need to be explicitly initialized if (s.networkName.isRoot()) { diff --git a/src/errors/IPCErrors.sol b/src/errors/IPCErrors.sol index dd7c3fe42..afd4fd11d 100644 --- a/src/errors/IPCErrors.sol +++ b/src/errors/IPCErrors.sol @@ -6,6 +6,8 @@ error AlreadyRegisteredSubnet(); error CallerHasNoStake(); error CannotReleaseZero(); error CannotSendCrossMsgToItself(); +error CheckpointAlreadyExists(); +error CheckpointInfoAlreadyExists(); error CheckpointNotChained(); error CollateralIsZero(); error CollateralStillLockedInSubnet(); @@ -15,6 +17,8 @@ error EpochNotVotable(); error GatewayCannotBeZero(); error InconsistentPrevCheckpoint(); error InvalidActorAddress(); +error CheckpointNotCreated(); +error CheckpointMembershipNotCreated(); error InvalidCheckpointEpoch(); error InvalidCheckpointSource(); error OldConfigurationNumber(); @@ -26,11 +30,11 @@ error InvalidMajorityPercentage(); error InvalidSignature(); error InvalidSignatureLength(); error InvalidSubmissionPeriod(); -error FailedToVerifyValidatorMembership(); error MessagesNotSorted(); error NoRewardToWithdraw(); error NoValidatorsInSubnet(); error NotEnoughValidatorsInSubnet(); +error NotAuthorized(address); error NotAllValidatorsHaveLeft(); error NotEmptySubnetCircSupply(); error NotEnoughBalance(); @@ -45,7 +49,7 @@ error NotSystemActor(); error NotRegisteredSubnet(); error NotValidator(); error PostboxNotExist(); -error DuplicateSignature(); +error SignatureReplay(); error SubnetAlreadyKilled(); error SubnetNotActive(); error ValidatorAlreadyVoted(); @@ -55,3 +59,4 @@ error WorkerAddressInvalid(); error WrongCheckpointSource(); error ParentFinalityAlreadyCommitted(); error InvalidCrossMsgValue(); +error ZeroMembershipWeight(); diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 5ff485965..be59f6eb8 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -3,17 +3,17 @@ pragma solidity 0.8.19; import {GatewayActorModifiers} from "../lib/LibGatewayActorStorage.sol"; import {EMPTY_HASH, METHOD_SEND} from "../constants/Constants.sol"; -import {CrossMsg, StorableMsg, ParentFinality, BottomUpCheckpoint, BottomUpCheckpointNew} from "../structs/Checkpoint.sol"; +import {CrossMsg, StorableMsg, ParentFinality, BottomUpCheckpoint, BottomUpCheckpointNew, CheckpointInfo} from "../structs/Checkpoint.sol"; import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {Status} from "../enums/Status.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; import {IPCMsgType} from "../enums/IPCMsgType.sol"; -import {Membership, CheckpointQuorum, CheckpointMembership} from "../structs/Validator.sol"; -import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, FailedToVerifyValidatorMembership, DuplicateSignature} from "../errors/IPCErrors.sol"; -import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet} from "../errors/IPCErrors.sol"; +import {Membership} from "../structs/Validator.sol"; +import {InconsistentPrevCheckpoint, NotEnoughSubnetCircSupply, InvalidCheckpointEpoch, InvalidSignature, NotAuthorized, SignatureReplay} from "../errors/IPCErrors.sol"; +import {InvalidCheckpointSource, InvalidCrossMsgNonce, InvalidCrossMsgDstSubnet, CheckpointAlreadyExists, CheckpointInfoAlreadyExists} from "../errors/IPCErrors.sol"; import {MessagesNotSorted, NotInitialized, NotEnoughBalance, NotRegisteredSubnet} from "../errors/IPCErrors.sol"; -import {NotValidator, SubnetNotActive} from "../errors/IPCErrors.sol"; +import {NotValidator, SubnetNotActive, CheckpointNotCreated, CheckpointMembershipNotCreated, ZeroMembershipWeight} from "../errors/IPCErrors.sol"; import {SubnetIDHelper} from "../lib/SubnetIDHelper.sol"; import {CheckpointHelper} from "../lib/CheckpointHelper.sol"; import {LibVoting} from "../lib/LibVoting.sol"; @@ -30,6 +30,7 @@ contract GatewayRouterFacet is GatewayActorModifiers { using FilAddress for address; using SubnetIDHelper for SubnetID; using CheckpointHelper for BottomUpCheckpoint; + using CheckpointHelper for BottomUpCheckpointNew; using CrossMsgHelper for CrossMsg; using FvmAddressHelper for FvmAddress; using StorableMsgHelper for StorableMsg; @@ -189,49 +190,65 @@ contract GatewayRouterFacet is GatewayActorModifiers { /// @notice checks whether the provided checkpoint signature for a block at height `h ` is valid and accumulates that it. /// @param height - the height of the block in the checkpoint - /// @param proof - a Merkle proof that the validator was in the membership at height `h` + /// @param membershipProof - a Merkle proof that the validator was in the membership at height `h` /// @param weight - the weight of the validator /// @param signature - the signature of the checkpoint function addCheckpointSignature( uint64 height, - bytes32[] memory proof, + bytes32[] memory membershipProof, uint256 weight, bytes memory signature - ) external systemActorOnly { + ) external { BottomUpCheckpointNew memory checkpoint = s.bottomUpCheckpoints[height]; + if (checkpoint.blockHeight == 0) { + revert CheckpointNotCreated(); + } - CheckpointMembership memory membership = s.bottomUpCheckpointMembership[height]; + CheckpointInfo memory checkpointInfo = s.bottomUpCheckpointInfo[height]; + if (checkpointInfo.rootHash.length == 0) { + revert CheckpointMembershipNotCreated(); + } - // TODO: do we need a helper here? - bytes32 checkpointHash = keccak256(abi.encode(checkpoint)); + bytes32 checkpointHash = checkpoint.toHash(); - (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpointHash, signature); + // slither-disable-next-line unused-return + (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpointInfo.hash, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } // Check whether the validator has already sent a valid signature if (s.bottomUpCollectedSignatures[height][recoveredSignatory]) { - revert DuplicateSignature(); + revert SignatureReplay(); } - bytes32 leaf = keccak256(abi.encode(recoveredSignatory, weight)); - bool valid = MerkleProof.verify({proof: proof, root: membership.rootHash, leaf: leaf}); + // The validator is allowed to send a signature if it was in the membership at the target height + bytes32 validatorLeaf = keccak256(abi.encode(recoveredSignatory, weight)); + bool valid = MerkleProof.verify({proof: membershipProof, root: checkpointInfo.rootHash, leaf: validatorLeaf}); if (!valid) { - revert FailedToVerifyValidatorMembership(); + revert NotAuthorized(recoveredSignatory); } - s.bottomUpCollectedSignatures[height][recoveredSignatory] = true; - - CheckpointQuorum memory quorum = s.bottomUpCheckpointQuorum[height]; - quorum.weight += weight; + // All checks passed. + // Adding signature and emitting events. - if (quorum.weight >= membership.totalWeight) { - if (!quorum.reached) { - quorum.reached = true; - emit QuorumReached({height: height, checkpoint: checkpointHash, quorumWeight: quorum.weight}); + s.bottomUpCollectedSignatures[height][recoveredSignatory] = true; + checkpointInfo.currentWeight += weight; + + if (checkpointInfo.currentWeight >= checkpointInfo.threshold) { + if (!checkpointInfo.reached) { + checkpointInfo.reached = true; + emit QuorumReached({ + height: height, + checkpoint: checkpointHash, + quorumWeight: checkpointInfo.currentWeight + }); } else { - emit QuorumWeightUpdated({height: height, checkpoint: checkpointHash, newWeight: quorum.weight}); + emit QuorumWeightUpdated({ + height: height, + checkpoint: checkpointHash, + newWeight: checkpointInfo.currentWeight + }); } } } @@ -239,16 +256,32 @@ contract GatewayRouterFacet is GatewayActorModifiers { /// @notice creates a new bottom-up checkpoint /// @param checkpoint - a bottom-up checkpoint /// @param membershipRootHash - a root hash of the Merkle tree built from the validator public keys and their weight - /// @param totalWeight - the total weight of the membership + /// @param membershipWeight - the total weight of the membership function createBottomUpCheckpoint( BottomUpCheckpointNew calldata checkpoint, bytes32 membershipRootHash, - uint256 totalWeight + uint256 membershipWeight ) external systemActorOnly { + if (s.bottomUpCheckpoints[checkpoint.blockHeight].blockHeight > 0) { + revert CheckpointAlreadyExists(); + } + if (s.bottomUpCheckpointInfo[checkpoint.blockHeight].rootHash.length > 0) { + revert CheckpointInfoAlreadyExists(); + } + if (membershipWeight == 0) { + revert ZeroMembershipWeight(); + } + + uint256 threshold = LibGateway.getThreshold(membershipWeight); + s.bottomUpCheckpoints[checkpoint.blockHeight] = checkpoint; - s.bottomUpCheckpointMembership[checkpoint.blockHeight] = CheckpointMembership({ + + s.bottomUpCheckpointInfo[checkpoint.blockHeight] = CheckpointInfo({ + hash: checkpoint.toHash(), rootHash: membershipRootHash, - totalWeight: totalWeight + threshold: threshold, + currentWeight: 0, + reached: false }); } } diff --git a/src/lib/CheckpointHelper.sol b/src/lib/CheckpointHelper.sol index 22adfb4b4..a3909d44b 100644 --- a/src/lib/CheckpointHelper.sol +++ b/src/lib/CheckpointHelper.sol @@ -4,7 +4,7 @@ pragma solidity 0.8.19; import {EMPTY_HASH} from "../constants/Constants.sol"; import {SubnetID} from "../structs/Subnet.sol"; import {SubnetIDHelper} from "../lib/SubnetIDHelper.sol"; -import {BottomUpCheckpoint, TopDownCheckpoint, CrossMsg, ChildCheck} from "../structs/Checkpoint.sol"; +import {BottomUpCheckpoint, BottomUpCheckpointNew, TopDownCheckpoint, CrossMsg, ChildCheck} from "../structs/Checkpoint.sol"; /// @title Helper library for manipulating Checkpoint struct /// @author LimeChain team @@ -33,6 +33,10 @@ library CheckpointHelper { return keccak256(abi.encode(bottomupCheckpoint)); } + function toHash(BottomUpCheckpointNew memory bottomupCheckpoint) public pure returns (bytes32) { + return keccak256(abi.encode(bottomupCheckpoint)); + } + function toHash(TopDownCheckpoint memory topdownCheckpoint) public pure returns (bytes32) { return keccak256(abi.encode(topdownCheckpoint)); } diff --git a/src/lib/LibGateway.sol b/src/lib/LibGateway.sol index 6c8203742..16e8000f9 100644 --- a/src/lib/LibGateway.sol +++ b/src/lib/LibGateway.sol @@ -245,4 +245,10 @@ library LibGateway { subnet = s.subnets[subnetId.toHash()]; found = !subnet.id.isEmpty(); } + + /// @notice returns the threshold corresponding to the majority percentage + function getThreshold(uint256 weight) internal view returns (uint256) { + GatewayActorStorage storage s = LibGatewayActorStorage.appStorage(); + return (weight * s.majorityPercentage) / 100; + } } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index 28a74f279..d9d4ebebd 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -3,9 +3,9 @@ pragma solidity 0.8.19; import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {NotEnoughFee, NotSystemActor} from "../errors/IPCErrors.sol"; -import {BottomUpCheckpoint, BottomUpCheckpointNew, CrossMsg, ParentFinality} from "../structs/Checkpoint.sol"; +import {BottomUpCheckpoint, BottomUpCheckpointNew, CrossMsg, ParentFinality, CheckpointInfo} from "../structs/Checkpoint.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; -import {Membership, CheckpointQuorum, CheckpointMembership} from "../structs/Validator.sol"; +import {Membership} from "../structs/Validator.sol"; import {AccountHelper} from "../lib/AccountHelper.sol"; import {FilAddress} from "fevmate/utils/FilAddress.sol"; @@ -35,13 +35,11 @@ struct GatewayActorStorage { /// @notice A mapping of block numbers to bottom-up checkpoints // slither-disable-next-line uninitialized-state mapping(uint64 => BottomUpCheckpointNew) bottomUpCheckpoints; - /// @notice A mapping of block numbers to bottom-up checkpoint membership data + /// @notice A mapping of block numbers to checkpoint data // slither-disable-next-line uninitialized-state - mapping(uint64 => CheckpointMembership) bottomUpCheckpointMembership; + mapping(uint64 => CheckpointInfo) bottomUpCheckpointInfo; /// @notice The validators have already sent signatures at height `h` mapping(uint64 => mapping(address => bool)) bottomUpCollectedSignatures; - /// @notice The signatures collected for the checkpoint at height `h` - mapping(uint64 => CheckpointQuorum) bottomUpCheckpointQuorum; /// @notice epoch => SubnetID => [childIndex, exists(0 - no, 1 - yes)] mapping(uint64 => mapping(bytes32 => uint256[2])) children; /// @notice epoch => SubnetID => check => exists @@ -57,6 +55,8 @@ struct GatewayActorStorage { uint256 minStake; /// @notice fee amount charged per cross message uint256 crossMsgFee; + /// @notice majority percentage value + uint8 majorityPercentage; /// @notice nonce for bottom-up messages uint64 bottomUpNonce; /// @notice AppliedNonces keep track of the next nonce of the message to be applied. diff --git a/src/structs/Checkpoint.sol b/src/structs/Checkpoint.sol index 943e95354..e9855cd0c 100644 --- a/src/structs/Checkpoint.sol +++ b/src/structs/Checkpoint.sol @@ -21,26 +21,39 @@ struct BottomUpCheckpoint { bytes proof; } -/// @notice A bottom-up checkpoint struct. -// TODO: Remove old BottomUpCheckpoint and update all the codebase. +/// @notice A bottom-up checkpoint type. +// TODO: Remove old BottomUpCheckpoint, rename BottomUpCheckpointNew to BottomUpCheckpoint and update the codebase. struct BottomUpCheckpointNew { /// @dev Child subnet ID, for replay protection from other subnets where the exact same validators operate. /// Alternatively it can be appended to the hash before signing, similar to how we use the chain ID. SubnetID subnetID; /// @dev The height of the child subnet at which this checkpoint was cut. - /// Has to follow the previous checkpoint by bottom_up_checkpoint_period + /// Has to follow the previous checkpoint by checkpoint period. uint64 blockHeight; - /// @dev The ID of the validator set which is going to sign the next checkpoint. - /// This one expected to be signed by the ID reported in the previous checkpoint. + /// @dev The number of the membership (validator set) which is going to sign the next checkpoint. + /// This one expected to be signed by the validators from the membership reported in the previous checkpoint. /// 0 could mean "no change". uint64 nextConfigurationNumber; - /// @dev Some kind of hash over the bottom-up messages. + /// @dev Hash over the bottom-up messages. /// By not including cross messages here directly, we can be compatible with IPLD Resolver based /// approach where the messages are fetched with Bitswap and provided by Fendermint, or the full-fat /// approach we need with Lotus, where the messages are part of the relayed transaction. bytes32 crossMessagesHash; } +struct CheckpointInfo { + /// @dev The hash of the corresponding bottom-up checkpoint. + bytes32 hash; + /// @dev The root hash of the Merkle tree built from the validator public keys and their weight. + bytes32 rootHash; + /// @dev The target weight that must be reached to accept the checkpoint. + uint256 threshold; + /// @dev The current weight of the checkpoint. + uint256 currentWeight; + /// @dev Whether the quorum has already been reached. + bool reached; +} + struct TopDownCheckpoint { uint64 epoch; CrossMsg[] topDownMsgs; diff --git a/src/structs/Validator.sol b/src/structs/Validator.sol index 48184e2c8..44f54861d 100644 --- a/src/structs/Validator.sol +++ b/src/structs/Validator.sol @@ -25,13 +25,3 @@ struct Membership { uint64 configurationNumber; uint256 totalWeight; } - -struct CheckpointMembership { - bytes32 rootHash; - uint256 totalWeight; -} - -struct CheckpointQuorum { - uint256 weight; - bool reached; -} From f9402ae28b0b0c8930c210a0c5f13590d898aec6 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Wed, 20 Sep 2023 10:58:59 +0200 Subject: [PATCH 09/14] use stored hash --- src/gateway/GatewayRouterFacet.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index be59f6eb8..44dc84210 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -209,10 +209,10 @@ contract GatewayRouterFacet is GatewayActorModifiers { revert CheckpointMembershipNotCreated(); } - bytes32 checkpointHash = checkpoint.toHash(); + bytes32 checkpointHash = checkpointInfo.hash; // slither-disable-next-line unused-return - (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpointInfo.hash, signature); + (address recoveredSignatory, ECDSA.RecoverError err, ) = ECDSA.tryRecover(checkpointHash, signature); if (err != ECDSA.RecoverError.NoError) { revert InvalidSignature(); } From c788bef0281af4a038a3b5cc2d91249d5d2b6daf Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Wed, 20 Sep 2023 13:34:49 +0200 Subject: [PATCH 10/14] fix proof validation and storage type --- src/gateway/GatewayRouterFacet.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index 44dc84210..ee9a42f55 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -204,7 +204,7 @@ contract GatewayRouterFacet is GatewayActorModifiers { revert CheckpointNotCreated(); } - CheckpointInfo memory checkpointInfo = s.bottomUpCheckpointInfo[height]; + CheckpointInfo storage checkpointInfo = s.bottomUpCheckpointInfo[height]; if (checkpointInfo.rootHash.length == 0) { revert CheckpointMembershipNotCreated(); } @@ -223,7 +223,8 @@ contract GatewayRouterFacet is GatewayActorModifiers { } // The validator is allowed to send a signature if it was in the membership at the target height - bytes32 validatorLeaf = keccak256(abi.encode(recoveredSignatory, weight)); + // Constructing leaf: https://github.com/OpenZeppelin/merkle-tree#leaf-hash + bytes32 validatorLeaf = keccak256(bytes.concat(keccak256(abi.encode(recoveredSignatory, weight)))); bool valid = MerkleProof.verify({proof: membershipProof, root: checkpointInfo.rootHash, leaf: validatorLeaf}); if (!valid) { revert NotAuthorized(recoveredSignatory); From e3a390a6e4991cb0d912eb0af601839e6708d8fc Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Wed, 20 Sep 2023 16:42:38 +0200 Subject: [PATCH 11/14] interface test --- .gitmodules | 5 ++++- lib/murky | 1 + remappings.json | 3 ++- remappings.txt | 3 ++- test/MerkleTree.t.sol | 41 +++++++++++++++++++++++++++++++++++++++ test/MerkleTreeHelper.sol | 32 ++++++++++++++++++++++++++++++ 6 files changed, 82 insertions(+), 3 deletions(-) create mode 160000 lib/murky create mode 100644 test/MerkleTree.t.sol create mode 100644 test/MerkleTreeHelper.sol diff --git a/.gitmodules b/.gitmodules index 03bf37566..6ef00ad02 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,7 @@ url = https://github.com/OpenZeppelin/openzeppelin-contracts [submodule "lib/fevmate"] path = lib/fevmate - url = https://github.com/wadealexc/fevmate \ No newline at end of file + url = https://github.com/wadealexc/fevmate +[submodule "lib/murky"] + path = lib/murky + url = https://github.com/dmfxyz/murky diff --git a/lib/murky b/lib/murky new file mode 160000 index 000000000..40de6e801 --- /dev/null +++ b/lib/murky @@ -0,0 +1 @@ +Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 diff --git a/remappings.json b/remappings.json index 7c19ff7ed..a272a21b9 100644 --- a/remappings.json +++ b/remappings.json @@ -3,6 +3,7 @@ "ds-test/=lib/forge-std/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", - "fevmate=lib/fevmate/contracts" + "fevmate=lib/fevmate/contracts", + "murky/=lib/murky/src" ] } diff --git a/remappings.txt b/remappings.txt index 120902a5b..5ff00f737 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,4 +1,5 @@ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/ -fevmate=lib/fevmate/contracts \ No newline at end of file +fevmate=lib/fevmate/contracts +murky/=lib/murky/src \ No newline at end of file diff --git a/test/MerkleTree.t.sol b/test/MerkleTree.t.sol new file mode 100644 index 000000000..80bb34a13 --- /dev/null +++ b/test/MerkleTree.t.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.19; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import {MerkleTreeHelper} from "./MerkleTreeHelper.sol"; +import {MerkleProof} from "openzeppelin-contracts/utils/cryptography/MerkleProof.sol"; +import {Merkle} from "murky/Merkle.sol"; + +contract MerkleTree is Test { + Merkle merkleTree; + + function test_merkle_proofInterface() public { + merkleTree = new Merkle(); + + address[] memory addrs = new address[](4); + addrs[0] = vm.addr(1939); + addrs[1] = vm.addr(1101); + addrs[2] = vm.addr(4323); + addrs[3] = vm.addr(3431); + + uint256[] memory weights = new uint256[](4); + weights[0] = 234; + weights[1] = 14; + weights[2] = 24; + weights[3] = 433; + + (bytes32 root, bytes32[][] memory proofs) = MerkleTreeHelper.createMerkleProofsForValidators(addrs, weights); + + bool valid; + bytes32 leaf; + + leaf = keccak256(bytes.concat(keccak256(abi.encode(addrs[0], weights[0])))); + valid = MerkleProof.verify({proof: proofs[0], root: root, leaf: leaf}); + require(valid, "the valid leaf in the tree"); + + leaf = keccak256(bytes.concat(keccak256(abi.encode(addrs[0], weights[1])))); + valid = MerkleProof.verify({proof: proofs[0], root: root, leaf: leaf}); + require(!valid, "invalid leaf is not in the tree"); + } +} \ No newline at end of file diff --git a/test/MerkleTreeHelper.sol b/test/MerkleTreeHelper.sol new file mode 100644 index 000000000..0738e51cb --- /dev/null +++ b/test/MerkleTreeHelper.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity 0.8.19; + +import { Merkle } from "murky/Merkle.sol"; + +library MerkleTreeHelper { + + function createMerkleProofsForValidators(address[] memory addrs, uint256[] memory weight) internal returns (bytes32, bytes32[][] memory) { + Merkle merkleTree = new Merkle(); + + if (addrs.length != weight.length) { + revert("different array lengths"); + } + uint256 len = addrs.length; + + bytes32 root; + bytes32[][] memory proofs = new bytes32[][](len); + bytes32[] memory data = new bytes32[](len); + for (uint256 i = 0; i < len; i++) { + data[i] = keccak256(bytes.concat(keccak256(abi.encode(addrs[i], weight[i])))); + } + + root = merkleTree.getRoot(data); + // get proof + for (uint256 i = 0; i < len; i++) { + bytes32[] memory proof = merkleTree.getProof(data, i); + proofs[i] = proof; + } + + return (root, proofs); + } +} \ No newline at end of file From f7ed69200b319b5e1844e86672acefb803f85fb9 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Wed, 20 Sep 2023 18:06:24 +0200 Subject: [PATCH 12/14] tests --- .storage-layouts/GatewayActorModifiers.json | 463 +++++++++++++------- .storage-layouts/GatewayDiamond.json | 463 +++++++++++++------- .storage-layouts/SubnetActorDiamond.json | 202 ++++----- .storage-layouts/SubnetActorModifiers.json | 202 ++++----- src/gateway/GatewayGetterFacet.sol | 12 +- src/gateway/GatewayRouterFacet.sol | 2 +- test/GatewayDiamond.t.sol | 105 ++++- test/MerkleTree.t.sol | 2 +- test/MerkleTreeHelper.sol | 10 +- 9 files changed, 927 insertions(+), 534 deletions(-) diff --git a/.storage-layouts/GatewayActorModifiers.json b/.storage-layouts/GatewayActorModifiers.json index d570caac9..7e9ff256d 100644 --- a/.storage-layouts/GatewayActorModifiers.json +++ b/.storage-layouts/GatewayActorModifiers.json @@ -1,12 +1,12 @@ { "storage": [ { - "astId": 8498, + "astId": 10016, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "s", "offset": 0, "slot": "0", - "type": "t_struct(GatewayActorStorage)8486_storage" + "type": "t_struct(GatewayActorStorage)10004_storage" } ], "types": { @@ -27,20 +27,20 @@ "label": "bytes32[]", "numberOfBytes": "32" }, - "t_array(t_struct(ChildCheck)10149_storage)dyn_storage": { - "base": "t_struct(ChildCheck)10149_storage", + "t_array(t_struct(ChildCheck)11697_storage)dyn_storage": { + "base": "t_struct(ChildCheck)11697_storage", "encoding": "dynamic_array", "label": "struct ChildCheck[]", "numberOfBytes": "32" }, - "t_array(t_struct(CrossMsg)10155_storage)dyn_storage": { - "base": "t_struct(CrossMsg)10155_storage", + "t_array(t_struct(CrossMsg)11703_storage)dyn_storage": { + "base": "t_struct(CrossMsg)11703_storage", "encoding": "dynamic_array", "label": "struct CrossMsg[]", "numberOfBytes": "32" }, - "t_array(t_struct(Validator)10314_storage)dyn_storage": { - "base": "t_struct(Validator)10314_storage", + "t_array(t_struct(Validator)11862_storage)dyn_storage": { + "base": "t_struct(Validator)11862_storage", "encoding": "dynamic_array", "label": "struct Validator[]", "numberOfBytes": "32" @@ -71,7 +71,7 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_enum(Status)4025": { + "t_enum(Status)4994": { "encoding": "inplace", "label": "enum Status", "numberOfBytes": "1" @@ -104,33 +104,33 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_bool)" }, - "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage))": { + "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage))": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => mapping(uint256 => struct CrossMsg[]))", "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage)" + "value": "t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage)" }, - "t_mapping(t_bytes32,t_struct(CrossMsg)10155_storage)": { + "t_mapping(t_bytes32,t_struct(CrossMsg)11703_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct CrossMsg)", "numberOfBytes": "32", - "value": "t_struct(CrossMsg)10155_storage" + "value": "t_struct(CrossMsg)11703_storage" }, - "t_mapping(t_bytes32,t_struct(Subnet)10280_storage)": { + "t_mapping(t_bytes32,t_struct(Subnet)11828_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Subnet)", "numberOfBytes": "32", - "value": "t_struct(Subnet)10280_storage" + "value": "t_struct(Subnet)11828_storage" }, - "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)10142_storage)": { + "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)11690_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct TopDownCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(TopDownCheckpoint)10142_storage" + "value": "t_struct(TopDownCheckpoint)11690_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -139,12 +139,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage)": { + "t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct CrossMsg[])", "numberOfBytes": "32", - "value": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "value": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, "t_mapping(t_uint256,t_mapping(t_address,t_bool))": { "encoding": "mapping", @@ -160,12 +160,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint256,t_struct(ParentFinality)10115_storage)": { + "t_mapping(t_uint256,t_struct(ParentFinality)11633_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct ParentFinality)", "numberOfBytes": "32", - "value": "t_struct(ParentFinality)10115_storage" + "value": "t_struct(ParentFinality)11633_storage" + }, + "t_mapping(t_uint64,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" }, "t_mapping(t_uint64,t_mapping(t_bytes32,t_array(t_uint256)2_storage))": { "encoding": "mapping", @@ -188,34 +195,48 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" + }, + "t_mapping(t_uint64,t_struct(BottomUpCheckpointNew)11667_storage)": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => struct BottomUpCheckpointNew)", + "numberOfBytes": "32", + "value": "t_struct(BottomUpCheckpointNew)11667_storage" }, - "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)10203_storage)": { + "t_mapping(t_uint64,t_struct(CheckpointInfo)11683_storage)": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => struct CheckpointInfo)", + "numberOfBytes": "32", + "value": "t_struct(CheckpointInfo)11683_storage" + }, + "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)11751_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct EpochVoteTopDownSubmission)", "numberOfBytes": "32", - "value": "t_struct(EpochVoteTopDownSubmission)10203_storage" + "value": "t_struct(EpochVoteTopDownSubmission)11751_storage" }, - "t_struct(BottomUpCheckpoint)10135_storage": { + "t_struct(BottomUpCheckpoint)11653_storage": { "encoding": "inplace", "label": "struct BottomUpCheckpoint", "members": [ { - "astId": 10118, + "astId": 11636, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10120, + "astId": 11638, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "epoch", "offset": 0, @@ -223,7 +244,7 @@ "type": "t_uint64" }, { - "astId": 10122, + "astId": 11640, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "fee", "offset": 0, @@ -231,23 +252,23 @@ "type": "t_uint256" }, { - "astId": 10126, + "astId": 11644, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "crossMsgs", "offset": 0, "slot": "4", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, { - "astId": 10130, + "astId": 11648, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "children", "offset": 0, "slot": "5", - "type": "t_array(t_struct(ChildCheck)10149_storage)dyn_storage" + "type": "t_array(t_struct(ChildCheck)11697_storage)dyn_storage" }, { - "astId": 10132, + "astId": 11650, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "prevHash", "offset": 0, @@ -255,7 +276,7 @@ "type": "t_bytes32" }, { - "astId": 10134, + "astId": 11652, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "proof", "offset": 0, @@ -265,20 +286,106 @@ ], "numberOfBytes": "256" }, - "t_struct(ChildCheck)10149_storage": { + "t_struct(BottomUpCheckpointNew)11667_storage": { + "encoding": "inplace", + "label": "struct BottomUpCheckpointNew", + "members": [ + { + "astId": 11657, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "subnetID", + "offset": 0, + "slot": "0", + "type": "t_struct(SubnetID)11808_storage" + }, + { + "astId": 11660, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "blockHeight", + "offset": 0, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 11663, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "nextConfigurationNumber", + "offset": 8, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 11666, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "crossMessagesHash", + "offset": 0, + "slot": "3", + "type": "t_bytes32" + } + ], + "numberOfBytes": "128" + }, + "t_struct(CheckpointInfo)11683_storage": { + "encoding": "inplace", + "label": "struct CheckpointInfo", + "members": [ + { + "astId": 11670, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "hash", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 11673, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "rootHash", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 11676, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "threshold", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 11679, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "currentWeight", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 11682, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "reached", + "offset": 0, + "slot": "4", + "type": "t_bool" + } + ], + "numberOfBytes": "160" + }, + "t_struct(ChildCheck)11697_storage": { "encoding": "inplace", "label": "struct ChildCheck", "members": [ { - "astId": 10145, + "astId": 11693, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10148, + "astId": 11696, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "checks", "offset": 0, @@ -288,20 +395,20 @@ ], "numberOfBytes": "96" }, - "t_struct(CrossMsg)10155_storage": { + "t_struct(CrossMsg)11703_storage": { "encoding": "inplace", "label": "struct CrossMsg", "members": [ { - "astId": 10152, + "astId": 11700, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "message", "offset": 0, "slot": "0", - "type": "t_struct(StorableMsg)10170_storage" + "type": "t_struct(StorableMsg)11718_storage" }, { - "astId": 10154, + "astId": 11702, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "wrapped", "offset": 0, @@ -311,12 +418,12 @@ ], "numberOfBytes": "384" }, - "t_struct(EpochVoteSubmission)10194_storage": { + "t_struct(EpochVoteSubmission)11742_storage": { "encoding": "inplace", "label": "struct EpochVoteSubmission", "members": [ { - "astId": 10177, + "astId": 11725, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "nonce", "offset": 0, @@ -324,7 +431,7 @@ "type": "t_uint256" }, { - "astId": 10179, + "astId": 11727, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "totalSubmissionWeight", "offset": 0, @@ -332,7 +439,7 @@ "type": "t_uint256" }, { - "astId": 10181, + "astId": 11729, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "mostVotedSubmission", "offset": 0, @@ -340,7 +447,7 @@ "type": "t_bytes32" }, { - "astId": 10187, + "astId": 11735, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "submitters", "offset": 0, @@ -348,7 +455,7 @@ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" }, { - "astId": 10193, + "astId": 11741, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "submissionWeights", "offset": 0, @@ -358,35 +465,35 @@ ], "numberOfBytes": "160" }, - "t_struct(EpochVoteTopDownSubmission)10203_storage": { + "t_struct(EpochVoteTopDownSubmission)11751_storage": { "encoding": "inplace", "label": "struct EpochVoteTopDownSubmission", "members": [ { - "astId": 10197, + "astId": 11745, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "vote", "offset": 0, "slot": "0", - "type": "t_struct(EpochVoteSubmission)10194_storage" + "type": "t_struct(EpochVoteSubmission)11742_storage" }, { - "astId": 10202, + "astId": 11750, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "submissions", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)10142_storage)" + "type": "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)11690_storage)" } ], "numberOfBytes": "192" }, - "t_struct(FvmAddress)10234_storage": { + "t_struct(FvmAddress)11782_storage": { "encoding": "inplace", "label": "struct FvmAddress", "members": [ { - "astId": 10231, + "astId": 11779, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "addrType", "offset": 0, @@ -394,7 +501,7 @@ "type": "t_uint8" }, { - "astId": 10233, + "astId": 11781, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "payload", "offset": 0, @@ -404,36 +511,36 @@ ], "numberOfBytes": "64" }, - "t_struct(GatewayActorStorage)8486_storage": { + "t_struct(GatewayActorStorage)10004_storage": { "encoding": "inplace", "label": "struct GatewayActorStorage", "members": [ { - "astId": 8385, + "astId": 9882, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "subnets", "offset": 0, "slot": "0", - "type": "t_mapping(t_bytes32,t_struct(Subnet)10280_storage)" + "type": "t_mapping(t_bytes32,t_struct(Subnet)11828_storage)" }, { - "astId": 8394, + "astId": 9891, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "topDownMsgs", "offset": 0, "slot": "1", - "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage))" + "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage))" }, { - "astId": 8400, + "astId": 9897, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "finalitiesMap", "offset": 0, "slot": "2", - "type": "t_mapping(t_uint256,t_struct(ParentFinality)10115_storage)" + "type": "t_mapping(t_uint256,t_struct(ParentFinality)11633_storage)" }, { - "astId": 8403, + "astId": 9900, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "latestParentHeight", "offset": 0, @@ -441,189 +548,221 @@ "type": "t_uint256" }, { - "astId": 8409, + "astId": 9906, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "postbox", "offset": 0, "slot": "4", - "type": "t_mapping(t_bytes32,t_struct(CrossMsg)10155_storage)" + "type": "t_mapping(t_bytes32,t_struct(CrossMsg)11703_storage)" }, { - "astId": 8415, + "astId": 9913, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "bottomUpCheckpoints", + "label": "validatorSetWeights", "offset": 0, "slot": "5", - "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_uint256))" }, { - "astId": 8422, + "astId": 9917, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "validatorSetWeights", + "label": "currentMembership", "offset": 0, "slot": "6", - "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_uint256))" + "type": "t_struct(Membership)11871_storage" }, { - "astId": 8426, + "astId": 9921, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "currentMembership", + "label": "lastMembership", "offset": 0, - "slot": "7", - "type": "t_struct(Membership)10323_storage" + "slot": "9", + "type": "t_struct(Membership)11871_storage" }, { - "astId": 8430, + "astId": 9926, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "lastMembership", + "label": "bottomUpCheckpointsLegacy", "offset": 0, - "slot": "10", - "type": "t_struct(Membership)10323_storage" + "slot": "12", + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)" }, { - "astId": 8439, + "astId": 9932, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "children", + "label": "bottomUpCheckpoints", "offset": 0, "slot": "13", + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpointNew)11667_storage)" + }, + { + "astId": 9938, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "bottomUpCheckpointInfo", + "offset": 0, + "slot": "14", + "type": "t_mapping(t_uint64,t_struct(CheckpointInfo)11683_storage)" + }, + { + "astId": 9945, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "bottomUpCollectedSignatures", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_uint64,t_mapping(t_address,t_bool))" + }, + { + "astId": 9954, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "children", + "offset": 0, + "slot": "16", "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_array(t_uint256)2_storage))" }, { - "astId": 8448, + "astId": 9963, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "checks", "offset": 0, - "slot": "14", + "slot": "17", "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_mapping(t_bytes32,t_bool)))" }, { - "astId": 8454, + "astId": 9969, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "epochVoteSubmissions", "offset": 0, - "slot": "15", - "type": "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)10203_storage)" + "slot": "18", + "type": "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)11751_storage)" }, { - "astId": 8458, + "astId": 9973, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "subnetKeys", "offset": 0, - "slot": "16", + "slot": "19", "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 8462, + "astId": 9977, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "networkName", "offset": 0, - "slot": "17", - "type": "t_struct(SubnetID)10260_storage" + "slot": "20", + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 8465, + "astId": 9980, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "minStake", "offset": 0, - "slot": "19", + "slot": "22", "type": "t_uint256" }, { - "astId": 8468, + "astId": 9983, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "crossMsgFee", "offset": 0, - "slot": "20", + "slot": "23", "type": "t_uint256" }, { - "astId": 8471, + "astId": 9986, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", - "label": "bottomUpNonce", + "label": "majorityPercentage", "offset": 0, - "slot": "21", + "slot": "24", + "type": "t_uint8" + }, + { + "astId": 9989, + "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", + "label": "bottomUpNonce", + "offset": 1, + "slot": "24", "type": "t_uint64" }, { - "astId": 8474, + "astId": 9992, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "appliedTopDownNonce", - "offset": 8, - "slot": "21", + "offset": 9, + "slot": "24", "type": "t_uint64" }, { - "astId": 8477, + "astId": 9995, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "topDownCheckPeriod", - "offset": 16, - "slot": "21", + "offset": 17, + "slot": "24", "type": "t_uint64" }, { - "astId": 8480, + "astId": 9998, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "totalSubnets", - "offset": 24, - "slot": "21", + "offset": 0, + "slot": "25", "type": "t_uint64" }, { - "astId": 8482, + "astId": 10000, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "bottomUpCheckPeriod", - "offset": 0, - "slot": "22", + "offset": 8, + "slot": "25", "type": "t_uint64" }, { - "astId": 8485, + "astId": 10003, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "initialized", - "offset": 8, - "slot": "22", + "offset": 16, + "slot": "25", "type": "t_bool" } ], - "numberOfBytes": "736" + "numberOfBytes": "832" }, - "t_struct(IPCAddress)10287_storage": { + "t_struct(IPCAddress)11835_storage": { "encoding": "inplace", "label": "struct IPCAddress", "members": [ { - "astId": 10283, + "astId": 11831, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "subnetId", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10286, + "astId": 11834, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "rawAddress", "offset": 0, "slot": "2", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "128" }, - "t_struct(Membership)10323_storage": { + "t_struct(Membership)11871_storage": { "encoding": "inplace", "label": "struct Membership", "members": [ { - "astId": 10318, + "astId": 11866, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "validators", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Validator)10314_storage)dyn_storage" + "type": "t_array(t_struct(Validator)11862_storage)dyn_storage" }, { - "astId": 10320, + "astId": 11868, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "configurationNumber", "offset": 0, @@ -631,7 +770,7 @@ "type": "t_uint64" }, { - "astId": 10322, + "astId": 11870, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "totalWeight", "offset": 0, @@ -641,12 +780,12 @@ ], "numberOfBytes": "96" }, - "t_struct(ParentFinality)10115_storage": { + "t_struct(ParentFinality)11633_storage": { "encoding": "inplace", "label": "struct ParentFinality", "members": [ { - "astId": 10112, + "astId": 11630, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "height", "offset": 0, @@ -654,7 +793,7 @@ "type": "t_uint256" }, { - "astId": 10114, + "astId": 11632, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "blockHash", "offset": 0, @@ -664,28 +803,28 @@ ], "numberOfBytes": "64" }, - "t_struct(StorableMsg)10170_storage": { + "t_struct(StorableMsg)11718_storage": { "encoding": "inplace", "label": "struct StorableMsg", "members": [ { - "astId": 10158, + "astId": 11706, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "from", "offset": 0, "slot": "0", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10161, + "astId": 11709, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "to", "offset": 0, "slot": "4", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10163, + "astId": 11711, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "value", "offset": 0, @@ -693,7 +832,7 @@ "type": "t_uint256" }, { - "astId": 10165, + "astId": 11713, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "nonce", "offset": 0, @@ -701,7 +840,7 @@ "type": "t_uint64" }, { - "astId": 10167, + "astId": 11715, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "method", "offset": 8, @@ -709,7 +848,7 @@ "type": "t_bytes4" }, { - "astId": 10169, + "astId": 11717, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "params", "offset": 0, @@ -719,12 +858,12 @@ ], "numberOfBytes": "352" }, - "t_struct(Subnet)10280_storage": { + "t_struct(Subnet)11828_storage": { "encoding": "inplace", "label": "struct Subnet", "members": [ { - "astId": 10262, + "astId": 11810, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "stake", "offset": 0, @@ -732,7 +871,7 @@ "type": "t_uint256" }, { - "astId": 10264, + "astId": 11812, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "genesisEpoch", "offset": 0, @@ -740,7 +879,7 @@ "type": "t_uint256" }, { - "astId": 10266, + "astId": 11814, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "circSupply", "offset": 0, @@ -748,7 +887,7 @@ "type": "t_uint256" }, { - "astId": 10268, + "astId": 11816, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "topDownNonce", "offset": 0, @@ -756,7 +895,7 @@ "type": "t_uint64" }, { - "astId": 10270, + "astId": 11818, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "appliedBottomUpNonce", "offset": 8, @@ -764,38 +903,38 @@ "type": "t_uint64" }, { - "astId": 10273, + "astId": 11821, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "status", "offset": 16, "slot": "3", - "type": "t_enum(Status)4025" + "type": "t_enum(Status)4994" }, { - "astId": 10276, + "astId": 11824, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "id", "offset": 0, "slot": "4", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10279, + "astId": 11827, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "prevCheckpoint", "offset": 0, "slot": "6", - "type": "t_struct(BottomUpCheckpoint)10135_storage" + "type": "t_struct(BottomUpCheckpoint)11653_storage" } ], "numberOfBytes": "448" }, - "t_struct(SubnetID)10260_storage": { + "t_struct(SubnetID)11808_storage": { "encoding": "inplace", "label": "struct SubnetID", "members": [ { - "astId": 10255, + "astId": 11803, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "root", "offset": 0, @@ -803,7 +942,7 @@ "type": "t_uint64" }, { - "astId": 10259, + "astId": 11807, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "route", "offset": 0, @@ -813,12 +952,12 @@ ], "numberOfBytes": "64" }, - "t_struct(TopDownCheckpoint)10142_storage": { + "t_struct(TopDownCheckpoint)11690_storage": { "encoding": "inplace", "label": "struct TopDownCheckpoint", "members": [ { - "astId": 10137, + "astId": 11685, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "epoch", "offset": 0, @@ -826,22 +965,22 @@ "type": "t_uint64" }, { - "astId": 10141, + "astId": 11689, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "topDownMsgs", "offset": 0, "slot": "1", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" } ], "numberOfBytes": "64" }, - "t_struct(Validator)10314_storage": { + "t_struct(Validator)11862_storage": { "encoding": "inplace", "label": "struct Validator", "members": [ { - "astId": 10310, + "astId": 11858, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "weight", "offset": 0, @@ -849,12 +988,12 @@ "type": "t_uint256" }, { - "astId": 10313, + "astId": 11861, "contract": "src/lib/LibGatewayActorStorage.sol:GatewayActorModifiers", "label": "addr", "offset": 0, "slot": "1", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "96" diff --git a/.storage-layouts/GatewayDiamond.json b/.storage-layouts/GatewayDiamond.json index 968c52f2e..b7606ce31 100644 --- a/.storage-layouts/GatewayDiamond.json +++ b/.storage-layouts/GatewayDiamond.json @@ -1,12 +1,12 @@ { "storage": [ { - "astId": 2783, + "astId": 3733, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "s", "offset": 0, "slot": "0", - "type": "t_struct(GatewayActorStorage)8486_storage" + "type": "t_struct(GatewayActorStorage)10004_storage" } ], "types": { @@ -27,20 +27,20 @@ "label": "bytes32[]", "numberOfBytes": "32" }, - "t_array(t_struct(ChildCheck)10149_storage)dyn_storage": { - "base": "t_struct(ChildCheck)10149_storage", + "t_array(t_struct(ChildCheck)11697_storage)dyn_storage": { + "base": "t_struct(ChildCheck)11697_storage", "encoding": "dynamic_array", "label": "struct ChildCheck[]", "numberOfBytes": "32" }, - "t_array(t_struct(CrossMsg)10155_storage)dyn_storage": { - "base": "t_struct(CrossMsg)10155_storage", + "t_array(t_struct(CrossMsg)11703_storage)dyn_storage": { + "base": "t_struct(CrossMsg)11703_storage", "encoding": "dynamic_array", "label": "struct CrossMsg[]", "numberOfBytes": "32" }, - "t_array(t_struct(Validator)10314_storage)dyn_storage": { - "base": "t_struct(Validator)10314_storage", + "t_array(t_struct(Validator)11862_storage)dyn_storage": { + "base": "t_struct(Validator)11862_storage", "encoding": "dynamic_array", "label": "struct Validator[]", "numberOfBytes": "32" @@ -71,7 +71,7 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_enum(Status)4025": { + "t_enum(Status)4994": { "encoding": "inplace", "label": "enum Status", "numberOfBytes": "1" @@ -104,33 +104,33 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_bool)" }, - "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage))": { + "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage))": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => mapping(uint256 => struct CrossMsg[]))", "numberOfBytes": "32", - "value": "t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage)" + "value": "t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage)" }, - "t_mapping(t_bytes32,t_struct(CrossMsg)10155_storage)": { + "t_mapping(t_bytes32,t_struct(CrossMsg)11703_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct CrossMsg)", "numberOfBytes": "32", - "value": "t_struct(CrossMsg)10155_storage" + "value": "t_struct(CrossMsg)11703_storage" }, - "t_mapping(t_bytes32,t_struct(Subnet)10280_storage)": { + "t_mapping(t_bytes32,t_struct(Subnet)11828_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct Subnet)", "numberOfBytes": "32", - "value": "t_struct(Subnet)10280_storage" + "value": "t_struct(Subnet)11828_storage" }, - "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)10142_storage)": { + "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)11690_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct TopDownCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(TopDownCheckpoint)10142_storage" + "value": "t_struct(TopDownCheckpoint)11690_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -139,12 +139,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage)": { + "t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct CrossMsg[])", "numberOfBytes": "32", - "value": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "value": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, "t_mapping(t_uint256,t_mapping(t_address,t_bool))": { "encoding": "mapping", @@ -160,12 +160,19 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint256,t_struct(ParentFinality)10115_storage)": { + "t_mapping(t_uint256,t_struct(ParentFinality)11633_storage)": { "encoding": "mapping", "key": "t_uint256", "label": "mapping(uint256 => struct ParentFinality)", "numberOfBytes": "32", - "value": "t_struct(ParentFinality)10115_storage" + "value": "t_struct(ParentFinality)11633_storage" + }, + "t_mapping(t_uint64,t_mapping(t_address,t_bool))": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => mapping(address => bool))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_bool)" }, "t_mapping(t_uint64,t_mapping(t_bytes32,t_array(t_uint256)2_storage))": { "encoding": "mapping", @@ -188,34 +195,48 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" + }, + "t_mapping(t_uint64,t_struct(BottomUpCheckpointNew)11667_storage)": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => struct BottomUpCheckpointNew)", + "numberOfBytes": "32", + "value": "t_struct(BottomUpCheckpointNew)11667_storage" }, - "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)10203_storage)": { + "t_mapping(t_uint64,t_struct(CheckpointInfo)11683_storage)": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => struct CheckpointInfo)", + "numberOfBytes": "32", + "value": "t_struct(CheckpointInfo)11683_storage" + }, + "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)11751_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct EpochVoteTopDownSubmission)", "numberOfBytes": "32", - "value": "t_struct(EpochVoteTopDownSubmission)10203_storage" + "value": "t_struct(EpochVoteTopDownSubmission)11751_storage" }, - "t_struct(BottomUpCheckpoint)10135_storage": { + "t_struct(BottomUpCheckpoint)11653_storage": { "encoding": "inplace", "label": "struct BottomUpCheckpoint", "members": [ { - "astId": 10118, + "astId": 11636, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10120, + "astId": 11638, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "epoch", "offset": 0, @@ -223,7 +244,7 @@ "type": "t_uint64" }, { - "astId": 10122, + "astId": 11640, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "fee", "offset": 0, @@ -231,23 +252,23 @@ "type": "t_uint256" }, { - "astId": 10126, + "astId": 11644, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "crossMsgs", "offset": 0, "slot": "4", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, { - "astId": 10130, + "astId": 11648, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "children", "offset": 0, "slot": "5", - "type": "t_array(t_struct(ChildCheck)10149_storage)dyn_storage" + "type": "t_array(t_struct(ChildCheck)11697_storage)dyn_storage" }, { - "astId": 10132, + "astId": 11650, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "prevHash", "offset": 0, @@ -255,7 +276,7 @@ "type": "t_bytes32" }, { - "astId": 10134, + "astId": 11652, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "proof", "offset": 0, @@ -265,20 +286,106 @@ ], "numberOfBytes": "256" }, - "t_struct(ChildCheck)10149_storage": { + "t_struct(BottomUpCheckpointNew)11667_storage": { + "encoding": "inplace", + "label": "struct BottomUpCheckpointNew", + "members": [ + { + "astId": 11657, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "subnetID", + "offset": 0, + "slot": "0", + "type": "t_struct(SubnetID)11808_storage" + }, + { + "astId": 11660, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "blockHeight", + "offset": 0, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 11663, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "nextConfigurationNumber", + "offset": 8, + "slot": "2", + "type": "t_uint64" + }, + { + "astId": 11666, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "crossMessagesHash", + "offset": 0, + "slot": "3", + "type": "t_bytes32" + } + ], + "numberOfBytes": "128" + }, + "t_struct(CheckpointInfo)11683_storage": { + "encoding": "inplace", + "label": "struct CheckpointInfo", + "members": [ + { + "astId": 11670, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "hash", + "offset": 0, + "slot": "0", + "type": "t_bytes32" + }, + { + "astId": 11673, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "rootHash", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + }, + { + "astId": 11676, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "threshold", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 11679, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "currentWeight", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 11682, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "reached", + "offset": 0, + "slot": "4", + "type": "t_bool" + } + ], + "numberOfBytes": "160" + }, + "t_struct(ChildCheck)11697_storage": { "encoding": "inplace", "label": "struct ChildCheck", "members": [ { - "astId": 10145, + "astId": 11693, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10148, + "astId": 11696, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "checks", "offset": 0, @@ -288,20 +395,20 @@ ], "numberOfBytes": "96" }, - "t_struct(CrossMsg)10155_storage": { + "t_struct(CrossMsg)11703_storage": { "encoding": "inplace", "label": "struct CrossMsg", "members": [ { - "astId": 10152, + "astId": 11700, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "message", "offset": 0, "slot": "0", - "type": "t_struct(StorableMsg)10170_storage" + "type": "t_struct(StorableMsg)11718_storage" }, { - "astId": 10154, + "astId": 11702, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "wrapped", "offset": 0, @@ -311,12 +418,12 @@ ], "numberOfBytes": "384" }, - "t_struct(EpochVoteSubmission)10194_storage": { + "t_struct(EpochVoteSubmission)11742_storage": { "encoding": "inplace", "label": "struct EpochVoteSubmission", "members": [ { - "astId": 10177, + "astId": 11725, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "nonce", "offset": 0, @@ -324,7 +431,7 @@ "type": "t_uint256" }, { - "astId": 10179, + "astId": 11727, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "totalSubmissionWeight", "offset": 0, @@ -332,7 +439,7 @@ "type": "t_uint256" }, { - "astId": 10181, + "astId": 11729, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "mostVotedSubmission", "offset": 0, @@ -340,7 +447,7 @@ "type": "t_bytes32" }, { - "astId": 10187, + "astId": 11735, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "submitters", "offset": 0, @@ -348,7 +455,7 @@ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" }, { - "astId": 10193, + "astId": 11741, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "submissionWeights", "offset": 0, @@ -358,35 +465,35 @@ ], "numberOfBytes": "160" }, - "t_struct(EpochVoteTopDownSubmission)10203_storage": { + "t_struct(EpochVoteTopDownSubmission)11751_storage": { "encoding": "inplace", "label": "struct EpochVoteTopDownSubmission", "members": [ { - "astId": 10197, + "astId": 11745, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "vote", "offset": 0, "slot": "0", - "type": "t_struct(EpochVoteSubmission)10194_storage" + "type": "t_struct(EpochVoteSubmission)11742_storage" }, { - "astId": 10202, + "astId": 11750, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "submissions", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)10142_storage)" + "type": "t_mapping(t_bytes32,t_struct(TopDownCheckpoint)11690_storage)" } ], "numberOfBytes": "192" }, - "t_struct(FvmAddress)10234_storage": { + "t_struct(FvmAddress)11782_storage": { "encoding": "inplace", "label": "struct FvmAddress", "members": [ { - "astId": 10231, + "astId": 11779, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "addrType", "offset": 0, @@ -394,7 +501,7 @@ "type": "t_uint8" }, { - "astId": 10233, + "astId": 11781, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "payload", "offset": 0, @@ -404,36 +511,36 @@ ], "numberOfBytes": "64" }, - "t_struct(GatewayActorStorage)8486_storage": { + "t_struct(GatewayActorStorage)10004_storage": { "encoding": "inplace", "label": "struct GatewayActorStorage", "members": [ { - "astId": 8385, + "astId": 9882, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "subnets", "offset": 0, "slot": "0", - "type": "t_mapping(t_bytes32,t_struct(Subnet)10280_storage)" + "type": "t_mapping(t_bytes32,t_struct(Subnet)11828_storage)" }, { - "astId": 8394, + "astId": 9891, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "topDownMsgs", "offset": 0, "slot": "1", - "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)10155_storage)dyn_storage))" + "type": "t_mapping(t_bytes32,t_mapping(t_uint256,t_array(t_struct(CrossMsg)11703_storage)dyn_storage))" }, { - "astId": 8400, + "astId": 9897, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "finalitiesMap", "offset": 0, "slot": "2", - "type": "t_mapping(t_uint256,t_struct(ParentFinality)10115_storage)" + "type": "t_mapping(t_uint256,t_struct(ParentFinality)11633_storage)" }, { - "astId": 8403, + "astId": 9900, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "latestParentHeight", "offset": 0, @@ -441,189 +548,221 @@ "type": "t_uint256" }, { - "astId": 8409, + "astId": 9906, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "postbox", "offset": 0, "slot": "4", - "type": "t_mapping(t_bytes32,t_struct(CrossMsg)10155_storage)" + "type": "t_mapping(t_bytes32,t_struct(CrossMsg)11703_storage)" }, { - "astId": 8415, + "astId": 9913, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "bottomUpCheckpoints", + "label": "validatorSetWeights", "offset": 0, "slot": "5", - "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_uint256))" }, { - "astId": 8422, + "astId": 9917, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "validatorSetWeights", + "label": "currentMembership", "offset": 0, "slot": "6", - "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_uint256))" + "type": "t_struct(Membership)11871_storage" }, { - "astId": 8426, + "astId": 9921, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "currentMembership", + "label": "lastMembership", "offset": 0, - "slot": "7", - "type": "t_struct(Membership)10323_storage" + "slot": "9", + "type": "t_struct(Membership)11871_storage" }, { - "astId": 8430, + "astId": 9926, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "lastMembership", + "label": "bottomUpCheckpointsLegacy", "offset": 0, - "slot": "10", - "type": "t_struct(Membership)10323_storage" + "slot": "12", + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)" }, { - "astId": 8439, + "astId": 9932, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "children", + "label": "bottomUpCheckpoints", "offset": 0, "slot": "13", + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpointNew)11667_storage)" + }, + { + "astId": 9938, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "bottomUpCheckpointInfo", + "offset": 0, + "slot": "14", + "type": "t_mapping(t_uint64,t_struct(CheckpointInfo)11683_storage)" + }, + { + "astId": 9945, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "bottomUpCollectedSignatures", + "offset": 0, + "slot": "15", + "type": "t_mapping(t_uint64,t_mapping(t_address,t_bool))" + }, + { + "astId": 9954, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "children", + "offset": 0, + "slot": "16", "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_array(t_uint256)2_storage))" }, { - "astId": 8448, + "astId": 9963, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "checks", "offset": 0, - "slot": "14", + "slot": "17", "type": "t_mapping(t_uint64,t_mapping(t_bytes32,t_mapping(t_bytes32,t_bool)))" }, { - "astId": 8454, + "astId": 9969, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "epochVoteSubmissions", "offset": 0, - "slot": "15", - "type": "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)10203_storage)" + "slot": "18", + "type": "t_mapping(t_uint64,t_struct(EpochVoteTopDownSubmission)11751_storage)" }, { - "astId": 8458, + "astId": 9973, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "subnetKeys", "offset": 0, - "slot": "16", + "slot": "19", "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 8462, + "astId": 9977, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "networkName", "offset": 0, - "slot": "17", - "type": "t_struct(SubnetID)10260_storage" + "slot": "20", + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 8465, + "astId": 9980, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "minStake", "offset": 0, - "slot": "19", + "slot": "22", "type": "t_uint256" }, { - "astId": 8468, + "astId": 9983, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "crossMsgFee", "offset": 0, - "slot": "20", + "slot": "23", "type": "t_uint256" }, { - "astId": 8471, + "astId": 9986, "contract": "src/GatewayDiamond.sol:GatewayDiamond", - "label": "bottomUpNonce", + "label": "majorityPercentage", "offset": 0, - "slot": "21", + "slot": "24", + "type": "t_uint8" + }, + { + "astId": 9989, + "contract": "src/GatewayDiamond.sol:GatewayDiamond", + "label": "bottomUpNonce", + "offset": 1, + "slot": "24", "type": "t_uint64" }, { - "astId": 8474, + "astId": 9992, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "appliedTopDownNonce", - "offset": 8, - "slot": "21", + "offset": 9, + "slot": "24", "type": "t_uint64" }, { - "astId": 8477, + "astId": 9995, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "topDownCheckPeriod", - "offset": 16, - "slot": "21", + "offset": 17, + "slot": "24", "type": "t_uint64" }, { - "astId": 8480, + "astId": 9998, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "totalSubnets", - "offset": 24, - "slot": "21", + "offset": 0, + "slot": "25", "type": "t_uint64" }, { - "astId": 8482, + "astId": 10000, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "bottomUpCheckPeriod", - "offset": 0, - "slot": "22", + "offset": 8, + "slot": "25", "type": "t_uint64" }, { - "astId": 8485, + "astId": 10003, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "initialized", - "offset": 8, - "slot": "22", + "offset": 16, + "slot": "25", "type": "t_bool" } ], - "numberOfBytes": "736" + "numberOfBytes": "832" }, - "t_struct(IPCAddress)10287_storage": { + "t_struct(IPCAddress)11835_storage": { "encoding": "inplace", "label": "struct IPCAddress", "members": [ { - "astId": 10283, + "astId": 11831, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "subnetId", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10286, + "astId": 11834, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "rawAddress", "offset": 0, "slot": "2", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "128" }, - "t_struct(Membership)10323_storage": { + "t_struct(Membership)11871_storage": { "encoding": "inplace", "label": "struct Membership", "members": [ { - "astId": 10318, + "astId": 11866, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "validators", "offset": 0, "slot": "0", - "type": "t_array(t_struct(Validator)10314_storage)dyn_storage" + "type": "t_array(t_struct(Validator)11862_storage)dyn_storage" }, { - "astId": 10320, + "astId": 11868, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "configurationNumber", "offset": 0, @@ -631,7 +770,7 @@ "type": "t_uint64" }, { - "astId": 10322, + "astId": 11870, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "totalWeight", "offset": 0, @@ -641,12 +780,12 @@ ], "numberOfBytes": "96" }, - "t_struct(ParentFinality)10115_storage": { + "t_struct(ParentFinality)11633_storage": { "encoding": "inplace", "label": "struct ParentFinality", "members": [ { - "astId": 10112, + "astId": 11630, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "height", "offset": 0, @@ -654,7 +793,7 @@ "type": "t_uint256" }, { - "astId": 10114, + "astId": 11632, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "blockHash", "offset": 0, @@ -664,28 +803,28 @@ ], "numberOfBytes": "64" }, - "t_struct(StorableMsg)10170_storage": { + "t_struct(StorableMsg)11718_storage": { "encoding": "inplace", "label": "struct StorableMsg", "members": [ { - "astId": 10158, + "astId": 11706, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "from", "offset": 0, "slot": "0", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10161, + "astId": 11709, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "to", "offset": 0, "slot": "4", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10163, + "astId": 11711, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "value", "offset": 0, @@ -693,7 +832,7 @@ "type": "t_uint256" }, { - "astId": 10165, + "astId": 11713, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "nonce", "offset": 0, @@ -701,7 +840,7 @@ "type": "t_uint64" }, { - "astId": 10167, + "astId": 11715, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "method", "offset": 8, @@ -709,7 +848,7 @@ "type": "t_bytes4" }, { - "astId": 10169, + "astId": 11717, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "params", "offset": 0, @@ -719,12 +858,12 @@ ], "numberOfBytes": "352" }, - "t_struct(Subnet)10280_storage": { + "t_struct(Subnet)11828_storage": { "encoding": "inplace", "label": "struct Subnet", "members": [ { - "astId": 10262, + "astId": 11810, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "stake", "offset": 0, @@ -732,7 +871,7 @@ "type": "t_uint256" }, { - "astId": 10264, + "astId": 11812, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "genesisEpoch", "offset": 0, @@ -740,7 +879,7 @@ "type": "t_uint256" }, { - "astId": 10266, + "astId": 11814, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "circSupply", "offset": 0, @@ -748,7 +887,7 @@ "type": "t_uint256" }, { - "astId": 10268, + "astId": 11816, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "topDownNonce", "offset": 0, @@ -756,7 +895,7 @@ "type": "t_uint64" }, { - "astId": 10270, + "astId": 11818, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "appliedBottomUpNonce", "offset": 8, @@ -764,38 +903,38 @@ "type": "t_uint64" }, { - "astId": 10273, + "astId": 11821, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "status", "offset": 16, "slot": "3", - "type": "t_enum(Status)4025" + "type": "t_enum(Status)4994" }, { - "astId": 10276, + "astId": 11824, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "id", "offset": 0, "slot": "4", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10279, + "astId": 11827, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "prevCheckpoint", "offset": 0, "slot": "6", - "type": "t_struct(BottomUpCheckpoint)10135_storage" + "type": "t_struct(BottomUpCheckpoint)11653_storage" } ], "numberOfBytes": "448" }, - "t_struct(SubnetID)10260_storage": { + "t_struct(SubnetID)11808_storage": { "encoding": "inplace", "label": "struct SubnetID", "members": [ { - "astId": 10255, + "astId": 11803, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "root", "offset": 0, @@ -803,7 +942,7 @@ "type": "t_uint64" }, { - "astId": 10259, + "astId": 11807, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "route", "offset": 0, @@ -813,12 +952,12 @@ ], "numberOfBytes": "64" }, - "t_struct(TopDownCheckpoint)10142_storage": { + "t_struct(TopDownCheckpoint)11690_storage": { "encoding": "inplace", "label": "struct TopDownCheckpoint", "members": [ { - "astId": 10137, + "astId": 11685, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "epoch", "offset": 0, @@ -826,22 +965,22 @@ "type": "t_uint64" }, { - "astId": 10141, + "astId": 11689, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "topDownMsgs", "offset": 0, "slot": "1", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" } ], "numberOfBytes": "64" }, - "t_struct(Validator)10314_storage": { + "t_struct(Validator)11862_storage": { "encoding": "inplace", "label": "struct Validator", "members": [ { - "astId": 10310, + "astId": 11858, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "weight", "offset": 0, @@ -849,12 +988,12 @@ "type": "t_uint256" }, { - "astId": 10313, + "astId": 11861, "contract": "src/GatewayDiamond.sol:GatewayDiamond", "label": "addr", "offset": 0, "slot": "1", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "96" diff --git a/.storage-layouts/SubnetActorDiamond.json b/.storage-layouts/SubnetActorDiamond.json index cb6ed6ade..81dff85c9 100644 --- a/.storage-layouts/SubnetActorDiamond.json +++ b/.storage-layouts/SubnetActorDiamond.json @@ -1,12 +1,12 @@ { "storage": [ { - "astId": 2989, + "astId": 3959, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "s", "offset": 0, "slot": "0", - "type": "t_struct(SubnetActorStorage)8716_storage" + "type": "t_struct(SubnetActorStorage)10234_storage" } ], "types": { @@ -27,14 +27,14 @@ "label": "bytes32[]", "numberOfBytes": "32" }, - "t_array(t_struct(ChildCheck)10149_storage)dyn_storage": { - "base": "t_struct(ChildCheck)10149_storage", + "t_array(t_struct(ChildCheck)11697_storage)dyn_storage": { + "base": "t_struct(ChildCheck)11697_storage", "encoding": "dynamic_array", "label": "struct ChildCheck[]", "numberOfBytes": "32" }, - "t_array(t_struct(CrossMsg)10155_storage)dyn_storage": { - "base": "t_struct(CrossMsg)10155_storage", + "t_array(t_struct(CrossMsg)11703_storage)dyn_storage": { + "base": "t_struct(CrossMsg)11703_storage", "encoding": "dynamic_array", "label": "struct CrossMsg[]", "numberOfBytes": "32" @@ -59,12 +59,12 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_enum(ConsensusType)4011": { + "t_enum(ConsensusType)4980": { "encoding": "inplace", "label": "enum ConsensusType", "numberOfBytes": "1" }, - "t_enum(Status)4025": { + "t_enum(Status)4994": { "encoding": "inplace", "label": "enum Status", "numberOfBytes": "1" @@ -83,12 +83,12 @@ "numberOfBytes": "32", "value": "t_string_storage" }, - "t_mapping(t_address,t_struct(FvmAddress)10234_storage)": { + "t_mapping(t_address,t_struct(FvmAddress)11782_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct FvmAddress)", "numberOfBytes": "32", - "value": "t_struct(FvmAddress)10234_storage" + "value": "t_struct(FvmAddress)11782_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -97,12 +97,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -125,54 +125,54 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" }, - "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)10212_storage)": { + "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)11760_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct EpochVoteBottomUpSubmission)", "numberOfBytes": "32", - "value": "t_struct(EpochVoteBottomUpSubmission)10212_storage" + "value": "t_struct(EpochVoteBottomUpSubmission)11760_storage" }, "t_string_storage": { "encoding": "bytes", "label": "string", "numberOfBytes": "32" }, - "t_struct(AddressSet)2473_storage": { + "t_struct(AddressSet)3420_storage": { "encoding": "inplace", "label": "struct EnumerableSet.AddressSet", "members": [ { - "astId": 2472, + "astId": 3419, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)2158_storage" + "type": "t_struct(Set)3105_storage" } ], "numberOfBytes": "64" }, - "t_struct(BottomUpCheckpoint)10135_storage": { + "t_struct(BottomUpCheckpoint)11653_storage": { "encoding": "inplace", "label": "struct BottomUpCheckpoint", "members": [ { - "astId": 10118, + "astId": 11636, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10120, + "astId": 11638, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "epoch", "offset": 0, @@ -180,7 +180,7 @@ "type": "t_uint64" }, { - "astId": 10122, + "astId": 11640, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "fee", "offset": 0, @@ -188,23 +188,23 @@ "type": "t_uint256" }, { - "astId": 10126, + "astId": 11644, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "crossMsgs", "offset": 0, "slot": "4", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, { - "astId": 10130, + "astId": 11648, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "children", "offset": 0, "slot": "5", - "type": "t_array(t_struct(ChildCheck)10149_storage)dyn_storage" + "type": "t_array(t_struct(ChildCheck)11697_storage)dyn_storage" }, { - "astId": 10132, + "astId": 11650, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "prevHash", "offset": 0, @@ -212,7 +212,7 @@ "type": "t_bytes32" }, { - "astId": 10134, + "astId": 11652, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "proof", "offset": 0, @@ -222,20 +222,20 @@ ], "numberOfBytes": "256" }, - "t_struct(ChildCheck)10149_storage": { + "t_struct(ChildCheck)11697_storage": { "encoding": "inplace", "label": "struct ChildCheck", "members": [ { - "astId": 10145, + "astId": 11693, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10148, + "astId": 11696, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "checks", "offset": 0, @@ -245,20 +245,20 @@ ], "numberOfBytes": "96" }, - "t_struct(CrossMsg)10155_storage": { + "t_struct(CrossMsg)11703_storage": { "encoding": "inplace", "label": "struct CrossMsg", "members": [ { - "astId": 10152, + "astId": 11700, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "message", "offset": 0, "slot": "0", - "type": "t_struct(StorableMsg)10170_storage" + "type": "t_struct(StorableMsg)11718_storage" }, { - "astId": 10154, + "astId": 11702, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "wrapped", "offset": 0, @@ -268,35 +268,35 @@ ], "numberOfBytes": "384" }, - "t_struct(EpochVoteBottomUpSubmission)10212_storage": { + "t_struct(EpochVoteBottomUpSubmission)11760_storage": { "encoding": "inplace", "label": "struct EpochVoteBottomUpSubmission", "members": [ { - "astId": 10206, + "astId": 11754, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "vote", "offset": 0, "slot": "0", - "type": "t_struct(EpochVoteSubmission)10194_storage" + "type": "t_struct(EpochVoteSubmission)11742_storage" }, { - "astId": 10211, + "astId": 11759, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "submissions", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)11653_storage)" } ], "numberOfBytes": "192" }, - "t_struct(EpochVoteSubmission)10194_storage": { + "t_struct(EpochVoteSubmission)11742_storage": { "encoding": "inplace", "label": "struct EpochVoteSubmission", "members": [ { - "astId": 10177, + "astId": 11725, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "nonce", "offset": 0, @@ -304,7 +304,7 @@ "type": "t_uint256" }, { - "astId": 10179, + "astId": 11727, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "totalSubmissionWeight", "offset": 0, @@ -312,7 +312,7 @@ "type": "t_uint256" }, { - "astId": 10181, + "astId": 11729, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "mostVotedSubmission", "offset": 0, @@ -320,7 +320,7 @@ "type": "t_bytes32" }, { - "astId": 10187, + "astId": 11735, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "submitters", "offset": 0, @@ -328,7 +328,7 @@ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" }, { - "astId": 10193, + "astId": 11741, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "submissionWeights", "offset": 0, @@ -338,12 +338,12 @@ ], "numberOfBytes": "160" }, - "t_struct(FvmAddress)10234_storage": { + "t_struct(FvmAddress)11782_storage": { "encoding": "inplace", "label": "struct FvmAddress", "members": [ { - "astId": 10231, + "astId": 11779, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "addrType", "offset": 0, @@ -351,7 +351,7 @@ "type": "t_uint8" }, { - "astId": 10233, + "astId": 11781, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "payload", "offset": 0, @@ -361,35 +361,35 @@ ], "numberOfBytes": "64" }, - "t_struct(IPCAddress)10287_storage": { + "t_struct(IPCAddress)11835_storage": { "encoding": "inplace", "label": "struct IPCAddress", "members": [ { - "astId": 10283, + "astId": 11831, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "subnetId", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10286, + "astId": 11834, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "rawAddress", "offset": 0, "slot": "2", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "128" }, - "t_struct(Set)2158_storage": { + "t_struct(Set)3105_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 2153, + "astId": 3100, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "_values", "offset": 0, @@ -397,7 +397,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 2157, + "astId": 3104, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "_indexes", "offset": 0, @@ -407,28 +407,28 @@ ], "numberOfBytes": "64" }, - "t_struct(StorableMsg)10170_storage": { + "t_struct(StorableMsg)11718_storage": { "encoding": "inplace", "label": "struct StorableMsg", "members": [ { - "astId": 10158, + "astId": 11706, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "from", "offset": 0, "slot": "0", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10161, + "astId": 11709, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "to", "offset": 0, "slot": "4", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10163, + "astId": 11711, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "value", "offset": 0, @@ -436,7 +436,7 @@ "type": "t_uint256" }, { - "astId": 10165, + "astId": 11713, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "nonce", "offset": 0, @@ -444,7 +444,7 @@ "type": "t_uint64" }, { - "astId": 10167, + "astId": 11715, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "method", "offset": 8, @@ -452,7 +452,7 @@ "type": "t_bytes4" }, { - "astId": 10169, + "astId": 11717, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "params", "offset": 0, @@ -462,20 +462,20 @@ ], "numberOfBytes": "352" }, - "t_struct(SubnetActorStorage)8716_storage": { + "t_struct(SubnetActorStorage)10234_storage": { "encoding": "inplace", "label": "struct SubnetActorStorage", "members": [ { - "astId": 8640, + "astId": 10158, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "epochVoteSubmissions", "offset": 0, "slot": "0", - "type": "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)10212_storage)" + "type": "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)11760_storage)" }, { - "astId": 8645, + "astId": 10163, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "stake", "offset": 0, @@ -483,7 +483,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 8650, + "astId": 10168, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "accumulatedRewards", "offset": 0, @@ -491,7 +491,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 8655, + "astId": 10173, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "validatorNetAddresses", "offset": 0, @@ -499,23 +499,23 @@ "type": "t_mapping(t_address,t_string_storage)" }, { - "astId": 8661, + "astId": 10179, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "validatorWorkerAddresses", "offset": 0, "slot": "4", - "type": "t_mapping(t_address,t_struct(FvmAddress)10234_storage)" + "type": "t_mapping(t_address,t_struct(FvmAddress)11782_storage)" }, { - "astId": 8667, + "astId": 10185, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "committedCheckpoints", "offset": 0, "slot": "5", - "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)" }, { - "astId": 8670, + "astId": 10188, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "genesis", "offset": 0, @@ -523,7 +523,7 @@ "type": "t_bytes_storage" }, { - "astId": 8673, + "astId": 10191, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "totalStake", "offset": 0, @@ -531,7 +531,7 @@ "type": "t_uint256" }, { - "astId": 8676, + "astId": 10194, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "minActivationCollateral", "offset": 0, @@ -539,7 +539,7 @@ "type": "t_uint256" }, { - "astId": 8679, + "astId": 10197, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "configurationNumber", "offset": 0, @@ -547,7 +547,7 @@ "type": "t_uint64" }, { - "astId": 8682, + "astId": 10200, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "topDownCheckPeriod", "offset": 8, @@ -555,7 +555,7 @@ "type": "t_uint64" }, { - "astId": 8685, + "astId": 10203, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "bottomUpCheckPeriod", "offset": 16, @@ -563,7 +563,7 @@ "type": "t_uint64" }, { - "astId": 8688, + "astId": 10206, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "minValidators", "offset": 24, @@ -571,7 +571,7 @@ "type": "t_uint64" }, { - "astId": 8691, + "astId": 10209, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "name", "offset": 0, @@ -579,7 +579,7 @@ "type": "t_bytes32" }, { - "astId": 8693, + "astId": 10211, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "currentSubnetHash", "offset": 0, @@ -587,7 +587,7 @@ "type": "t_bytes32" }, { - "astId": 8696, + "astId": 10214, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "prevExecutedCheckpointHash", "offset": 0, @@ -595,7 +595,7 @@ "type": "t_bytes32" }, { - "astId": 8699, + "astId": 10217, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "ipcGatewayAddr", "offset": 0, @@ -603,46 +603,46 @@ "type": "t_address" }, { - "astId": 8703, + "astId": 10221, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "status", "offset": 20, "slot": "13", - "type": "t_enum(Status)4025" + "type": "t_enum(Status)4994" }, { - "astId": 8707, + "astId": 10225, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "validators", "offset": 0, "slot": "14", - "type": "t_struct(AddressSet)2473_storage" + "type": "t_struct(AddressSet)3420_storage" }, { - "astId": 8711, + "astId": 10229, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "parentId", "offset": 0, "slot": "16", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 8715, + "astId": 10233, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "consensus", "offset": 0, "slot": "18", - "type": "t_enum(ConsensusType)4011" + "type": "t_enum(ConsensusType)4980" } ], "numberOfBytes": "608" }, - "t_struct(SubnetID)10260_storage": { + "t_struct(SubnetID)11808_storage": { "encoding": "inplace", "label": "struct SubnetID", "members": [ { - "astId": 10255, + "astId": 11803, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "root", "offset": 0, @@ -650,7 +650,7 @@ "type": "t_uint64" }, { - "astId": 10259, + "astId": 11807, "contract": "src/SubnetActorDiamond.sol:SubnetActorDiamond", "label": "route", "offset": 0, diff --git a/.storage-layouts/SubnetActorModifiers.json b/.storage-layouts/SubnetActorModifiers.json index bad7fddde..6c3b628af 100644 --- a/.storage-layouts/SubnetActorModifiers.json +++ b/.storage-layouts/SubnetActorModifiers.json @@ -1,12 +1,12 @@ { "storage": [ { - "astId": 8728, + "astId": 10246, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "s", "offset": 0, "slot": "0", - "type": "t_struct(SubnetActorStorage)8716_storage" + "type": "t_struct(SubnetActorStorage)10234_storage" } ], "types": { @@ -27,14 +27,14 @@ "label": "bytes32[]", "numberOfBytes": "32" }, - "t_array(t_struct(ChildCheck)10149_storage)dyn_storage": { - "base": "t_struct(ChildCheck)10149_storage", + "t_array(t_struct(ChildCheck)11697_storage)dyn_storage": { + "base": "t_struct(ChildCheck)11697_storage", "encoding": "dynamic_array", "label": "struct ChildCheck[]", "numberOfBytes": "32" }, - "t_array(t_struct(CrossMsg)10155_storage)dyn_storage": { - "base": "t_struct(CrossMsg)10155_storage", + "t_array(t_struct(CrossMsg)11703_storage)dyn_storage": { + "base": "t_struct(CrossMsg)11703_storage", "encoding": "dynamic_array", "label": "struct CrossMsg[]", "numberOfBytes": "32" @@ -59,12 +59,12 @@ "label": "bytes", "numberOfBytes": "32" }, - "t_enum(ConsensusType)4011": { + "t_enum(ConsensusType)4980": { "encoding": "inplace", "label": "enum ConsensusType", "numberOfBytes": "1" }, - "t_enum(Status)4025": { + "t_enum(Status)4994": { "encoding": "inplace", "label": "enum Status", "numberOfBytes": "1" @@ -83,12 +83,12 @@ "numberOfBytes": "32", "value": "t_string_storage" }, - "t_mapping(t_address,t_struct(FvmAddress)10234_storage)": { + "t_mapping(t_address,t_struct(FvmAddress)11782_storage)": { "encoding": "mapping", "key": "t_address", "label": "mapping(address => struct FvmAddress)", "numberOfBytes": "32", - "value": "t_struct(FvmAddress)10234_storage" + "value": "t_struct(FvmAddress)11782_storage" }, "t_mapping(t_address,t_uint256)": { "encoding": "mapping", @@ -97,12 +97,12 @@ "numberOfBytes": "32", "value": "t_uint256" }, - "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_bytes32", "label": "mapping(bytes32 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" }, "t_mapping(t_bytes32,t_uint256)": { "encoding": "mapping", @@ -125,54 +125,54 @@ "numberOfBytes": "32", "value": "t_mapping(t_bytes32,t_uint256)" }, - "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)": { + "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct BottomUpCheckpoint)", "numberOfBytes": "32", - "value": "t_struct(BottomUpCheckpoint)10135_storage" + "value": "t_struct(BottomUpCheckpoint)11653_storage" }, - "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)10212_storage)": { + "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)11760_storage)": { "encoding": "mapping", "key": "t_uint64", "label": "mapping(uint64 => struct EpochVoteBottomUpSubmission)", "numberOfBytes": "32", - "value": "t_struct(EpochVoteBottomUpSubmission)10212_storage" + "value": "t_struct(EpochVoteBottomUpSubmission)11760_storage" }, "t_string_storage": { "encoding": "bytes", "label": "string", "numberOfBytes": "32" }, - "t_struct(AddressSet)2473_storage": { + "t_struct(AddressSet)3420_storage": { "encoding": "inplace", "label": "struct EnumerableSet.AddressSet", "members": [ { - "astId": 2472, + "astId": 3419, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "_inner", "offset": 0, "slot": "0", - "type": "t_struct(Set)2158_storage" + "type": "t_struct(Set)3105_storage" } ], "numberOfBytes": "64" }, - "t_struct(BottomUpCheckpoint)10135_storage": { + "t_struct(BottomUpCheckpoint)11653_storage": { "encoding": "inplace", "label": "struct BottomUpCheckpoint", "members": [ { - "astId": 10118, + "astId": 11636, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10120, + "astId": 11638, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "epoch", "offset": 0, @@ -180,7 +180,7 @@ "type": "t_uint64" }, { - "astId": 10122, + "astId": 11640, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "fee", "offset": 0, @@ -188,23 +188,23 @@ "type": "t_uint256" }, { - "astId": 10126, + "astId": 11644, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "crossMsgs", "offset": 0, "slot": "4", - "type": "t_array(t_struct(CrossMsg)10155_storage)dyn_storage" + "type": "t_array(t_struct(CrossMsg)11703_storage)dyn_storage" }, { - "astId": 10130, + "astId": 11648, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "children", "offset": 0, "slot": "5", - "type": "t_array(t_struct(ChildCheck)10149_storage)dyn_storage" + "type": "t_array(t_struct(ChildCheck)11697_storage)dyn_storage" }, { - "astId": 10132, + "astId": 11650, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "prevHash", "offset": 0, @@ -212,7 +212,7 @@ "type": "t_bytes32" }, { - "astId": 10134, + "astId": 11652, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "proof", "offset": 0, @@ -222,20 +222,20 @@ ], "numberOfBytes": "256" }, - "t_struct(ChildCheck)10149_storage": { + "t_struct(ChildCheck)11697_storage": { "encoding": "inplace", "label": "struct ChildCheck", "members": [ { - "astId": 10145, + "astId": 11693, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "source", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10148, + "astId": 11696, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "checks", "offset": 0, @@ -245,20 +245,20 @@ ], "numberOfBytes": "96" }, - "t_struct(CrossMsg)10155_storage": { + "t_struct(CrossMsg)11703_storage": { "encoding": "inplace", "label": "struct CrossMsg", "members": [ { - "astId": 10152, + "astId": 11700, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "message", "offset": 0, "slot": "0", - "type": "t_struct(StorableMsg)10170_storage" + "type": "t_struct(StorableMsg)11718_storage" }, { - "astId": 10154, + "astId": 11702, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "wrapped", "offset": 0, @@ -268,35 +268,35 @@ ], "numberOfBytes": "384" }, - "t_struct(EpochVoteBottomUpSubmission)10212_storage": { + "t_struct(EpochVoteBottomUpSubmission)11760_storage": { "encoding": "inplace", "label": "struct EpochVoteBottomUpSubmission", "members": [ { - "astId": 10206, + "astId": 11754, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "vote", "offset": 0, "slot": "0", - "type": "t_struct(EpochVoteSubmission)10194_storage" + "type": "t_struct(EpochVoteSubmission)11742_storage" }, { - "astId": 10211, + "astId": 11759, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "submissions", "offset": 0, "slot": "5", - "type": "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_bytes32,t_struct(BottomUpCheckpoint)11653_storage)" } ], "numberOfBytes": "192" }, - "t_struct(EpochVoteSubmission)10194_storage": { + "t_struct(EpochVoteSubmission)11742_storage": { "encoding": "inplace", "label": "struct EpochVoteSubmission", "members": [ { - "astId": 10177, + "astId": 11725, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "nonce", "offset": 0, @@ -304,7 +304,7 @@ "type": "t_uint256" }, { - "astId": 10179, + "astId": 11727, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "totalSubmissionWeight", "offset": 0, @@ -312,7 +312,7 @@ "type": "t_uint256" }, { - "astId": 10181, + "astId": 11729, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "mostVotedSubmission", "offset": 0, @@ -320,7 +320,7 @@ "type": "t_bytes32" }, { - "astId": 10187, + "astId": 11735, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "submitters", "offset": 0, @@ -328,7 +328,7 @@ "type": "t_mapping(t_uint256,t_mapping(t_address,t_bool))" }, { - "astId": 10193, + "astId": 11741, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "submissionWeights", "offset": 0, @@ -338,12 +338,12 @@ ], "numberOfBytes": "160" }, - "t_struct(FvmAddress)10234_storage": { + "t_struct(FvmAddress)11782_storage": { "encoding": "inplace", "label": "struct FvmAddress", "members": [ { - "astId": 10231, + "astId": 11779, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "addrType", "offset": 0, @@ -351,7 +351,7 @@ "type": "t_uint8" }, { - "astId": 10233, + "astId": 11781, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "payload", "offset": 0, @@ -361,35 +361,35 @@ ], "numberOfBytes": "64" }, - "t_struct(IPCAddress)10287_storage": { + "t_struct(IPCAddress)11835_storage": { "encoding": "inplace", "label": "struct IPCAddress", "members": [ { - "astId": 10283, + "astId": 11831, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "subnetId", "offset": 0, "slot": "0", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 10286, + "astId": 11834, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "rawAddress", "offset": 0, "slot": "2", - "type": "t_struct(FvmAddress)10234_storage" + "type": "t_struct(FvmAddress)11782_storage" } ], "numberOfBytes": "128" }, - "t_struct(Set)2158_storage": { + "t_struct(Set)3105_storage": { "encoding": "inplace", "label": "struct EnumerableSet.Set", "members": [ { - "astId": 2153, + "astId": 3100, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "_values", "offset": 0, @@ -397,7 +397,7 @@ "type": "t_array(t_bytes32)dyn_storage" }, { - "astId": 2157, + "astId": 3104, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "_indexes", "offset": 0, @@ -407,28 +407,28 @@ ], "numberOfBytes": "64" }, - "t_struct(StorableMsg)10170_storage": { + "t_struct(StorableMsg)11718_storage": { "encoding": "inplace", "label": "struct StorableMsg", "members": [ { - "astId": 10158, + "astId": 11706, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "from", "offset": 0, "slot": "0", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10161, + "astId": 11709, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "to", "offset": 0, "slot": "4", - "type": "t_struct(IPCAddress)10287_storage" + "type": "t_struct(IPCAddress)11835_storage" }, { - "astId": 10163, + "astId": 11711, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "value", "offset": 0, @@ -436,7 +436,7 @@ "type": "t_uint256" }, { - "astId": 10165, + "astId": 11713, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "nonce", "offset": 0, @@ -444,7 +444,7 @@ "type": "t_uint64" }, { - "astId": 10167, + "astId": 11715, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "method", "offset": 8, @@ -452,7 +452,7 @@ "type": "t_bytes4" }, { - "astId": 10169, + "astId": 11717, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "params", "offset": 0, @@ -462,20 +462,20 @@ ], "numberOfBytes": "352" }, - "t_struct(SubnetActorStorage)8716_storage": { + "t_struct(SubnetActorStorage)10234_storage": { "encoding": "inplace", "label": "struct SubnetActorStorage", "members": [ { - "astId": 8640, + "astId": 10158, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "epochVoteSubmissions", "offset": 0, "slot": "0", - "type": "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)10212_storage)" + "type": "t_mapping(t_uint64,t_struct(EpochVoteBottomUpSubmission)11760_storage)" }, { - "astId": 8645, + "astId": 10163, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "stake", "offset": 0, @@ -483,7 +483,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 8650, + "astId": 10168, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "accumulatedRewards", "offset": 0, @@ -491,7 +491,7 @@ "type": "t_mapping(t_address,t_uint256)" }, { - "astId": 8655, + "astId": 10173, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "validatorNetAddresses", "offset": 0, @@ -499,23 +499,23 @@ "type": "t_mapping(t_address,t_string_storage)" }, { - "astId": 8661, + "astId": 10179, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "validatorWorkerAddresses", "offset": 0, "slot": "4", - "type": "t_mapping(t_address,t_struct(FvmAddress)10234_storage)" + "type": "t_mapping(t_address,t_struct(FvmAddress)11782_storage)" }, { - "astId": 8667, + "astId": 10185, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "committedCheckpoints", "offset": 0, "slot": "5", - "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)10135_storage)" + "type": "t_mapping(t_uint64,t_struct(BottomUpCheckpoint)11653_storage)" }, { - "astId": 8670, + "astId": 10188, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "genesis", "offset": 0, @@ -523,7 +523,7 @@ "type": "t_bytes_storage" }, { - "astId": 8673, + "astId": 10191, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "totalStake", "offset": 0, @@ -531,7 +531,7 @@ "type": "t_uint256" }, { - "astId": 8676, + "astId": 10194, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "minActivationCollateral", "offset": 0, @@ -539,7 +539,7 @@ "type": "t_uint256" }, { - "astId": 8679, + "astId": 10197, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "configurationNumber", "offset": 0, @@ -547,7 +547,7 @@ "type": "t_uint64" }, { - "astId": 8682, + "astId": 10200, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "topDownCheckPeriod", "offset": 8, @@ -555,7 +555,7 @@ "type": "t_uint64" }, { - "astId": 8685, + "astId": 10203, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "bottomUpCheckPeriod", "offset": 16, @@ -563,7 +563,7 @@ "type": "t_uint64" }, { - "astId": 8688, + "astId": 10206, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "minValidators", "offset": 24, @@ -571,7 +571,7 @@ "type": "t_uint64" }, { - "astId": 8691, + "astId": 10209, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "name", "offset": 0, @@ -579,7 +579,7 @@ "type": "t_bytes32" }, { - "astId": 8693, + "astId": 10211, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "currentSubnetHash", "offset": 0, @@ -587,7 +587,7 @@ "type": "t_bytes32" }, { - "astId": 8696, + "astId": 10214, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "prevExecutedCheckpointHash", "offset": 0, @@ -595,7 +595,7 @@ "type": "t_bytes32" }, { - "astId": 8699, + "astId": 10217, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "ipcGatewayAddr", "offset": 0, @@ -603,46 +603,46 @@ "type": "t_address" }, { - "astId": 8703, + "astId": 10221, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "status", "offset": 20, "slot": "13", - "type": "t_enum(Status)4025" + "type": "t_enum(Status)4994" }, { - "astId": 8707, + "astId": 10225, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "validators", "offset": 0, "slot": "14", - "type": "t_struct(AddressSet)2473_storage" + "type": "t_struct(AddressSet)3420_storage" }, { - "astId": 8711, + "astId": 10229, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "parentId", "offset": 0, "slot": "16", - "type": "t_struct(SubnetID)10260_storage" + "type": "t_struct(SubnetID)11808_storage" }, { - "astId": 8715, + "astId": 10233, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "consensus", "offset": 0, "slot": "18", - "type": "t_enum(ConsensusType)4011" + "type": "t_enum(ConsensusType)4980" } ], "numberOfBytes": "608" }, - "t_struct(SubnetID)10260_storage": { + "t_struct(SubnetID)11808_storage": { "encoding": "inplace", "label": "struct SubnetID", "members": [ { - "astId": 10255, + "astId": 11803, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "root", "offset": 0, @@ -650,7 +650,7 @@ "type": "t_uint64" }, { - "astId": 10259, + "astId": 11807, "contract": "src/lib/LibSubnetActorStorage.sol:SubnetActorModifiers", "label": "route", "offset": 0, diff --git a/src/gateway/GatewayGetterFacet.sol b/src/gateway/GatewayGetterFacet.sol index 6f868669b..3ab2c887b 100644 --- a/src/gateway/GatewayGetterFacet.sol +++ b/src/gateway/GatewayGetterFacet.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.19; -import {CrossMsg, BottomUpCheckpoint, StorableMsg, ParentFinality} from "../structs/Checkpoint.sol"; +import {CrossMsg, BottomUpCheckpoint, StorableMsg, ParentFinality, CheckpointInfo} from "../structs/Checkpoint.sol"; import {EpochVoteTopDownSubmission} from "../structs/EpochVoteSubmission.sol"; import {SubnetID, Subnet} from "../structs/Subnet.sol"; import {Membership} from "../structs/Validator.sol"; @@ -184,4 +184,14 @@ contract GatewayGetterFacet { function getCurrentTotalWeight() public view returns (uint256) { return s.currentMembership.totalWeight; } + + /// @notice get the checkpoint information corresponding to the block height + function getCheckpointInfo(uint64 h) public view returns (CheckpointInfo memory) { + return s.bottomUpCheckpointInfo[h]; + } + + /// @notice get the checkpoint current weight corresponding to the block height + function getCheckpointCurrentWeight(uint64 h) public view returns (uint256) { + return s.bottomUpCheckpointInfo[h].currentWeight; + } } diff --git a/src/gateway/GatewayRouterFacet.sol b/src/gateway/GatewayRouterFacet.sol index ee9a42f55..b2fce821f 100644 --- a/src/gateway/GatewayRouterFacet.sol +++ b/src/gateway/GatewayRouterFacet.sol @@ -266,7 +266,7 @@ contract GatewayRouterFacet is GatewayActorModifiers { if (s.bottomUpCheckpoints[checkpoint.blockHeight].blockHeight > 0) { revert CheckpointAlreadyExists(); } - if (s.bottomUpCheckpointInfo[checkpoint.blockHeight].rootHash.length > 0) { + if (s.bottomUpCheckpointInfo[checkpoint.blockHeight].threshold > 0) { revert CheckpointInfoAlreadyExists(); } if (membershipWeight == 0) { diff --git a/test/GatewayDiamond.t.sol b/test/GatewayDiamond.t.sol index 6ae8fb971..0c87a2303 100644 --- a/test/GatewayDiamond.t.sol +++ b/test/GatewayDiamond.t.sol @@ -13,7 +13,8 @@ import {IDiamondLoupe} from "../src/interfaces/IDiamondLoupe.sol"; import {IDiamondCut} from "../src/interfaces/IDiamondCut.sol"; import {IPCMsgType} from "../src/enums/IPCMsgType.sol"; import {ISubnetActor} from "../src/interfaces/ISubnetActor.sol"; -import {CrossMsg, BottomUpCheckpoint, TopDownCheckpoint, StorableMsg, ChildCheck, ParentFinality} from "../src/structs/Checkpoint.sol"; +import {CheckpointInfo} from "../src/structs/Checkpoint.sol"; +import {CrossMsg, BottomUpCheckpoint, BottomUpCheckpointNew, TopDownCheckpoint, StorableMsg, ChildCheck, ParentFinality} from "../src/structs/Checkpoint.sol"; import {FvmAddress} from "../src/structs/FvmAddress.sol"; import {SubnetID, Subnet, IPCAddress} from "../src/structs/Subnet.sol"; import {ValidatorSet, ValidatorInfo, Membership, Validator} from "../src/structs/Validator.sol"; @@ -32,6 +33,7 @@ import {GatewayRouterFacet} from "../src/gateway/GatewayRouterFacet.sol"; import {SubnetActorManagerFacet} from "../src/subnet/SubnetActorManagerFacet.sol"; import {SubnetActorGetterFacet} from "../src/subnet/SubnetActorGetterFacet.sol"; import {DiamondLoupeFacet} from "../src/diamond/DiamondLoupeFacet.sol"; +import {MerkleTreeHelper} from "./MerkleTreeHelper.sol"; contract GatewayDiamondDeploymentTest is StdInvariant, Test { using SubnetIDHelper for SubnetID; @@ -1416,6 +1418,82 @@ contract GatewayDiamondDeploymentTest is StdInvariant, Test { require(curMb.totalWeight == 600, "curMb.totalWeight correct"); } + function testGatewayDiamond_adding_bottomUp_signatures() public { + (uint256[] memory privKeys, address[] memory addrs, uint256[] memory weights) = setupValidatorsForCheckpoint(); + + (bytes32 membershipRoot, bytes32[][] memory membershipProofs) = MerkleTreeHelper + .createMerkleProofsForValidators(addrs, weights); + + BottomUpCheckpointNew memory checkpoint = BottomUpCheckpointNew({ + subnetID: gwGetter.getNetworkName(), + blockHeight: 1, + nextConfigurationNumber: 1, + crossMessagesHash: keccak256("messages") + }); + + // create a checkpoint + vm.startPrank(FilAddress.SYSTEM_ACTOR); + gwRouter.createBottomUpCheckpoint(checkpoint, membershipRoot, 10); + vm.stopPrank(); + + // adds signatures + + uint8 v; + bytes32 r; + bytes32 s; + bytes memory signature; + + for (uint64 i = 0; i < 3; i++) { + (v, r, s) = vm.sign(privKeys[i], keccak256(abi.encode(checkpoint))); + signature = abi.encodePacked(r, s, v); + + vm.startPrank(vm.addr(privKeys[i])); + gwRouter.addCheckpointSignature(1, membershipProofs[i], weights[i], signature); + vm.stopPrank(); + } + + require(gwGetter.getCheckpointCurrentWeight(1) == totalWeight(weights), "checkpoint weight was updated"); + } + + function testGatewayDiamond_adding_bottomUp_signatures_notauthorized() public { + (uint256[] memory privKeys, address[] memory addrs, uint256[] memory weights) = setupValidatorsForCheckpoint(); + + (bytes32 membershipRoot, bytes32[][] memory membershipProofs) = MerkleTreeHelper + .createMerkleProofsForValidators(addrs, weights); + + BottomUpCheckpointNew memory checkpoint = BottomUpCheckpointNew({ + subnetID: gwGetter.getNetworkName(), + blockHeight: 1, + nextConfigurationNumber: 1, + crossMessagesHash: keccak256("messages") + }); + + // create a checkpoint + vm.startPrank(FilAddress.SYSTEM_ACTOR); + gwRouter.createBottomUpCheckpoint(checkpoint, membershipRoot, 10); + vm.stopPrank(); + + uint8 v; + bytes32 r; + bytes32 s; + bytes memory signature; + + (v, r, s) = vm.sign(privKeys[0], keccak256(abi.encode(checkpoint))); + signature = abi.encodePacked(r, s, v); + + vm.startPrank(vm.addr(privKeys[0])); + vm.expectRevert(); + gwRouter.addCheckpointSignature(1, membershipProofs[0], weights[1], signature); + vm.stopPrank(); + } + + function totalWeight(uint256[] memory weights) internal pure returns (uint256 sum) { + for (uint64 i = 0; i < 3; i++) { + sum += weights[i]; + } + return sum; + } + function setupValidators() internal returns (FvmAddress[] memory validators, address[] memory addresses) { validators = new FvmAddress[](3); validators[0] = FvmAddressHelper.from(vm.addr(100)); @@ -1446,6 +1524,31 @@ contract GatewayDiamondDeploymentTest is StdInvariant, Test { gwRouter.commitParentFinality(finality, n, validators, weights); } + function setupValidatorsForCheckpoint() + internal + returns (uint256[] memory validatorKeys, address[] memory addresses, uint256[] memory weights) + { + validatorKeys = new uint256[](3); + validatorKeys[0] = 100; + validatorKeys[1] = 200; + validatorKeys[2] = 300; + + addresses = new address[](3); + addresses[0] = vm.addr(validatorKeys[0]); + addresses[1] = vm.addr(validatorKeys[1]); + addresses[2] = vm.addr(validatorKeys[2]); + + weights = new uint256[](3); + vm.deal(vm.addr(validatorKeys[0]), 1); + vm.deal(vm.addr(validatorKeys[1]), 1); + vm.deal(vm.addr(validatorKeys[2]), 1); + + weights = new uint256[](3); + weights[0] = 100; + weights[1] = 101; + weights[2] = 300; + } + function addValidator(address validator) internal { addValidator(validator, 100); } diff --git a/test/MerkleTree.t.sol b/test/MerkleTree.t.sol index 80bb34a13..e69e4a442 100644 --- a/test/MerkleTree.t.sol +++ b/test/MerkleTree.t.sol @@ -38,4 +38,4 @@ contract MerkleTree is Test { valid = MerkleProof.verify({proof: proofs[0], root: root, leaf: leaf}); require(!valid, "invalid leaf is not in the tree"); } -} \ No newline at end of file +} diff --git a/test/MerkleTreeHelper.sol b/test/MerkleTreeHelper.sol index 0738e51cb..b282b6cfd 100644 --- a/test/MerkleTreeHelper.sol +++ b/test/MerkleTreeHelper.sol @@ -1,11 +1,13 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity 0.8.19; -import { Merkle } from "murky/Merkle.sol"; +import {Merkle} from "murky/Merkle.sol"; library MerkleTreeHelper { - - function createMerkleProofsForValidators(address[] memory addrs, uint256[] memory weight) internal returns (bytes32, bytes32[][] memory) { + function createMerkleProofsForValidators( + address[] memory addrs, + uint256[] memory weight + ) internal returns (bytes32, bytes32[][] memory) { Merkle merkleTree = new Merkle(); if (addrs.length != weight.length) { @@ -29,4 +31,4 @@ library MerkleTreeHelper { return (root, proofs); } -} \ No newline at end of file +} From 083109dfdbc26874e10d61bdbf93a562e170bbcf Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Thu, 21 Sep 2023 11:12:38 +0200 Subject: [PATCH 13/14] more tests --- src/GatewayDiamond.sol | 2 +- src/lib/LibGatewayActorStorage.sol | 2 +- test/GatewayDiamond.t.sol | 41 ++++++++++++++++++++++++++++-- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/GatewayDiamond.sol b/src/GatewayDiamond.sol index acc6b4b27..638d15912 100644 --- a/src/GatewayDiamond.sol +++ b/src/GatewayDiamond.sol @@ -36,7 +36,7 @@ contract GatewayDiamond { revert InvalidSubmissionPeriod(); } - if (params.majorityPercentage > 100) { + if (params.majorityPercentage < 51 || params.majorityPercentage > 100) { revert InvalidMajorityPercentage(); } diff --git a/src/lib/LibGatewayActorStorage.sol b/src/lib/LibGatewayActorStorage.sol index d9d4ebebd..b44e544b2 100644 --- a/src/lib/LibGatewayActorStorage.sol +++ b/src/lib/LibGatewayActorStorage.sol @@ -55,7 +55,7 @@ struct GatewayActorStorage { uint256 minStake; /// @notice fee amount charged per cross message uint256 crossMsgFee; - /// @notice majority percentage value + /// @notice majority percentage value (must be greater than or equal to 51) uint8 majorityPercentage; /// @notice nonce for bottom-up messages uint64 bottomUpNonce; diff --git a/test/GatewayDiamond.t.sol b/test/GatewayDiamond.t.sol index 0c87a2303..341c74589 100644 --- a/test/GatewayDiamond.t.sol +++ b/test/GatewayDiamond.t.sol @@ -1418,7 +1418,44 @@ contract GatewayDiamondDeploymentTest is StdInvariant, Test { require(curMb.totalWeight == 600, "curMb.totalWeight correct"); } - function testGatewayDiamond_adding_bottomUp_signatures() public { + function testGatewayDiamond_createBottomUpCheckpoint() public { + (, address[] memory addrs, uint256[] memory weights) = setupValidatorsForCheckpoint(); + + (bytes32 membershipRoot, ) = MerkleTreeHelper.createMerkleProofsForValidators(addrs, weights); + + BottomUpCheckpointNew memory checkpoint = BottomUpCheckpointNew({ + subnetID: gwGetter.getNetworkName(), + blockHeight: 1, + nextConfigurationNumber: 1, + crossMessagesHash: keccak256("messages") + }); + + // failed to create a checkpoint with zero membership weight + vm.startPrank(FilAddress.SYSTEM_ACTOR); + vm.expectRevert(ZeroMembershipWeight.selector); + gwRouter.createBottomUpCheckpoint(checkpoint, membershipRoot, 0); + vm.stopPrank(); + + // create a checkpoint + vm.startPrank(FilAddress.SYSTEM_ACTOR); + gwRouter.createBottomUpCheckpoint(checkpoint, membershipRoot, 10); + vm.stopPrank(); + + // failed to create a checkpoint with the same height + checkpoint = BottomUpCheckpointNew({ + subnetID: gwGetter.getNetworkName(), + blockHeight: 1, + nextConfigurationNumber: 2, + crossMessagesHash: keccak256("newmessages") + }); + + vm.startPrank(FilAddress.SYSTEM_ACTOR); + vm.expectRevert(CheckpointAlreadyExists.selector); + gwRouter.createBottomUpCheckpoint(checkpoint, membershipRoot, 10); + vm.stopPrank(); + } + + function testGatewayDiamond_addCheckpointSignature() public { (uint256[] memory privKeys, address[] memory addrs, uint256[] memory weights) = setupValidatorsForCheckpoint(); (bytes32 membershipRoot, bytes32[][] memory membershipProofs) = MerkleTreeHelper @@ -1455,7 +1492,7 @@ contract GatewayDiamondDeploymentTest is StdInvariant, Test { require(gwGetter.getCheckpointCurrentWeight(1) == totalWeight(weights), "checkpoint weight was updated"); } - function testGatewayDiamond_adding_bottomUp_signatures_notauthorized() public { + function testGatewayDiamond_addCheckpointSignature_notAuthorized() public { (uint256[] memory privKeys, address[] memory addrs, uint256[] memory weights) = setupValidatorsForCheckpoint(); (bytes32 membershipRoot, bytes32[][] memory membershipProofs) = MerkleTreeHelper From 4190c00ead0a7740335a88f08cbd86b05a1c0620 Mon Sep 17 00:00:00 2001 From: Denis Kolegov Date: Thu, 21 Sep 2023 12:57:18 +0200 Subject: [PATCH 14/14] fix error --- src/GatewayDiamond.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GatewayDiamond.sol b/src/GatewayDiamond.sol index 638d15912..a12e7a8d6 100644 --- a/src/GatewayDiamond.sol +++ b/src/GatewayDiamond.sol @@ -3,14 +3,13 @@ pragma solidity 0.8.19; import {GatewayActorStorage} from "./lib/LibGatewayActorStorage.sol"; import {IDiamond} from "./interfaces/IDiamond.sol"; -import {InvalidCollateral, InvalidSubmissionPeriod} from "./errors/IPCErrors.sol"; +import {InvalidCollateral, InvalidSubmissionPeriod, InvalidMajorityPercentage} from "./errors/IPCErrors.sol"; import {LibDiamond} from "./lib/LibDiamond.sol"; import {LibVoting} from "./lib/LibVoting.sol"; import {SubnetID} from "./structs/Subnet.sol"; import {SubnetIDHelper} from "./lib/SubnetIDHelper.sol"; error FunctionNotFound(bytes4 _functionSelector); -error InvalidMajorityPercentage(); contract GatewayDiamond { GatewayActorStorage internal s;