diff --git a/abi-bindings/go/staking/ERC20TokenStakingManager/ERC20TokenStakingManager.go b/abi-bindings/go/staking/ERC20TokenStakingManager/ERC20TokenStakingManager.go new file mode 100644 index 000000000..ee3bb754e --- /dev/null +++ b/abi-bindings/go/staking/ERC20TokenStakingManager/ERC20TokenStakingManager.go @@ -0,0 +1,1198 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package erc20tokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// StakingManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type StakingManagerSettings struct { + PChainBlockchainID [32]byte + SubnetID [32]byte + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MaximumHourlyChurn uint8 + RewardCalculator common.Address +} + +// ERC20TokenStakingManagerMetaData contains all meta data concerning the ERC20TokenStakingManager contract. +var ERC20TokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"init\",\"type\":\"uint8\",\"internalType\":\"enumICMInitializable\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"completeEndValidation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"setWeightMessageType\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeValidatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"settings\",\"type\":\"tuple\",\"internalType\":\"structStakingManagerSettings\",\"components\":[{\"name\":\"pChainBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"subnetID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"minimumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maximumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minimumStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maximumHourlyChurn\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"rewardCalculator\",\"type\":\"address\",\"internalType\":\"contractIRewardCalculator\"}]},{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"contractIERC20\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndValidation\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorRegistration\",\"inputs\":[{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"blsPublicKey\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendEndValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendRegisterValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"valueToWeight\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"weightToValue\",\"inputs\":[{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerValidationMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodEnded\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodRegistered\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRemovalInitialized\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"uptime\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"SafeERC20FailedOperation\",\"inputs\":[{\"name\":\"token\",\"type\":\"address\",\"internalType\":\"address\"}]}]", + Bin: "0x608060405234801561000f575f80fd5b506040516134a93803806134a983398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b61335c8061014d5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c8063872fda6411610063578063872fda641461012b578063a3a65e481461013e578063b771b3bc14610151578063bee0a03f14610177578063fdf94a1a1461018a575f80fd5b80630322ed981461009f5780632e2194d8146100b45780635d0d7466146100e457806362065856146100f757806376f7862114610118575b5f80fd5b6100b26100ad366004612a12565b61019d565b005b6100c76100c2366004612a12565b610393565b6040516001600160401b0390911681526020015b60405180910390f35b6100b26100f2366004612a3d565b6103a9565b61010a610105366004612a95565b6104b7565b6040519081526020016100db565b6100b2610126366004612ad5565b6104d0565b61010a610139366004612ba2565b610a50565b6100b261014c366004612c3e565b610a68565b61015f6005600160991b0181565b6040516001600160a01b0390911681526020016100db565b6100b2610185366004612a12565b610cf5565b6100b2610198366004612c57565b610e09565b5f8181527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60860205260408082208151610120810190925280545f8051602061333083398151915293929190829060ff1660058111156101fe576101fe612c81565b600581111561020f5761020f612c81565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301546001600160a01b03811660c084015260ff600160a01b820416151560e0840152600160a81b90041661010090910152909150815160058111156102a6576102a6612c81565b1461030e5760405162461bcd60e51b815260206004820152602d60248201527f5374616b696e674d616e616765723a2056616c696461746f72206e6f7420706560448201526c1b991a5b99c81c995b5bdd985b609a1b60648201526084015b60405180910390fd5b5f61031f848361010001515f611230565b60405163ee5b48eb60e01b81529091506005600160991b019063ee5b48eb9061034c908490600401612cb7565b6020604051808303815f875af1158015610368573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038c9190612ce9565b5050505050565b5f6103a364e8d4a5100083612d28565b92915050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156103ed5750825b90505f826001600160401b031660011480156104085750303b155b905081158015610416575080155b156104345760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff19166001178555831561045e57845460ff60401b1916600160401b1785555b610468878761144d565b83156104ae57845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b5f6103a36001600160401b03831664e8d4a51000612d3b565b5f8381527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60860205260408082208151610120810190925280545f8051602061333083398151915293929190829060ff16600581111561053157610531612c81565b600581111561054257610542612c81565b8152600182015460208201526002808301546001600160401b038082166040850152600160401b820481166060850152600160801b820481166080850152600160c01b909104811660a08401526003909301546001600160a01b03811660c084015260ff600160a01b820416151560e0840152600160a81b900490921661010090910152909150815160058111156105dc576105dc612c81565b146106355760405162461bcd60e51b8152602060048201526024808201527f5374616b696e674d616e616765723a2056616c696461746f72206e6f742061636044820152637469766560e01b6064820152608401610305565b60c08101516001600160a01b0316336001600160a01b03161461066a5760405162461bcd60e51b815260040161030590612d52565b610677816040015161146b565b60038152426001600160401b031660808201525f8415610850576040516306f8253560e41b815263ffffffff851660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa1580156106da573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526107019190810190612da7565b91509150806107225760405162461bcd60e51b815260040161030590612e79565b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa158015610765573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107899190612ce9565b8251146107a85760405162461bcd60e51b815260040161030590612ebd565b60208201516001600160a01b0316156107d35760405162461bcd60e51b815260040161030590612f04565b5f806107e28460400151611618565b91509150818a1461084a5760405162461bcd60e51b815260206004820152602c60248201527f5374616b696e674d616e616765723a20496e76616c696420757074696d65207660448201526b185b1a59185d1a5bdb88125160a21b6064820152608401610305565b93505050505b6001600160401b03811660a08301525f86815260088401602052604090208251815484929190829060ff1916600183600581111561089057610890612c81565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c08301516003909201805460e0850151610100958601516001600160a01b039095166001600160a81b031990921691909117600160a01b911515919091021767ffffffffffffffff60a81b1916600160a81b93909216929092021790558201515f9061098190889083611230565b60405163ee5b48eb60e01b81529091505f906005600160991b019063ee5b48eb906109b0908590600401612cb7565b6020604051808303815f875af11580156109cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f09190612ce9565b60408581015181516001600160401b03918216815242602082015290861681830152905191925082918a917f530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5919081900360600190a35050505050505050565b5f610a5d848685856117f0565b90505b949350505050565b5f5f805160206133308339815191526040516306f8253560e41b815263ffffffff841660048201529091505f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610ac3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610aea9190810190612da7565b9150915080610b0b5760405162461bcd60e51b815260040161030590612e79565b8254825114610b2c5760405162461bcd60e51b815260040161030590612ebd565b60208201516001600160a01b031615610b575760405162461bcd60e51b815260040161030590612f04565b5f80610b668460400151611d00565b9150915080610bc65760405162461bcd60e51b815260206004820152602660248201527f5374616b696e674d616e616765723a20526567697374726174696f6e206e6f74604482015265081d985b1a5960d21b6064820152608401610305565b5f82815260078601602052604081208054610be090612f51565b9050118015610c12575060015f83815260088701602052604090205460ff166005811115610c1057610c10612c81565b145b610c2e5760405162461bcd60e51b815260040161030590612f89565b5f8281526007860160205260408120610c46916129c8565b5f8281526008860160208181526040808420805460ff191660029081178255810180546001600160401b0342818116600160401b026fffffffffffffffff000000000000000019909316929092178355600190930154875260098c0185528387208990559588905293835292548151931683529082019290925283917ff8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568910160405180910390a2505050505050565b5f8181527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6076020526040812080545f80516020613330833981519152929190610d3d90612f51565b9050118015610d6f575060015f83815260088301602052604090205460ff166005811115610d6d57610d6d612c81565b145b610d8b5760405162461bcd60e51b815260040161030590612f89565b5f82815260078201602052604090819020905163ee5b48eb60e01b81526005600160991b019163ee5b48eb91610dc49190600401612fce565b6020604051808303815f875af1158015610de0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e049190612ce9565b505050565b5f5f805160206133308339815191526040516306f8253560e41b815263ffffffff851660048201529091505f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610e64573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e8b9190810190612da7565b9150915080610eac5760405162461bcd60e51b815260040161030590612e79565b5f8415610f25575f610ec18460400151611ea1565b919350909150506001600160401b03811615610f1f5760405162461bcd60e51b815260206004820181905260248201527f5374616b696e674d616e616765723a20576569676874206d75737420626520306044820152606401610305565b50610f99565b5f610f338460400151611d00565b90925090508015610f975760405162461bcd60e51b815260206004820152602860248201527f5374616b696e674d616e616765723a20526567697374726174696f6e207374696044820152671b1b081d985b1a5960c21b6064820152608401610305565b505b5f818152600885016020526040808220815161012081019092528054829060ff166005811115610fcb57610fcb612c81565b6005811115610fdc57610fdc612c81565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003909201546001600160a01b0380821660c080850191909152600160a01b830460ff16151560e0850152600160a81b9092049093166101009092019190915282015191925016331461108d5760405162461bcd60e51b815260040161030590612d52565b5f6003825160058111156110a3576110a3612c81565b14806110c157506002825160058111156110bf576110bf612c81565b145b156110e457506020808201515f90815260098701909152604081205560046110e8565b5060055b5f83815260088701602052604090208251815484929190829060ff1916600183600581111561111957611119612c81565b0217905550602082015160018201556040808301516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c08401516003909301805460e0860151610100909601516001600160a01b039095166001600160a81b031990911617600160a01b951515959095029490941767ffffffffffffffff60a81b1916600160a81b9390911692909202919091179091555183907f3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8905f90a25050505050505050565b60408051603680825260608281019093525f91906020820181803683370190505090505f5b60028110156112a957611269816001613058565b611274906008612d3b565b5081515f9083908390811061128b5761128b61306b565b60200101906001600160f81b03191690815f1a905350600101611255565b505f5b600481101561130c576112c0816003613058565b6112cb906008612d3b565b6001901c60f81b826112de83600261307f565b815181106112ee576112ee61306b565b60200101906001600160f81b03191690815f1a9053506001016112ac565b505f5b602081101561136e5761132381601f613058565b61132e906008612d3b565b86901c60f81b8261134083600661307f565b815181106113505761135061306b565b60200101906001600160f81b03191690815f1a90535060010161130f565b505f5b60088110156113d957611385816007613058565b611390906008612d3b565b6001600160401b038616901c60f81b826113ab83602661307f565b815181106113bb576113bb61306b565b60200101906001600160f81b03191690815f1a905350600101611371565b505f5b6008811015611444576113f0816007613058565b6113fb906008612d3b565b6001600160401b038516901c60f81b8261141683602e61307f565b815181106114265761142661306b565b60200101906001600160f81b03191690815f1a9053506001016113dc565b50949350505050565b6114556120dc565b61145e82612127565b6114678161214b565b5050565b7fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab604545f8051602061333083398151915290600160e01b900460ff165f036114b0575050565b60408051606081018252600583015480825260068401546001600160401b038082166020850152600160401b9091041692820192909252904290610e10906114f89083613058565b10611514576001600160401b0384166040830152808252611533565b83826040018181516115269190613092565b6001600160401b03169052505b5f82602001518360400151606461154a91906130b9565b61155491906130e4565b600485015490915060ff600160e01b909104811690821611156115d45760405162461bcd60e51b815260206004820152603260248201527f5374616b696e674d616e616765723a204d6178696d756d20686f75726c7920636044820152711a1d5c9b881c985d1948195e18d95959195960721b6064820152608401610305565b5050805160058301556020810151600690920180546040909201516001600160401b03908116600160401b026001600160801b031990931693169290921717905550565b5f808251602e1461163b5760405162461bcd60e51b815260040161030590613109565b5f805b600281101561168a57611652816001613058565b61165d906008612d3b565b61ffff168582815181106116735761167361306b565b016020015160f81c901b919091179060010161163e565b5061ffff8116156116ad5760405162461bcd60e51b815260040161030590613150565b5f805b6004811015611708576116c4816003613058565b6116cf906008612d3b565b63ffffffff16866116e183600261307f565b815181106116f1576116f161306b565b016020015160f81c901b91909117906001016116b0565b5063ffffffff811660041461172f5760405162461bcd60e51b815260040161030590613191565b5f805b60208110156117845761174681601f613058565b611751906008612d3b565b8761175d83600661307f565b8151811061176d5761176d61306b565b016020015160f81c901b9190911790600101611732565b505f805b60088110156117e35761179c816007613058565b6117a7906008612d3b565b6001600160401b0316886117bc83602661307f565b815181106117cc576117cc61306b565b016020015160f81c901b9190911790600101611788565b5090969095509350505050565b5f6117f96121ff565b5f80516020613330833981519152426001600160401b03851611801561183357506001600160401b038416611831426202a30061307f565b115b6118935760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e674d616e616765723a20496e76616c696420726567697374726160448201526a74696f6e2065787069727960a81b6064820152608401610305565b856118e05760405162461bcd60e51b815260206004820152601f60248201527f5374616b696e674d616e616765723a20496e76616c6964206e6f6465204944006044820152606401610305565b5f8681526009820160205260409020541561194c5760405162461bcd60e51b815260206004820152602660248201527f5374616b696e674d616e616765723a204e6f646520494420616c72656164792060448201526561637469766560d01b6064820152608401610305565b82516030146119b15760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e674d616e616765723a20496e76616c696420626c735075626c6960448201526a0c696caf240d8cadccee8d60ab1b6064820152608401610305565b5f6119bb86612249565b90505f6119c782610393565b90506119d28161146b565b8260020154816001600160401b0316101580156119fc57508260030154816001600160401b031611155b611a545760405162461bcd60e51b8152602060048201526024808201527f5374616b696e674d616e616765723a20496e76616c6964207374616b6520616d6044820152631bdd5b9d60e21b6064820152608401610305565b5f80611a9b6040518060a00160405280876001015481526020018c8152602001856001600160401b031681526020018a6001600160401b031681526020018981525061227f565b5f82815260078801602052604090209193509150611ab9828261321a565b5060405163ee5b48eb60e01b81525f906005600160991b019063ee5b48eb90611ae6908590600401612cb7565b6020604051808303815f875af1158015611b02573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b269190612ce9565b6040805161012081019091529091508060018152602081018d90526001600160401b03861660408201525f606082018190526080820181905260a082015260c001336001600160a01b031681525f6020808301829052604092830182905286825260088a0190522081518154829060ff19166001836005811115611bac57611bac612c81565b021790555060208281015160018301556040808401516002840180546060870151608088015160a08901516001600160401b03908116600160c01b026001600160c01b03928216600160801b02929092166001600160801b03938216600160401b026001600160801b03199095169682169690961793909317919091169390931792909217905560c08501516003909401805460e0870151610100909701518316600160a81b0267ffffffffffffffff60a81b19971515600160a01b026001600160a81b03199092166001600160a01b039097169690961717959095169390931790935582518783168152918c169082015282918d9186917f79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e910160405180910390a45090945050505050610a6060017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f808251602714611d235760405162461bcd60e51b815260040161030590613109565b5f805b6002811015611d7257611d3a816001613058565b611d45906008612d3b565b61ffff16858281518110611d5b57611d5b61306b565b016020015160f81c901b9190911790600101611d26565b5061ffff811615611d955760405162461bcd60e51b815260040161030590613150565b5f805b6004811015611df057611dac816003613058565b611db7906008612d3b565b63ffffffff1686611dc983600261307f565b81518110611dd957611dd961306b565b016020015160f81c901b9190911790600101611d98565b5063ffffffff8116600214611e175760405162461bcd60e51b815260040161030590613191565b5f805b6020811015611e6c57611e2e81601f613058565b611e39906008612d3b565b87611e4583600661307f565b81518110611e5557611e5561306b565b016020015160f81c901b9190911790600101611e1a565b505f86602681518110611e8157611e8161306b565b016020015191976001600160f81b03199092161515965090945050505050565b5f805f8351603614611ec55760405162461bcd60e51b815260040161030590613109565b5f805b6002811015611f1457611edc816001613058565b611ee7906008612d3b565b61ffff16868281518110611efd57611efd61306b565b016020015160f81c901b9190911790600101611ec8565b5061ffff811615611f375760405162461bcd60e51b815260040161030590613150565b5f805b6004811015611f9257611f4e816003613058565b611f59906008612d3b565b63ffffffff1687611f6b83600261307f565b81518110611f7b57611f7b61306b565b016020015160f81c901b9190911790600101611f3a565b5063ffffffff8116600114611fb95760405162461bcd60e51b815260040161030590613191565b5f805b602081101561200e57611fd081601f613058565b611fdb906008612d3b565b88611fe783600661307f565b81518110611ff757611ff761306b565b016020015160f81c901b9190911790600101611fbc565b505f805b600881101561206d57612026816007613058565b612031906008612d3b565b6001600160401b03168961204683602661307f565b815181106120565761205661306b565b016020015160f81c901b9190911790600101612012565b505f805b60088110156120cc57612085816007613058565b612090906008612d3b565b6001600160401b03168a6120a583602e61307f565b815181106120b5576120b561306b565b016020015160f81c901b9190911790600101612071565b5091989097509095509350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661212557604051631afcd79f60e31b815260040160405180910390fd5b565b61212f6120dc565b61213761264a565b61213f61265a565b61214881612662565b50565b6121536120dc565b7f8568826440873e37a96cb0aab773b28d8154d963d2f0e41bd9b5c15f63625f916001600160a01b0382166121df5760405162461bcd60e51b815260206004820152602c60248201527f4552433230546f6b656e5374616b696e674d616e616765723a207a65726f207460448201526b6f6b656e206164647265737360a01b6064820152608401610305565b80546001600160a01b0319166001600160a01b0392909216919091179055565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0080546001190161224357604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f6103a3827f8568826440873e37a96cb0aab773b28d8154d963d2f0e41bd9b5c15f63625f91546001600160a01b031690612792565b5f60608260800151516030146122e95760405162461bcd60e51b815260206004820152602960248201527f5374616b696e674d657373616765733a20496e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b6064820152608401610305565b60408051608680825260c082019092525f916020820181803683370190505090505f5b600281101561236057612320816001613058565b61232b906008612d3b565b5081515f908390839081106123425761234261306b565b60200101906001600160f81b03191690815f1a90535060010161230c565b505f5b60048110156123be57612377816003613058565b612382906008612d3b565b505f8261239083600261307f565b815181106123a0576123a061306b565b60200101906001600160f81b03191690815f1a905350600101612363565b505f5b602081101561241b57845181602081106123dd576123dd61306b565b1a60f81b826123ed83600661307f565b815181106123fd576123fd61306b565b60200101906001600160f81b03191690815f1a9053506001016123c1565b505f5b602081101561247b578460200151816020811061243d5761243d61306b565b1a60f81b8261244d83602661307f565b8151811061245d5761245d61306b565b60200101906001600160f81b03191690815f1a90535060010161241e565b505f5b60088110156124ef57612492816007613058565b61249d906008612d3b565b60ff1685604001516001600160401b0316901c60f81b828260466124c1919061307f565b815181106124d1576124d161306b565b60200101906001600160f81b03191690815f1a90535060010161247e565b505f5b603081101561255a57846080015181815181106125115761251161306b565b01602001516001600160f81b0319168261252c83604e61307f565b8151811061253c5761253c61306b565b60200101906001600160f81b03191690815f1a9053506001016124f2565b505f5b60088110156125cc57612571816007613058565b61257c906008612d3b565b60608601516001600160401b0390811691161c60f81b8261259e83607e61307f565b815181106125ae576125ae61306b565b60200101906001600160f81b03191690815f1a90535060010161255d565b506002816040516125dd91906132d9565b602060405180830381855afa1580156125f8573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061261b9190612ce9565b94909350915050565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6126526120dc565b6121256128f4565b6121256120dc565b61266a6120dc565b80355f8051602061333083398151915290815560208201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6015560408201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6025560608201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6035561270260a0830160808401612a95565b60048201805467ffffffffffffffff19166001600160401b039290921691909117905561273560c0830160a084016132f4565b60048201805460ff92909216600160e01b0260ff60e01b1990921691909117905561276660e0830160c08401613314565b8160040160086101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b6040516370a0823160e01b81523060048201525f9081906001600160a01b038516906370a0823190602401602060405180830381865afa1580156127d8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127fc9190612ce9565b90506128136001600160a01b0385163330866128fc565b6040516370a0823160e01b81523060048201525f906001600160a01b038616906370a0823190602401602060405180830381865afa158015612857573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061287b9190612ce9565b90508181116128e15760405162461bcd60e51b815260206004820152602c60248201527f5361666545524332305472616e7366657246726f6d3a2062616c616e6365206e60448201526b1bdd081a5b98dc99585cd95960a21b6064820152608401610305565b6128eb8282613058565b95945050505050565b6126246120dc565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261295690859061295c565b50505050565b5f8060205f8451602086015f885af18061297b576040513d5f823e3d81fd5b50505f513d9150811561299257806001141561299f565b6001600160a01b0384163b155b1561295657604051635274afe760e01b81526001600160a01b0385166004820152602401610305565b5080546129d490612f51565b5f825580601f106129e3575050565b601f0160209004905f5260205f209081019061214891905b80821115612a0e575f81556001016129fb565b5090565b5f60208284031215612a22575f80fd5b5035919050565b6001600160a01b0381168114612148575f80fd5b5f80828403610100811215612a50575f80fd5b60e0811215612a5d575f80fd5b5082915060e0830135612a6f81612a29565b809150509250929050565b80356001600160401b0381168114612a90575f80fd5b919050565b5f60208284031215612aa5575f80fd5b612aae82612a7a565b9392505050565b8015158114612148575f80fd5b803563ffffffff81168114612a90575f80fd5b5f805f60608486031215612ae7575f80fd5b833592506020840135612af981612ab5565b9150612b0760408501612ac2565b90509250925092565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b0381118282101715612b4657612b46612b10565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612b7457612b74612b10565b604052919050565b5f6001600160401b03821115612b9457612b94612b10565b50601f01601f191660200190565b5f805f8060808587031215612bb5575f80fd5b8435935060208501359250612bcc60408601612a7a565b915060608501356001600160401b03811115612be6575f80fd5b8501601f81018713612bf6575f80fd5b8035612c09612c0482612b7c565b612b4c565b818152886020838501011115612c1d575f80fd5b816020840160208301375f6020838301015280935050505092959194509250565b5f60208284031215612c4e575f80fd5b612aae82612ac2565b5f8060408385031215612c68575f80fd5b612c7183612ac2565b91506020830135612a6f81612ab5565b634e487b7160e01b5f52602160045260245ffd5b5f5b83811015612caf578181015183820152602001612c97565b50505f910152565b602081525f8251806020840152612cd5816040850160208701612c95565b601f01601f19169190910160400192915050565b5f60208284031215612cf9575f80fd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f82612d3657612d36612d00565b500490565b80820281158282048414176103a3576103a3612d14565b6020808252602a908201527f5374616b696e674d616e616765723a2053656e646572206e6f742076616c696460408201526930ba37b91037bbb732b960b11b606082015260800190565b8051612a9081612ab5565b5f8060408385031215612db8575f80fd5b82516001600160401b0380821115612dce575f80fd5b9084019060608287031215612de1575f80fd5b612de9612b24565b82518152602080840151612dfc81612a29565b82820152604084015183811115612e11575f80fd5b80850194505087601f850112612e25575f80fd5b83519250612e35612c0484612b7c565b8381528882858701011115612e48575f80fd5b612e5784838301848801612c95565b80604084015250819550612e6c818801612d9c565b9450505050509250929050565b60208082526024908201527f5374616b696e674d616e616765723a20496e76616c69642077617270206d65736040820152637361676560e01b606082015260800190565b60208082526027908201527f5374616b696e674d616e616765723a20496e76616c696420736f7572636520636040820152661a185a5b88125160ca1b606082015260800190565b6020808252602d908201527f5374616b696e674d616e616765723a20496e76616c6964206f726967696e207360408201526c656e646572206164647265737360981b606082015260800190565b600181811c90821680612f6557607f821691505b602082108103612f8357634e487b7160e01b5f52602260045260245ffd5b50919050565b60208082526025908201527f5374616b696e674d616e616765723a20496e76616c69642076616c69646174696040820152641bdb88125160da1b606082015260800190565b5f60208083525f8454612fe081612f51565b806020870152604060018084165f8114613001576001811461301d5761304a565b60ff19851660408a0152604084151560051b8a0101955061304a565b895f5260205f205f5b858110156130415781548b8201860152908301908801613026565b8a016040019650505b509398975050505050505050565b818103818111156103a3576103a3612d14565b634e487b7160e01b5f52603260045260245ffd5b808201808211156103a3576103a3612d14565b6001600160401b038181168382160190808211156130b2576130b2612d14565b5092915050565b6001600160401b038181168382160280821691908281146130dc576130dc612d14565b505092915050565b5f6001600160401b03808416806130fd576130fd612d00565b92169190910492915050565b60208082526027908201527f5374616b696e674d657373616765733a20496e76616c6964206d657373616765604082015266040d8cadccee8d60cb1b606082015260800190565b60208082526021908201527f5374616b696e674d657373616765733a20496e76616c696420636f64656320496040820152601160fa1b606082015260800190565b60208082526025908201527f5374616b696e674d657373616765733a20496e76616c6964206d657373616765604082015264207479706560d81b606082015260800190565b601f821115610e0457805f5260205f20601f840160051c810160208510156131fb5750805b601f840160051c820191505b8181101561038c575f8155600101613207565b81516001600160401b0381111561323357613233612b10565b613247816132418454612f51565b846131d6565b602080601f83116001811461327a575f84156132635750858301515b5f19600386901b1c1916600185901b1785556132d1565b5f85815260208120601f198616915b828110156132a857888601518255948401946001909101908401613289565b50858210156132c557878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f82516132ea818460208701612c95565b9190910192915050565b5f60208284031215613304575f80fd5b813560ff81168114612aae575f80fd5b5f60208284031215613324575f80fd5b8135612aae81612a2956feafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab600a164736f6c6343000819000a", +} + +// ERC20TokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use ERC20TokenStakingManagerMetaData.ABI instead. +var ERC20TokenStakingManagerABI = ERC20TokenStakingManagerMetaData.ABI + +// ERC20TokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use ERC20TokenStakingManagerMetaData.Bin instead. +var ERC20TokenStakingManagerBin = ERC20TokenStakingManagerMetaData.Bin + +// DeployERC20TokenStakingManager deploys a new Ethereum contract, binding an instance of ERC20TokenStakingManager to it. +func DeployERC20TokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *ERC20TokenStakingManager, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(ERC20TokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// ERC20TokenStakingManager is an auto generated Go binding around an Ethereum contract. +type ERC20TokenStakingManager struct { + ERC20TokenStakingManagerCaller // Read-only binding to the contract + ERC20TokenStakingManagerTransactor // Write-only binding to the contract + ERC20TokenStakingManagerFilterer // Log filterer for contract events +} + +// ERC20TokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type ERC20TokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// ERC20TokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type ERC20TokenStakingManagerSession struct { + Contract *ERC20TokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type ERC20TokenStakingManagerCallerSession struct { + Contract *ERC20TokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// ERC20TokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type ERC20TokenStakingManagerTransactorSession struct { + Contract *ERC20TokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// ERC20TokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type ERC20TokenStakingManagerRaw struct { + Contract *ERC20TokenStakingManager // Generic contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerCallerRaw struct { + Contract *ERC20TokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// ERC20TokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type ERC20TokenStakingManagerTransactorRaw struct { + Contract *ERC20TokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewERC20TokenStakingManager creates a new instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManager(address common.Address, backend bind.ContractBackend) (*ERC20TokenStakingManager, error) { + contract, err := bindERC20TokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManager{ERC20TokenStakingManagerCaller: ERC20TokenStakingManagerCaller{contract: contract}, ERC20TokenStakingManagerTransactor: ERC20TokenStakingManagerTransactor{contract: contract}, ERC20TokenStakingManagerFilterer: ERC20TokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewERC20TokenStakingManagerCaller creates a new read-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*ERC20TokenStakingManagerCaller, error) { + contract, err := bindERC20TokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerCaller{contract: contract}, nil +} + +// NewERC20TokenStakingManagerTransactor creates a new write-only instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*ERC20TokenStakingManagerTransactor, error) { + contract, err := bindERC20TokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerTransactor{contract: contract}, nil +} + +// NewERC20TokenStakingManagerFilterer creates a new log filterer instance of ERC20TokenStakingManager, bound to a specific deployed contract. +func NewERC20TokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*ERC20TokenStakingManagerFilterer, error) { + contract, err := bindERC20TokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerFilterer{contract: contract}, nil +} + +// bindERC20TokenStakingManager binds a generic wrapper to an already deployed contract. +func bindERC20TokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := ERC20TokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ERC20TokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _ERC20TokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _ERC20TokenStakingManager.Contract.WARPMESSENGER(&_ERC20TokenStakingManager.CallOpts) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _ERC20TokenStakingManager.Contract.ValueToWeight(&_ERC20TokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _ERC20TokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _ERC20TokenStakingManager.Contract.WeightToValue(&_ERC20TokenStakingManager.CallOpts, weight) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteEndValidation(opts *bind.TransactOpts, messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeEndValidation", messageIndex, setWeightMessageType) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteEndValidation(messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndValidation(&_ERC20TokenStakingManager.TransactOpts, messageIndex, setWeightMessageType) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteEndValidation(messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteEndValidation(&_ERC20TokenStakingManager.TransactOpts, messageIndex, setWeightMessageType) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.CompleteValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0x5d0d7466. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initialize", settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0x5d0d7466. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) Initialize(settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// Initialize is a paid mutator transaction binding the contract method 0x5d0d7466. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings, address token) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) Initialize(settings StakingManagerSettings, token common.Address) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.Initialize(&_ERC20TokenStakingManager.TransactOpts, settings, token) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeEndValidation(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeEndValidation", validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndValidation(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeEndValidation(&_ERC20TokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x872fda64. +// +// Solidity: function initializeValidatorRegistration(uint256 stakeAmount, bytes32 nodeID, uint64 registrationExpiry, bytes blsPublicKey) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) InitializeValidatorRegistration(opts *bind.TransactOpts, stakeAmount *big.Int, nodeID [32]byte, registrationExpiry uint64, blsPublicKey []byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "initializeValidatorRegistration", stakeAmount, nodeID, registrationExpiry, blsPublicKey) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x872fda64. +// +// Solidity: function initializeValidatorRegistration(uint256 stakeAmount, bytes32 nodeID, uint64 registrationExpiry, bytes blsPublicKey) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) InitializeValidatorRegistration(stakeAmount *big.Int, nodeID [32]byte, registrationExpiry uint64, blsPublicKey []byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, stakeAmount, nodeID, registrationExpiry, blsPublicKey) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0x872fda64. +// +// Solidity: function initializeValidatorRegistration(uint256 stakeAmount, bytes32 nodeID, uint64 registrationExpiry, bytes blsPublicKey) returns(bytes32 validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) InitializeValidatorRegistration(stakeAmount *big.Int, nodeID [32]byte, registrationExpiry uint64, blsPublicKey []byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.InitializeValidatorRegistration(&_ERC20TokenStakingManager.TransactOpts, stakeAmount, nodeID, registrationExpiry, blsPublicKey) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendEndValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendEndValidatorMessage", validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendEndValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendEndValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendRegisterValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _ERC20TokenStakingManager.Contract.ResendRegisterValidatorMessage(&_ERC20TokenStakingManager.TransactOpts, validationID) +} + +// ERC20TokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitializedIterator struct { + Event *ERC20TokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerInitialized represents a Initialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*ERC20TokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseInitialized(log types.Log) (*ERC20TokenStakingManagerInitialized, error) { + event := new(ERC20TokenStakingManagerInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodCreatedIterator is returned from FilterValidationPeriodCreated and is used to iterate over the raw logs and unpacked data for ValidationPeriodCreated events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodCreatedIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodCreated represents a ValidationPeriodCreated event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodCreated struct { + ValidationID [32]byte + NodeID [32]byte + RegisterValidationMessageID [32]byte + Weight *big.Int + RegistrationExpiry uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodCreated is a free log retrieval operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (*ERC20TokenStakingManagerValidationPeriodCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodCreatedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodCreated", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodCreated is a free log subscription operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodCreated(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodCreated, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodCreated is a log parse operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodCreated(log types.Log) (*ERC20TokenStakingManagerValidationPeriodCreated, error) { + event := new(ERC20TokenStakingManagerValidationPeriodCreated) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodEndedIterator is returned from FilterValidationPeriodEnded and is used to iterate over the raw logs and unpacked data for ValidationPeriodEnded events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodEndedIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodEnded represents a ValidationPeriodEnded event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodEnded struct { + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodEnded is a free log retrieval operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodEnded(opts *bind.FilterOpts, validationID [][32]byte) (*ERC20TokenStakingManagerValidationPeriodEndedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodEnded", validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodEndedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodEnded", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodEnded is a free log subscription operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodEnded(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodEnded, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodEnded", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodEnded is a log parse operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodEnded(log types.Log) (*ERC20TokenStakingManagerValidationPeriodEnded, error) { + event := new(ERC20TokenStakingManagerValidationPeriodEnded) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidationPeriodRegisteredIterator is returned from FilterValidationPeriodRegistered and is used to iterate over the raw logs and unpacked data for ValidationPeriodRegistered events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodRegisteredIterator struct { + Event *ERC20TokenStakingManagerValidationPeriodRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidationPeriodRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidationPeriodRegistered represents a ValidationPeriodRegistered event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidationPeriodRegistered struct { + ValidationID [32]byte + StakeAmount *big.Int + Timestamp *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodRegistered is a free log retrieval operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidationPeriodRegistered(opts *bind.FilterOpts, validationID [][32]byte) (*ERC20TokenStakingManagerValidationPeriodRegisteredIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidationPeriodRegisteredIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidationPeriodRegistered", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodRegistered is a free log subscription operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidationPeriodRegistered(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidationPeriodRegistered, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodRegistered is a log parse operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidationPeriodRegistered(log types.Log) (*ERC20TokenStakingManagerValidationPeriodRegistered, error) { + event := new(ERC20TokenStakingManagerValidationPeriodRegistered) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// ERC20TokenStakingManagerValidatorRemovalInitializedIterator is returned from FilterValidatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for ValidatorRemovalInitialized events raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRemovalInitializedIterator struct { + Event *ERC20TokenStakingManagerValidatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *ERC20TokenStakingManagerValidatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// ERC20TokenStakingManagerValidatorRemovalInitialized represents a ValidatorRemovalInitialized event raised by the ERC20TokenStakingManager contract. +type ERC20TokenStakingManagerValidatorRemovalInitialized struct { + ValidationID [32]byte + SetWeightMessageID [32]byte + StakeAmount *big.Int + EndTime *big.Int + Uptime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRemovalInitialized is a free log retrieval operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) FilterValidatorRemovalInitialized(opts *bind.FilterOpts, validationID [][32]byte, setWeightMessageID [][32]byte) (*ERC20TokenStakingManagerValidatorRemovalInitializedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.FilterLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return &ERC20TokenStakingManagerValidatorRemovalInitializedIterator{contract: _ERC20TokenStakingManager.contract, event: "ValidatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchValidatorRemovalInitialized is a free log subscription operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) WatchValidatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *ERC20TokenStakingManagerValidatorRemovalInitialized, validationID [][32]byte, setWeightMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _ERC20TokenStakingManager.contract.WatchLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRemovalInitialized is a log parse operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_ERC20TokenStakingManager *ERC20TokenStakingManagerFilterer) ParseValidatorRemovalInitialized(log types.Log) (*ERC20TokenStakingManagerValidatorRemovalInitialized, error) { + event := new(ERC20TokenStakingManagerValidatorRemovalInitialized) + if err := _ERC20TokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/abi-bindings/go/staking/NativeTokenStakingManager/NativeTokenStakingManager.go b/abi-bindings/go/staking/NativeTokenStakingManager/NativeTokenStakingManager.go new file mode 100644 index 000000000..83b75bcc7 --- /dev/null +++ b/abi-bindings/go/staking/NativeTokenStakingManager/NativeTokenStakingManager.go @@ -0,0 +1,1198 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package nativetokenstakingmanager + +import ( + "errors" + "math/big" + "strings" + + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = interfaces.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// StakingManagerSettings is an auto generated low-level Go binding around an user-defined struct. +type StakingManagerSettings struct { + PChainBlockchainID [32]byte + SubnetID [32]byte + MinimumStakeAmount *big.Int + MaximumStakeAmount *big.Int + MinimumStakeDuration uint64 + MaximumHourlyChurn uint8 + RewardCalculator common.Address +} + +// NativeTokenStakingManagerMetaData contains all meta data concerning the NativeTokenStakingManager contract. +var NativeTokenStakingManagerMetaData = &bind.MetaData{ + ABI: "[{\"type\":\"constructor\",\"inputs\":[{\"name\":\"init\",\"type\":\"uint8\",\"internalType\":\"enumICMInitializable\"}],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"WARP_MESSENGER\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"address\",\"internalType\":\"contractIWarpMessenger\"}],\"stateMutability\":\"view\"},{\"type\":\"function\",\"name\":\"completeEndValidation\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"},{\"name\":\"setWeightMessageType\",\"type\":\"bool\",\"internalType\":\"bool\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"completeValidatorRegistration\",\"inputs\":[{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initialize\",\"inputs\":[{\"name\":\"settings\",\"type\":\"tuple\",\"internalType\":\"structStakingManagerSettings\",\"components\":[{\"name\":\"pChainBlockchainID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"subnetID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"minimumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"maximumStakeAmount\",\"type\":\"uint256\",\"internalType\":\"uint256\"},{\"name\":\"minimumStakeDuration\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"maximumHourlyChurn\",\"type\":\"uint8\",\"internalType\":\"uint8\"},{\"name\":\"rewardCalculator\",\"type\":\"address\",\"internalType\":\"contractIRewardCalculator\"}]}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeEndValidation\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"includeUptimeProof\",\"type\":\"bool\",\"internalType\":\"bool\"},{\"name\":\"messageIndex\",\"type\":\"uint32\",\"internalType\":\"uint32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"initializeValidatorRegistration\",\"inputs\":[{\"name\":\"nodeID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"internalType\":\"uint64\"},{\"name\":\"signature\",\"type\":\"bytes\",\"internalType\":\"bytes\"}],\"outputs\":[{\"name\":\"\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"stateMutability\":\"payable\"},{\"type\":\"function\",\"name\":\"resendEndValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"resendRegisterValidatorMessage\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"internalType\":\"bytes32\"}],\"outputs\":[],\"stateMutability\":\"nonpayable\"},{\"type\":\"function\",\"name\":\"valueToWeight\",\"inputs\":[{\"name\":\"value\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"stateMutability\":\"pure\"},{\"type\":\"function\",\"name\":\"weightToValue\",\"inputs\":[{\"name\":\"weight\",\"type\":\"uint64\",\"internalType\":\"uint64\"}],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"internalType\":\"uint256\"}],\"stateMutability\":\"pure\"},{\"type\":\"event\",\"name\":\"Initialized\",\"inputs\":[{\"name\":\"version\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodCreated\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"nodeID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"registerValidationMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"weight\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"registrationExpiry\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodEnded\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidationPeriodRegistered\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"timestamp\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"ValidatorRemovalInitialized\",\"inputs\":[{\"name\":\"validationID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"setWeightMessageID\",\"type\":\"bytes32\",\"indexed\":true,\"internalType\":\"bytes32\"},{\"name\":\"stakeAmount\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"endTime\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"uptime\",\"type\":\"uint64\",\"indexed\":false,\"internalType\":\"uint64\"}],\"anonymous\":false},{\"type\":\"error\",\"name\":\"InvalidInitialization\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"NotInitializing\",\"inputs\":[]},{\"type\":\"error\",\"name\":\"ReentrancyGuardReentrantCall\",\"inputs\":[]}]", + Bin: "0x608060405234801561000f575f80fd5b506040516131a43803806131a483398101604081905261002e91610107565b60018160018111156100425761004261012c565b0361004f5761004f610055565b50610140565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff16156100a55760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b03908116146101045780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b5f60208284031215610117575f80fd5b815160028110610125575f80fd5b9392505050565b634e487b7160e01b5f52602160045260245ffd5b6130578061014d5f395ff3fe60806040526004361061008f575f3560e01c8063a3a65e4811610057578063a3a65e481461015b578063b771b3bc1461017a578063bee0a03f146101ac578063f40797d7146101cb578063fdf94a1a146101de575f80fd5b80630322ed98146100935780632e2194d8146100b457806362065856146100f057806376f786211461011d57806379f54eb11461013c575b5f80fd5b34801561009e575f80fd5b506100b26100ad36600461273d565b6101fd565b005b3480156100bf575f80fd5b506100d36100ce36600461273d565b6103f3565b6040516001600160401b0390911681526020015b60405180910390f35b3480156100fb575f80fd5b5061010f61010a36600461276f565b610409565b6040519081526020016100e7565b348015610128575f80fd5b506100b26101373660046127af565b610422565b348015610147575f80fd5b506100b26101563660046127ea565b6109a2565b348015610166575f80fd5b506100b2610175366004612800565b610aae565b348015610185575f80fd5b506101946005600160991b0181565b6040516001600160a01b0390911681526020016100e7565b3480156101b7575f80fd5b506100b26101c636600461273d565b610d3b565b61010f6101d93660046128ab565b610e4f565b3480156101e9575f80fd5b506100b26101f836600461293d565b610e64565b5f8181527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60860205260408082208151610120810190925280545f8051602061302b83398151915293929190829060ff16600581111561025e5761025e612972565b600581111561026f5761026f612972565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003928301546001600160a01b03811660c084015260ff600160a01b820416151560e0840152600160a81b900416610100909101529091508151600581111561030657610306612972565b1461036e5760405162461bcd60e51b815260206004820152602d60248201527f5374616b696e674d616e616765723a2056616c696461746f72206e6f7420706560448201526c1b991a5b99c81c995b5bdd985b609a1b60648201526084015b60405180910390fd5b5f61037f848361010001515f61128b565b60405163ee5b48eb60e01b81529091506005600160991b019063ee5b48eb906103ac9084906004016129a8565b6020604051808303815f875af11580156103c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103ec91906129da565b5050505050565b5f61040364e8d4a5100083612a19565b92915050565b5f6104036001600160401b03831664e8d4a51000612a2c565b5f8381527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab60860205260408082208151610120810190925280545f8051602061302b83398151915293929190829060ff16600581111561048357610483612972565b600581111561049457610494612972565b8152600182015460208201526002808301546001600160401b038082166040850152600160401b820481166060850152600160801b820481166080850152600160c01b909104811660a08401526003909301546001600160a01b03811660c084015260ff600160a01b820416151560e0840152600160a81b9004909216610100909101529091508151600581111561052e5761052e612972565b146105875760405162461bcd60e51b8152602060048201526024808201527f5374616b696e674d616e616765723a2056616c696461746f72206e6f742061636044820152637469766560e01b6064820152608401610365565b60c08101516001600160a01b0316336001600160a01b0316146105bc5760405162461bcd60e51b815260040161036590612a43565b6105c981604001516114a8565b60038152426001600160401b031660808201525f84156107a2576040516306f8253560e41b815263ffffffff851660048201525f9081906005600160991b0190636f825350906024015f60405180830381865afa15801561062c573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106539190810190612aac565b91509150806106745760405162461bcd60e51b815260040161036590612b7e565b6005600160991b016001600160a01b0316634213cf786040518163ffffffff1660e01b8152600401602060405180830381865afa1580156106b7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106db91906129da565b8251146106fa5760405162461bcd60e51b815260040161036590612bc2565b60208201516001600160a01b0316156107255760405162461bcd60e51b815260040161036590612c09565b5f806107348460400151611655565b91509150818a1461079c5760405162461bcd60e51b815260206004820152602c60248201527f5374616b696e674d616e616765723a20496e76616c696420757074696d65207660448201526b185b1a59185d1a5bdb88125160a21b6064820152608401610365565b93505050505b6001600160401b03811660a08301525f86815260088401602052604090208251815484929190829060ff191660018360058111156107e2576107e2612972565b02179055506020820151600182015560408201516002820180546060850151608086015160a08701516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c08301516003909201805460e0850151610100958601516001600160a01b039095166001600160a81b031990921691909117600160a01b911515919091021767ffffffffffffffff60a81b1916600160a81b93909216929092021790558201515f906108d39088908361128b565b60405163ee5b48eb60e01b81529091505f906005600160991b019063ee5b48eb906109029085906004016129a8565b6020604051808303815f875af115801561091e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061094291906129da565b60408581015181516001600160401b03918216815242602082015290861681830152905191925082918a917f530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5919081900360600190a35050505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a008054600160401b810460ff1615906001600160401b03165f811580156109e65750825b90505f826001600160401b03166001148015610a015750303b155b905081158015610a0f575080155b15610a2d5760405163f92ee8a960e01b815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610a5757845460ff60401b1916600160401b1785555b610a608661182d565b8315610aa657845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b5f5f8051602061302b8339815191526040516306f8253560e41b815263ffffffff841660048201529091505f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610b09573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610b309190810190612aac565b9150915080610b515760405162461bcd60e51b815260040161036590612b7e565b8254825114610b725760405162461bcd60e51b815260040161036590612bc2565b60208201516001600160a01b031615610b9d5760405162461bcd60e51b815260040161036590612c09565b5f80610bac8460400151611841565b9150915080610c0c5760405162461bcd60e51b815260206004820152602660248201527f5374616b696e674d616e616765723a20526567697374726174696f6e206e6f74604482015265081d985b1a5960d21b6064820152608401610365565b5f82815260078601602052604081208054610c2690612c56565b9050118015610c58575060015f83815260088701602052604090205460ff166005811115610c5657610c56612972565b145b610c745760405162461bcd60e51b815260040161036590612c88565b5f8281526007860160205260408120610c8c916126f3565b5f8281526008860160208181526040808420805460ff191660029081178255810180546001600160401b0342818116600160401b026fffffffffffffffff000000000000000019909316929092178355600190930154875260098c0185528387208990559588905293835292548151931683529082019290925283917ff8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568910160405180910390a2505050505050565b5f8181527fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6076020526040812080545f8051602061302b833981519152929190610d8390612c56565b9050118015610db5575060015f83815260088301602052604090205460ff166005811115610db357610db3612972565b145b610dd15760405162461bcd60e51b815260040161036590612c88565b5f82815260078201602052604090819020905163ee5b48eb60e01b81526005600160991b019163ee5b48eb91610e0a9190600401612ccd565b6020604051808303815f875af1158015610e26573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e4a91906129da565b505050565b5f610e5c843485856119e2565b949350505050565b5f5f8051602061302b8339815191526040516306f8253560e41b815263ffffffff851660048201529091505f9081906005600160991b0190636f825350906024015f60405180830381865afa158015610ebf573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610ee69190810190612aac565b9150915080610f075760405162461bcd60e51b815260040161036590612b7e565b5f8415610f80575f610f1c8460400151611ee7565b919350909150506001600160401b03811615610f7a5760405162461bcd60e51b815260206004820181905260248201527f5374616b696e674d616e616765723a20576569676874206d75737420626520306044820152606401610365565b50610ff4565b5f610f8e8460400151611841565b90925090508015610ff25760405162461bcd60e51b815260206004820152602860248201527f5374616b696e674d616e616765723a20526567697374726174696f6e207374696044820152671b1b081d985b1a5960c21b6064820152608401610365565b505b5f818152600885016020526040808220815161012081019092528054829060ff16600581111561102657611026612972565b600581111561103757611037612972565b81526001820154602082015260028201546001600160401b038082166040840152600160401b820481166060840152600160801b820481166080840152600160c01b909104811660a08301526003909201546001600160a01b0380821660c080850191909152600160a01b830460ff16151560e0850152600160a81b909204909316610100909201919091528201519192501633146110e85760405162461bcd60e51b815260040161036590612a43565b5f6003825160058111156110fe576110fe612972565b148061111c575060028251600581111561111a5761111a612972565b145b1561113f57506020808201515f9081526009870190915260408120556004611143565b5060055b5f83815260088701602052604090208251815484929190829060ff1916600183600581111561117457611174612972565b0217905550602082015160018201556040808301516002830180546060860151608087015160a08801516001600160401b039586166001600160801b031990941693909317600160401b92861692909202919091176001600160801b0316600160801b918516919091026001600160c01b031617600160c01b9184169190910217905560c08401516003909301805460e0860151610100909601516001600160a01b039095166001600160a81b031990911617600160a01b951515959095029490941767ffffffffffffffff60a81b1916600160a81b9390911692909202919091179091555183907f3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8905f90a25050505050505050565b60408051603680825260608281019093525f91906020820181803683370190505090505f5b6002811015611304576112c4816001612d57565b6112cf906008612a2c565b5081515f908390839081106112e6576112e6612d6a565b60200101906001600160f81b03191690815f1a9053506001016112b0565b505f5b60048110156113675761131b816003612d57565b611326906008612a2c565b6001901c60f81b82611339836002612d7e565b8151811061134957611349612d6a565b60200101906001600160f81b03191690815f1a905350600101611307565b505f5b60208110156113c95761137e81601f612d57565b611389906008612a2c565b86901c60f81b8261139b836006612d7e565b815181106113ab576113ab612d6a565b60200101906001600160f81b03191690815f1a90535060010161136a565b505f5b6008811015611434576113e0816007612d57565b6113eb906008612a2c565b6001600160401b038616901c60f81b82611406836026612d7e565b8151811061141657611416612d6a565b60200101906001600160f81b03191690815f1a9053506001016113cc565b505f5b600881101561149f5761144b816007612d57565b611456906008612a2c565b6001600160401b038516901c60f81b8261147183602e612d7e565b8151811061148157611481612d6a565b60200101906001600160f81b03191690815f1a905350600101611437565b50949350505050565b7fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab604545f8051602061302b83398151915290600160e01b900460ff165f036114ed575050565b60408051606081018252600583015480825260068401546001600160401b038082166020850152600160401b9091041692820192909252904290610e10906115359083612d57565b10611551576001600160401b0384166040830152808252611570565b83826040018181516115639190612d91565b6001600160401b03169052505b5f8260200151836040015160646115879190612db8565b6115919190612de3565b600485015490915060ff600160e01b909104811690821611156116115760405162461bcd60e51b815260206004820152603260248201527f5374616b696e674d616e616765723a204d6178696d756d20686f75726c7920636044820152711a1d5c9b881c985d1948195e18d95959195960721b6064820152608401610365565b5050805160058301556020810151600690920180546040909201516001600160401b03908116600160401b026001600160801b031990931693169290921717905550565b5f808251602e146116785760405162461bcd60e51b815260040161036590612e08565b5f805b60028110156116c75761168f816001612d57565b61169a906008612a2c565b61ffff168582815181106116b0576116b0612d6a565b016020015160f81c901b919091179060010161167b565b5061ffff8116156116ea5760405162461bcd60e51b815260040161036590612e4f565b5f805b600481101561174557611701816003612d57565b61170c906008612a2c565b63ffffffff168661171e836002612d7e565b8151811061172e5761172e612d6a565b016020015160f81c901b91909117906001016116ed565b5063ffffffff811660041461176c5760405162461bcd60e51b815260040161036590612e90565b5f805b60208110156117c15761178381601f612d57565b61178e906008612a2c565b8761179a836006612d7e565b815181106117aa576117aa612d6a565b016020015160f81c901b919091179060010161176f565b505f805b6008811015611820576117d9816007612d57565b6117e4906008612a2c565b6001600160401b0316886117f9836026612d7e565b8151811061180957611809612d6a565b016020015160f81c901b91909117906001016117c5565b5090969095509350505050565b611835612122565b61183e8161216d565b50565b5f8082516027146118645760405162461bcd60e51b815260040161036590612e08565b5f805b60028110156118b35761187b816001612d57565b611886906008612a2c565b61ffff1685828151811061189c5761189c612d6a565b016020015160f81c901b9190911790600101611867565b5061ffff8116156118d65760405162461bcd60e51b815260040161036590612e4f565b5f805b6004811015611931576118ed816003612d57565b6118f8906008612a2c565b63ffffffff168661190a836002612d7e565b8151811061191a5761191a612d6a565b016020015160f81c901b91909117906001016118d9565b5063ffffffff81166002146119585760405162461bcd60e51b815260040161036590612e90565b5f805b60208110156119ad5761196f81601f612d57565b61197a906008612a2c565b87611986836006612d7e565b8151811061199657611996612d6a565b016020015160f81c901b919091179060010161195b565b505f866026815181106119c2576119c2612d6a565b016020015191976001600160f81b03199092161515965090945050505050565b5f6119eb61218e565b5f8051602061302b833981519152426001600160401b038516118015611a2557506001600160401b038416611a23426202a300612d7e565b115b611a855760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e674d616e616765723a20496e76616c696420726567697374726160448201526a74696f6e2065787069727960a81b6064820152608401610365565b85611ad25760405162461bcd60e51b815260206004820152601f60248201527f5374616b696e674d616e616765723a20496e76616c6964206e6f6465204944006044820152606401610365565b5f86815260098201602052604090205415611b3e5760405162461bcd60e51b815260206004820152602660248201527f5374616b696e674d616e616765723a204e6f646520494420616c72656164792060448201526561637469766560d01b6064820152608401610365565b8251603014611ba35760405162461bcd60e51b815260206004820152602b60248201527f5374616b696e674d616e616765723a20496e76616c696420626c735075626c6960448201526a0c696caf240d8cadccee8d60ab1b6064820152608401610365565b845f611bae826103f3565b9050611bb9816114a8565b8260020154816001600160401b031610158015611be357508260030154816001600160401b031611155b611c3b5760405162461bcd60e51b8152602060048201526024808201527f5374616b696e674d616e616765723a20496e76616c6964207374616b6520616d6044820152631bdd5b9d60e21b6064820152608401610365565b5f80611c826040518060a00160405280876001015481526020018c8152602001856001600160401b031681526020018a6001600160401b03168152602001898152506121d8565b5f82815260078801602052604090209193509150611ca08282612f19565b5060405163ee5b48eb60e01b81525f906005600160991b019063ee5b48eb90611ccd9085906004016129a8565b6020604051808303815f875af1158015611ce9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d0d91906129da565b6040805161012081019091529091508060018152602081018d90526001600160401b03861660408201525f606082018190526080820181905260a082015260c001336001600160a01b031681525f6020808301829052604092830182905286825260088a0190522081518154829060ff19166001836005811115611d9357611d93612972565b021790555060208281015160018301556040808401516002840180546060870151608088015160a08901516001600160401b03908116600160c01b026001600160c01b03928216600160801b02929092166001600160801b03938216600160401b026001600160801b03199095169682169690961793909317919091169390931792909217905560c08501516003909401805460e0870151610100909701518316600160a81b0267ffffffffffffffff60a81b19971515600160a01b026001600160a81b03199092166001600160a01b039097169690961717959095169390931790935582518783168152918c169082015282918d9186917f79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e910160405180910390a45090945050505050610e5c60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b5f805f8351603614611f0b5760405162461bcd60e51b815260040161036590612e08565b5f805b6002811015611f5a57611f22816001612d57565b611f2d906008612a2c565b61ffff16868281518110611f4357611f43612d6a565b016020015160f81c901b9190911790600101611f0e565b5061ffff811615611f7d5760405162461bcd60e51b815260040161036590612e4f565b5f805b6004811015611fd857611f94816003612d57565b611f9f906008612a2c565b63ffffffff1687611fb1836002612d7e565b81518110611fc157611fc1612d6a565b016020015160f81c901b9190911790600101611f80565b5063ffffffff8116600114611fff5760405162461bcd60e51b815260040161036590612e90565b5f805b60208110156120545761201681601f612d57565b612021906008612a2c565b8861202d836006612d7e565b8151811061203d5761203d612d6a565b016020015160f81c901b9190911790600101612002565b505f805b60088110156120b35761206c816007612d57565b612077906008612a2c565b6001600160401b03168961208c836026612d7e565b8151811061209c5761209c612d6a565b016020015160f81c901b9190911790600101612058565b505f805b6008811015612112576120cb816007612d57565b6120d6906008612a2c565b6001600160401b03168a6120eb83602e612d7e565b815181106120fb576120fb612d6a565b016020015160f81c901b91909117906001016120b7565b5091989097509095509350505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0054600160401b900460ff1661216b57604051631afcd79f60e31b815260040160405180910390fd5b565b612175612122565b61217d6125a3565b6121856125b3565b61183e816125bb565b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f008054600119016121d257604051633ee5aeb560e01b815260040160405180910390fd5b60029055565b5f60608260800151516030146122425760405162461bcd60e51b815260206004820152602960248201527f5374616b696e674d657373616765733a20496e76616c6964207369676e6174756044820152680e4ca40d8cadccee8d60bb1b6064820152608401610365565b60408051608680825260c082019092525f916020820181803683370190505090505f5b60028110156122b957612279816001612d57565b612284906008612a2c565b5081515f9083908390811061229b5761229b612d6a565b60200101906001600160f81b03191690815f1a905350600101612265565b505f5b6004811015612317576122d0816003612d57565b6122db906008612a2c565b505f826122e9836002612d7e565b815181106122f9576122f9612d6a565b60200101906001600160f81b03191690815f1a9053506001016122bc565b505f5b6020811015612374578451816020811061233657612336612d6a565b1a60f81b82612346836006612d7e565b8151811061235657612356612d6a565b60200101906001600160f81b03191690815f1a90535060010161231a565b505f5b60208110156123d4578460200151816020811061239657612396612d6a565b1a60f81b826123a6836026612d7e565b815181106123b6576123b6612d6a565b60200101906001600160f81b03191690815f1a905350600101612377565b505f5b6008811015612448576123eb816007612d57565b6123f6906008612a2c565b60ff1685604001516001600160401b0316901c60f81b8282604661241a9190612d7e565b8151811061242a5761242a612d6a565b60200101906001600160f81b03191690815f1a9053506001016123d7565b505f5b60308110156124b3578460800151818151811061246a5761246a612d6a565b01602001516001600160f81b0319168261248583604e612d7e565b8151811061249557612495612d6a565b60200101906001600160f81b03191690815f1a90535060010161244b565b505f5b6008811015612525576124ca816007612d57565b6124d5906008612a2c565b60608601516001600160401b0390811691161c60f81b826124f783607e612d7e565b8151811061250757612507612d6a565b60200101906001600160f81b03191690815f1a9053506001016124b6565b506002816040516125369190612fd4565b602060405180830381855afa158015612551573d5f803e3d5ffd5b5050506040513d601f19601f8201168201806040525081019061257491906129da565b94909350915050565b60017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055565b6125ab612122565b61216b6126eb565b61216b612122565b6125c3612122565b80355f8051602061302b83398151915290815560208201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6015560408201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6025560608201357fafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab6035561265b60a083016080840161276f565b60048201805467ffffffffffffffff19166001600160401b039290921691909117905561268e60c0830160a08401612fef565b60048201805460ff92909216600160e01b0260ff60e01b199092169190911790556126bf60e0830160c0840161300f565b8160040160086101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b61257d612122565b5080546126ff90612c56565b5f825580601f1061270e575050565b601f0160209004905f5260205f209081019061183e91905b80821115612739575f8155600101612726565b5090565b5f6020828403121561274d575f80fd5b5035919050565b80356001600160401b038116811461276a575f80fd5b919050565b5f6020828403121561277f575f80fd5b61278882612754565b9392505050565b801515811461183e575f80fd5b803563ffffffff8116811461276a575f80fd5b5f805f606084860312156127c1575f80fd5b8335925060208401356127d38161278f565b91506127e16040850161279c565b90509250925092565b5f60e082840312156127fa575f80fd5b50919050565b5f60208284031215612810575f80fd5b6127888261279c565b634e487b7160e01b5f52604160045260245ffd5b604051606081016001600160401b038111828210171561284f5761284f612819565b60405290565b604051601f8201601f191681016001600160401b038111828210171561287d5761287d612819565b604052919050565b5f6001600160401b0382111561289d5761289d612819565b50601f01601f191660200190565b5f805f606084860312156128bd575f80fd5b833592506128cd60208501612754565b915060408401356001600160401b038111156128e7575f80fd5b8401601f810186136128f7575f80fd5b803561290a61290582612885565b612855565b81815287602083850101111561291e575f80fd5b816020840160208301375f602083830101528093505050509250925092565b5f806040838503121561294e575f80fd5b6129578361279c565b915060208301356129678161278f565b809150509250929050565b634e487b7160e01b5f52602160045260245ffd5b5f5b838110156129a0578181015183820152602001612988565b50505f910152565b602081525f82518060208401526129c6816040850160208701612986565b601f01601f19169190910160400192915050565b5f602082840312156129ea575f80fd5b5051919050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f82612a2757612a276129f1565b500490565b808202811582820484141761040357610403612a05565b6020808252602a908201527f5374616b696e674d616e616765723a2053656e646572206e6f742076616c696460408201526930ba37b91037bbb732b960b11b606082015260800190565b6001600160a01b038116811461183e575f80fd5b805161276a8161278f565b5f8060408385031215612abd575f80fd5b82516001600160401b0380821115612ad3575f80fd5b9084019060608287031215612ae6575f80fd5b612aee61282d565b82518152602080840151612b0181612a8d565b82820152604084015183811115612b16575f80fd5b80850194505087601f850112612b2a575f80fd5b83519250612b3a61290584612885565b8381528882858701011115612b4d575f80fd5b612b5c84838301848801612986565b80604084015250819550612b71818801612aa1565b9450505050509250929050565b60208082526024908201527f5374616b696e674d616e616765723a20496e76616c69642077617270206d65736040820152637361676560e01b606082015260800190565b60208082526027908201527f5374616b696e674d616e616765723a20496e76616c696420736f7572636520636040820152661a185a5b88125160ca1b606082015260800190565b6020808252602d908201527f5374616b696e674d616e616765723a20496e76616c6964206f726967696e207360408201526c656e646572206164647265737360981b606082015260800190565b600181811c90821680612c6a57607f821691505b6020821081036127fa57634e487b7160e01b5f52602260045260245ffd5b60208082526025908201527f5374616b696e674d616e616765723a20496e76616c69642076616c69646174696040820152641bdb88125160da1b606082015260800190565b5f60208083525f8454612cdf81612c56565b806020870152604060018084165f8114612d005760018114612d1c57612d49565b60ff19851660408a0152604084151560051b8a01019550612d49565b895f5260205f205f5b85811015612d405781548b8201860152908301908801612d25565b8a016040019650505b509398975050505050505050565b8181038181111561040357610403612a05565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561040357610403612a05565b6001600160401b03818116838216019080821115612db157612db1612a05565b5092915050565b6001600160401b03818116838216028082169190828114612ddb57612ddb612a05565b505092915050565b5f6001600160401b0380841680612dfc57612dfc6129f1565b92169190910492915050565b60208082526027908201527f5374616b696e674d657373616765733a20496e76616c6964206d657373616765604082015266040d8cadccee8d60cb1b606082015260800190565b60208082526021908201527f5374616b696e674d657373616765733a20496e76616c696420636f64656320496040820152601160fa1b606082015260800190565b60208082526025908201527f5374616b696e674d657373616765733a20496e76616c6964206d657373616765604082015264207479706560d81b606082015260800190565b601f821115610e4a57805f5260205f20601f840160051c81016020851015612efa5750805b601f840160051c820191505b818110156103ec575f8155600101612f06565b81516001600160401b03811115612f3257612f32612819565b612f4681612f408454612c56565b84612ed5565b602080601f831160018114612f79575f8415612f625750858301515b5f19600386901b1c1916600185901b178555610aa6565b5f85815260208120601f198616915b82811015612fa757888601518255948401946001909101908401612f88565b5085821015612fc457878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b5f8251612fe5818460208701612986565b9190910192915050565b5f60208284031215612fff575f80fd5b813560ff81168114612788575f80fd5b5f6020828403121561301f575f80fd5b813561278881612a8d56feafe6c4731b852fc2be89a0896ae43d22d8b24989064d841b2a1586b4d39ab600a164736f6c6343000819000a", +} + +// NativeTokenStakingManagerABI is the input ABI used to generate the binding from. +// Deprecated: Use NativeTokenStakingManagerMetaData.ABI instead. +var NativeTokenStakingManagerABI = NativeTokenStakingManagerMetaData.ABI + +// NativeTokenStakingManagerBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use NativeTokenStakingManagerMetaData.Bin instead. +var NativeTokenStakingManagerBin = NativeTokenStakingManagerMetaData.Bin + +// DeployNativeTokenStakingManager deploys a new Ethereum contract, binding an instance of NativeTokenStakingManager to it. +func DeployNativeTokenStakingManager(auth *bind.TransactOpts, backend bind.ContractBackend, init uint8) (common.Address, *types.Transaction, *NativeTokenStakingManager, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(NativeTokenStakingManagerBin), backend, init) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NativeTokenStakingManager is an auto generated Go binding around an Ethereum contract. +type NativeTokenStakingManager struct { + NativeTokenStakingManagerCaller // Read-only binding to the contract + NativeTokenStakingManagerTransactor // Write-only binding to the contract + NativeTokenStakingManagerFilterer // Log filterer for contract events +} + +// NativeTokenStakingManagerCaller is an auto generated read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerTransactor is an auto generated write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type NativeTokenStakingManagerFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// NativeTokenStakingManagerSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type NativeTokenStakingManagerSession struct { + Contract *NativeTokenStakingManager // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type NativeTokenStakingManagerCallerSession struct { + Contract *NativeTokenStakingManagerCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// NativeTokenStakingManagerTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type NativeTokenStakingManagerTransactorSession struct { + Contract *NativeTokenStakingManagerTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// NativeTokenStakingManagerRaw is an auto generated low-level Go binding around an Ethereum contract. +type NativeTokenStakingManagerRaw struct { + Contract *NativeTokenStakingManager // Generic contract binding to access the raw methods on +} + +// NativeTokenStakingManagerCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerCallerRaw struct { + Contract *NativeTokenStakingManagerCaller // Generic read-only contract binding to access the raw methods on +} + +// NativeTokenStakingManagerTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type NativeTokenStakingManagerTransactorRaw struct { + Contract *NativeTokenStakingManagerTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewNativeTokenStakingManager creates a new instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManager(address common.Address, backend bind.ContractBackend) (*NativeTokenStakingManager, error) { + contract, err := bindNativeTokenStakingManager(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &NativeTokenStakingManager{NativeTokenStakingManagerCaller: NativeTokenStakingManagerCaller{contract: contract}, NativeTokenStakingManagerTransactor: NativeTokenStakingManagerTransactor{contract: contract}, NativeTokenStakingManagerFilterer: NativeTokenStakingManagerFilterer{contract: contract}}, nil +} + +// NewNativeTokenStakingManagerCaller creates a new read-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerCaller(address common.Address, caller bind.ContractCaller) (*NativeTokenStakingManagerCaller, error) { + contract, err := bindNativeTokenStakingManager(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerCaller{contract: contract}, nil +} + +// NewNativeTokenStakingManagerTransactor creates a new write-only instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerTransactor(address common.Address, transactor bind.ContractTransactor) (*NativeTokenStakingManagerTransactor, error) { + contract, err := bindNativeTokenStakingManager(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerTransactor{contract: contract}, nil +} + +// NewNativeTokenStakingManagerFilterer creates a new log filterer instance of NativeTokenStakingManager, bound to a specific deployed contract. +func NewNativeTokenStakingManagerFilterer(address common.Address, filterer bind.ContractFilterer) (*NativeTokenStakingManagerFilterer, error) { + contract, err := bindNativeTokenStakingManager(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerFilterer{contract: contract}, nil +} + +// bindNativeTokenStakingManager binds a generic wrapper to an already deployed contract. +func bindNativeTokenStakingManager(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := NativeTokenStakingManagerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.NativeTokenStakingManagerTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _NativeTokenStakingManager.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.contract.Transact(opts, method, params...) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WARPMESSENGER(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "WARP_MESSENGER") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// WARPMESSENGER is a free data retrieval call binding the contract method 0xb771b3bc. +// +// Solidity: function WARP_MESSENGER() view returns(address) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WARPMESSENGER() (common.Address, error) { + return _NativeTokenStakingManager.Contract.WARPMESSENGER(&_NativeTokenStakingManager.CallOpts) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) ValueToWeight(opts *bind.CallOpts, value *big.Int) (uint64, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "valueToWeight", value) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// ValueToWeight is a free data retrieval call binding the contract method 0x2e2194d8. +// +// Solidity: function valueToWeight(uint256 value) pure returns(uint64) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) ValueToWeight(value *big.Int) (uint64, error) { + return _NativeTokenStakingManager.Contract.ValueToWeight(&_NativeTokenStakingManager.CallOpts, value) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCaller) WeightToValue(opts *bind.CallOpts, weight uint64) (*big.Int, error) { + var out []interface{} + err := _NativeTokenStakingManager.contract.Call(opts, &out, "weightToValue", weight) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// WeightToValue is a free data retrieval call binding the contract method 0x62065856. +// +// Solidity: function weightToValue(uint64 weight) pure returns(uint256) +func (_NativeTokenStakingManager *NativeTokenStakingManagerCallerSession) WeightToValue(weight uint64) (*big.Int, error) { + return _NativeTokenStakingManager.Contract.WeightToValue(&_NativeTokenStakingManager.CallOpts, weight) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteEndValidation(opts *bind.TransactOpts, messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeEndValidation", messageIndex, setWeightMessageType) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteEndValidation(messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndValidation(&_NativeTokenStakingManager.TransactOpts, messageIndex, setWeightMessageType) +} + +// CompleteEndValidation is a paid mutator transaction binding the contract method 0xfdf94a1a. +// +// Solidity: function completeEndValidation(uint32 messageIndex, bool setWeightMessageType) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteEndValidation(messageIndex uint32, setWeightMessageType bool) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteEndValidation(&_NativeTokenStakingManager.TransactOpts, messageIndex, setWeightMessageType) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) CompleteValidatorRegistration(opts *bind.TransactOpts, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "completeValidatorRegistration", messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// CompleteValidatorRegistration is a paid mutator transaction binding the contract method 0xa3a65e48. +// +// Solidity: function completeValidatorRegistration(uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) CompleteValidatorRegistration(messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.CompleteValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, messageIndex) +} + +// Initialize is a paid mutator transaction binding the contract method 0x79f54eb1. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) Initialize(opts *bind.TransactOpts, settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initialize", settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x79f54eb1. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) Initialize(settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// Initialize is a paid mutator transaction binding the contract method 0x79f54eb1. +// +// Solidity: function initialize((bytes32,bytes32,uint256,uint256,uint64,uint8,address) settings) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) Initialize(settings StakingManagerSettings) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.Initialize(&_NativeTokenStakingManager.TransactOpts, settings) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeEndValidation(opts *bind.TransactOpts, validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeEndValidation", validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndValidation(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeEndValidation is a paid mutator transaction binding the contract method 0x76f78621. +// +// Solidity: function initializeEndValidation(bytes32 validationID, bool includeUptimeProof, uint32 messageIndex) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeEndValidation(validationID [32]byte, includeUptimeProof bool, messageIndex uint32) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeEndValidation(&_NativeTokenStakingManager.TransactOpts, validationID, includeUptimeProof, messageIndex) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xf40797d7. +// +// Solidity: function initializeValidatorRegistration(bytes32 nodeID, uint64 registrationExpiry, bytes signature) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) InitializeValidatorRegistration(opts *bind.TransactOpts, nodeID [32]byte, registrationExpiry uint64, signature []byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "initializeValidatorRegistration", nodeID, registrationExpiry, signature) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xf40797d7. +// +// Solidity: function initializeValidatorRegistration(bytes32 nodeID, uint64 registrationExpiry, bytes signature) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) InitializeValidatorRegistration(nodeID [32]byte, registrationExpiry uint64, signature []byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, nodeID, registrationExpiry, signature) +} + +// InitializeValidatorRegistration is a paid mutator transaction binding the contract method 0xf40797d7. +// +// Solidity: function initializeValidatorRegistration(bytes32 nodeID, uint64 registrationExpiry, bytes signature) payable returns(bytes32) +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) InitializeValidatorRegistration(nodeID [32]byte, registrationExpiry uint64, signature []byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.InitializeValidatorRegistration(&_NativeTokenStakingManager.TransactOpts, nodeID, registrationExpiry, signature) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendEndValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendEndValidatorMessage", validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendEndValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendEndValidatorMessage is a paid mutator transaction binding the contract method 0x0322ed98. +// +// Solidity: function resendEndValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendEndValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendEndValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactor) ResendRegisterValidatorMessage(opts *bind.TransactOpts, validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.contract.Transact(opts, "resendRegisterValidatorMessage", validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendRegisterValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// ResendRegisterValidatorMessage is a paid mutator transaction binding the contract method 0xbee0a03f. +// +// Solidity: function resendRegisterValidatorMessage(bytes32 validationID) returns() +func (_NativeTokenStakingManager *NativeTokenStakingManagerTransactorSession) ResendRegisterValidatorMessage(validationID [32]byte) (*types.Transaction, error) { + return _NativeTokenStakingManager.Contract.ResendRegisterValidatorMessage(&_NativeTokenStakingManager.TransactOpts, validationID) +} + +// NativeTokenStakingManagerInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitializedIterator struct { + Event *NativeTokenStakingManagerInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerInitialized represents a Initialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerInitialized struct { + Version uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterInitialized(opts *bind.FilterOpts) (*NativeTokenStakingManagerInitializedIterator, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerInitialized) (event.Subscription, error) { + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0xc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d2. +// +// Solidity: event Initialized(uint64 version) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseInitialized(log types.Log) (*NativeTokenStakingManagerInitialized, error) { + event := new(NativeTokenStakingManagerInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodCreatedIterator is returned from FilterValidationPeriodCreated and is used to iterate over the raw logs and unpacked data for ValidationPeriodCreated events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodCreatedIterator struct { + Event *NativeTokenStakingManagerValidationPeriodCreated // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodCreated represents a ValidationPeriodCreated event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodCreated struct { + ValidationID [32]byte + NodeID [32]byte + RegisterValidationMessageID [32]byte + Weight *big.Int + RegistrationExpiry uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodCreated is a free log retrieval operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodCreated(opts *bind.FilterOpts, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (*NativeTokenStakingManagerValidationPeriodCreatedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodCreatedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodCreated", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodCreated is a free log subscription operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodCreated(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodCreated, validationID [][32]byte, nodeID [][32]byte, registerValidationMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var nodeIDRule []interface{} + for _, nodeIDItem := range nodeID { + nodeIDRule = append(nodeIDRule, nodeIDItem) + } + var registerValidationMessageIDRule []interface{} + for _, registerValidationMessageIDItem := range registerValidationMessageID { + registerValidationMessageIDRule = append(registerValidationMessageIDRule, registerValidationMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodCreated", validationIDRule, nodeIDRule, registerValidationMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodCreated is a log parse operation binding the contract event 0x79b81620b81daf2c08cd5bb3dbb79e75d2d7a87f52171fde5aadc8c47823026e. +// +// Solidity: event ValidationPeriodCreated(bytes32 indexed validationID, bytes32 indexed nodeID, bytes32 indexed registerValidationMessageID, uint256 weight, uint64 registrationExpiry) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodCreated(log types.Log) (*NativeTokenStakingManagerValidationPeriodCreated, error) { + event := new(NativeTokenStakingManagerValidationPeriodCreated) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodEndedIterator is returned from FilterValidationPeriodEnded and is used to iterate over the raw logs and unpacked data for ValidationPeriodEnded events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodEndedIterator struct { + Event *NativeTokenStakingManagerValidationPeriodEnded // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodEnded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodEndedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodEnded represents a ValidationPeriodEnded event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodEnded struct { + ValidationID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodEnded is a free log retrieval operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodEnded(opts *bind.FilterOpts, validationID [][32]byte) (*NativeTokenStakingManagerValidationPeriodEndedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodEnded", validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodEndedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodEnded", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodEnded is a free log subscription operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodEnded(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodEnded, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodEnded", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodEnded is a log parse operation binding the contract event 0x3532ad18e70a039beb4663d48c15acbef558c96ec9b8fd0cc3c0304f774740b8. +// +// Solidity: event ValidationPeriodEnded(bytes32 indexed validationID) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodEnded(log types.Log) (*NativeTokenStakingManagerValidationPeriodEnded, error) { + event := new(NativeTokenStakingManagerValidationPeriodEnded) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodEnded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidationPeriodRegisteredIterator is returned from FilterValidationPeriodRegistered and is used to iterate over the raw logs and unpacked data for ValidationPeriodRegistered events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodRegisteredIterator struct { + Event *NativeTokenStakingManagerValidationPeriodRegistered // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidationPeriodRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidationPeriodRegistered represents a ValidationPeriodRegistered event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidationPeriodRegistered struct { + ValidationID [32]byte + StakeAmount *big.Int + Timestamp *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidationPeriodRegistered is a free log retrieval operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidationPeriodRegistered(opts *bind.FilterOpts, validationID [][32]byte) (*NativeTokenStakingManagerValidationPeriodRegisteredIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidationPeriodRegisteredIterator{contract: _NativeTokenStakingManager.contract, event: "ValidationPeriodRegistered", logs: logs, sub: sub}, nil +} + +// WatchValidationPeriodRegistered is a free log subscription operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidationPeriodRegistered(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidationPeriodRegistered, validationID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidationPeriodRegistered", validationIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidationPeriodRegistered is a log parse operation binding the contract event 0xf8fd1c90fb9cfa2ca2358fdf5806b086ad43315d92b221c929efc7f105ce7568. +// +// Solidity: event ValidationPeriodRegistered(bytes32 indexed validationID, uint256 stakeAmount, uint256 timestamp) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidationPeriodRegistered(log types.Log) (*NativeTokenStakingManagerValidationPeriodRegistered, error) { + event := new(NativeTokenStakingManagerValidationPeriodRegistered) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidationPeriodRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// NativeTokenStakingManagerValidatorRemovalInitializedIterator is returned from FilterValidatorRemovalInitialized and is used to iterate over the raw logs and unpacked data for ValidatorRemovalInitialized events raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRemovalInitializedIterator struct { + Event *NativeTokenStakingManagerValidatorRemovalInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub interfaces.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *NativeTokenStakingManagerValidatorRemovalInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// NativeTokenStakingManagerValidatorRemovalInitialized represents a ValidatorRemovalInitialized event raised by the NativeTokenStakingManager contract. +type NativeTokenStakingManagerValidatorRemovalInitialized struct { + ValidationID [32]byte + SetWeightMessageID [32]byte + StakeAmount *big.Int + EndTime *big.Int + Uptime uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterValidatorRemovalInitialized is a free log retrieval operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) FilterValidatorRemovalInitialized(opts *bind.FilterOpts, validationID [][32]byte, setWeightMessageID [][32]byte) (*NativeTokenStakingManagerValidatorRemovalInitializedIterator, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.FilterLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return &NativeTokenStakingManagerValidatorRemovalInitializedIterator{contract: _NativeTokenStakingManager.contract, event: "ValidatorRemovalInitialized", logs: logs, sub: sub}, nil +} + +// WatchValidatorRemovalInitialized is a free log subscription operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) WatchValidatorRemovalInitialized(opts *bind.WatchOpts, sink chan<- *NativeTokenStakingManagerValidatorRemovalInitialized, validationID [][32]byte, setWeightMessageID [][32]byte) (event.Subscription, error) { + + var validationIDRule []interface{} + for _, validationIDItem := range validationID { + validationIDRule = append(validationIDRule, validationIDItem) + } + var setWeightMessageIDRule []interface{} + for _, setWeightMessageIDItem := range setWeightMessageID { + setWeightMessageIDRule = append(setWeightMessageIDRule, setWeightMessageIDItem) + } + + logs, sub, err := _NativeTokenStakingManager.contract.WatchLogs(opts, "ValidatorRemovalInitialized", validationIDRule, setWeightMessageIDRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseValidatorRemovalInitialized is a log parse operation binding the contract event 0x530b908725650fb1052974f9df59e834fefac78c9ec2f00c6d2464d60cc6add5. +// +// Solidity: event ValidatorRemovalInitialized(bytes32 indexed validationID, bytes32 indexed setWeightMessageID, uint256 stakeAmount, uint256 endTime, uint64 uptime) +func (_NativeTokenStakingManager *NativeTokenStakingManagerFilterer) ParseValidatorRemovalInitialized(log types.Log) (*NativeTokenStakingManagerValidatorRemovalInitialized, error) { + event := new(NativeTokenStakingManagerValidatorRemovalInitialized) + if err := _NativeTokenStakingManager.contract.UnpackLog(event, "ValidatorRemovalInitialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/contracts/staking/ERC20TokenStakingManager.sol b/contracts/staking/ERC20TokenStakingManager.sol index 9fe936db6..422c12ff6 100644 --- a/contracts/staking/ERC20TokenStakingManager.sol +++ b/contracts/staking/ERC20TokenStakingManager.sol @@ -76,9 +76,10 @@ contract ERC20TokenStakingManager is Initializable, StakingManager, IERC20TokenS uint256 stakeAmount, bytes32 nodeID, uint64 registrationExpiry, - bytes memory signature + bytes memory blsPublicKey ) external override returns (bytes32 validationID) { - return _initializeValidatorRegistration(nodeID, stakeAmount, registrationExpiry, signature); + return + _initializeValidatorRegistration(nodeID, stakeAmount, registrationExpiry, blsPublicKey); } // Must be guarded with reentrancy guard for safe transfer from diff --git a/contracts/staking/StakingManager.sol b/contracts/staking/StakingManager.sol index 4636c0cc5..e22e66d20 100644 --- a/contracts/staking/StakingManager.sol +++ b/contracts/staking/StakingManager.sol @@ -120,18 +120,13 @@ abstract contract StakingManager is * @notice Begins the validator registration process. Locks the provided native asset in the contract as the stake. * @param nodeID The node ID of the validator being registered. * @param registrationExpiry The time at which the reigistration is no longer valid on the P-Chain. - * @param signature The raw bytes of the Ed25519 signature over the concatenated bytes of - * [subnetID]+[nodeID]+[blsPublicKey]+[weight]+[balance]+[expiry]. This signature must correspond to the Ed25519 - * public key that is used for the nodeID. This approach prevents NodeIDs from being unwillingly added to Subnets. - * balance is the minimum initial $nAVAX balance that must be attached to the validator serialized as a uint64. - * The signature field will be validated by the P-Chain. Implementations may choose to validate that the signature - * field is well-formed but it is not required. + * @param blsPublicKey The BLS public key of the validator. */ function _initializeValidatorRegistration( bytes32 nodeID, uint256 value, uint64 registrationExpiry, - bytes memory signature + bytes memory blsPublicKey ) internal nonReentrant returns (bytes32) { StakingManagerStorage storage $ = _getStakingManagerStorage(); @@ -144,12 +139,7 @@ abstract contract StakingManager is // Ensure the nodeID is not the zero address, and is not already an active validator. require(nodeID != bytes32(0), "StakingManager: Invalid node ID"); require($._activeValidators[nodeID] == bytes32(0), "StakingManager: Node ID already active"); - - // Ensure the signature is the proper length. The EVM does not provide an Ed25519 precompile to - // validate the signature, but the P-Chain will validate the signature. If the signature is invalid, - // the P-Chain will reject the registration, and the stake can be returned to the staker after the registration - // expiry has passed. - require(signature.length == 64, "StakingManager: Invalid signature length"); + require(blsPublicKey.length == 48, "StakingManager: Invalid blsPublicKey length"); // Lock the stake in the contract. uint256 lockedValue = _lock(value); @@ -170,8 +160,8 @@ abstract contract StakingManager is subnetID: $._subnetID, nodeID: nodeID, weight: weight, - registrationExpiry: registrationExpiry, - signature: signature + blsPublicKey: blsPublicKey, + registrationExpiry: registrationExpiry }) ); $._pendingRegisterValidationMessages[validationID] = registerSubnetValidatorMessage; diff --git a/contracts/staking/StakingMessages.sol b/contracts/staking/StakingMessages.sol index d9072f205..fa65e4dc0 100644 --- a/contracts/staking/StakingMessages.sol +++ b/contracts/staking/StakingMessages.sol @@ -6,47 +6,61 @@ pragma solidity 0.8.25; library StakingMessages { // The information that uniquely identifies a subnet validation period. - // The SHA-256 hash of the concatenation of these field is the validationID. + // The validationID is the SHA-256 hash of the concatenation of the CODEC_ID, + // REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID, and the concatenated ValidationInfo fields. struct ValidationInfo { bytes32 subnetID; bytes32 nodeID; uint64 weight; uint64 registrationExpiry; - bytes signature; + bytes blsPublicKey; } + // The P-Chain uses a hardcoded codecID of 0 for all messages. + uint16 internal constant CODEC_ID = 0; + // Subnets send a RegisterSubnetValidator message to the P-Chain to register a validator. - // The P-Chain responds with a RegisterSubnetValidator message indicating whether the registration was successful - // for the given validation ID. - uint32 internal constant SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID = 1; + uint32 internal constant REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID = 0; + // Subnets can send a SetSubnetValidatorWeight message to the P-Chain to update a validator's weight. // The P-Chain responds with a SetSubnetValidatorWeight message acknowledging the weight update. - uint32 internal constant SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID = 2; + uint32 internal constant SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID = 1; + + // The P-Chain responds with a RegisterSubnetValidator message indicating whether the registration was successful + // for the given validation ID. + uint32 internal constant SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID = 2; + + // The P-Chain responds with a SetSubnetValidatorWeight message indicating whether the weight update was successful + // for the given validation ID. + uint32 internal constant SET_SUBNET_VALIDATOR_WEIGHT_UPDATE_MESSAGE_TYPE_ID = 3; + // The Subnet will self-sign a ValidationUptimeMessage to be provided when a validator is initiating // the end of their validation period. - uint32 internal constant VALIDATION_UPTIME_MESSAGE_TYPE_ID = 3; + uint32 internal constant VALIDATION_UPTIME_MESSAGE_TYPE_ID = 4; - // TODO: The implemenation of these packing and unpacking functions is neither tested or optimzied at all. + // TODO: The implementation of these packing and unpacking functions is neither tested nor optimized at all. // Full test coverage should be provided, and the implementation should be optimized for gas efficiency. /** * @notice Packs a RegisterSubnetValidatorMessage message into a byte array. * The message format specification is: - * +-----------+----------+-----------+ - * | typeID : uint32 | 4 bytes | - * +-----------+----------+-----------+ - * | subnetID : [32]byte | 32 bytes | - * +-----------+----------+-----------+ - * | nodeID : [32]byte | 32 bytes | - * +-----------+----------+-----------+ - * | weight : uint64 | 8 bytes | - * +-----------+----------+-----------+ - * | expiry : uint64 | 8 bytes | - * +-----------+----------+-----------+ - * | signature : [64]byte | 64 bytes | - * +-----------+----------+-----------+ - * | 148 bytes | - * +-----------+ + * +--------------+----------+-----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+-----------+ + * | typeID : uint32 | 4 bytes | + * +--------------+----------+-----------+ + * | subnetID : [32]byte | 32 bytes | + * +--------------+----------+-----------+ + * | nodeID : [32]byte | 32 bytes | + * +--------------+----------+-----------+ + * | weight : uint64 | 8 bytes | + * +--------------+----------+-----------+ + * | blsPublicKey : [48]byte | 48 bytes | + * +--------------+----------+-----------+ + * | expiry : uint64 | 8 bytes | + * +--------------+----------+-----------+ + * | 134 bytes | + * +-----------+ * * @param validationInfo The information to pack into the message. * @return The validationID and the packed message. @@ -56,20 +70,41 @@ library StakingMessages { pure returns (bytes32, bytes memory) { - (bytes32 validationID, bytes memory serializedValidationInfo) = - packValidationInfo(validationInfo); - - bytes memory res = new bytes(148); - // Pack the message type - for (uint256 i; i < 4; ++i) { - res[i] = bytes1(uint8(SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID >> (8 * (3 - i)))); + require( + validationInfo.blsPublicKey.length == 48, "StakingMessages: Invalid signature length" + ); + bytes memory res = new bytes(134); + // Pack the codec ID + for (uint256 i; i < 2; ++i) { + res[i] = bytes1(uint8(CODEC_ID >> uint8((8 * (1 - i))))); } - // Pack the validation info - for (uint256 i; i < 144; ++i) { - res[i + 4] = serializedValidationInfo[i]; + // Pack the type ID + for (uint256 i; i < 4; ++i) { + res[i + 2] = + bytes1(uint8(REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID >> uint8((8 * (3 - i))))); } - return (validationID, res); + // Pack the subnetID + for (uint256 i; i < 32; ++i) { + res[i + 6] = validationInfo.subnetID[i]; + } + // Pack the nodeID + for (uint256 i; i < 32; ++i) { + res[i + 38] = validationInfo.nodeID[i]; + } + // Pack the weight + for (uint256 i; i < 8; ++i) { + res[i + 70] = bytes1(uint8(validationInfo.weight >> uint8((8 * (7 - i))))); + } + // Pack the blsPublicKey + for (uint256 i; i < 48; ++i) { + res[i + 78] = validationInfo.blsPublicKey[i]; + } + // Pack the registration expiry + for (uint256 i; i < 8; ++i) { + res[i + 126] = bytes1(uint8(validationInfo.registrationExpiry >> uint64((8 * (7 - i))))); + } + return (sha256(res), res); } /** @@ -84,46 +119,53 @@ library StakingMessages { pure returns (ValidationInfo memory) { - require(input.length == 148, "StakingMessages: Invalid message length"); + require(input.length == 134, "StakingMessages: Invalid message length"); + + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + require(codecID == CODEC_ID, "StakingMessages: Invalid codec ID"); // Unpack the type ID uint32 typeID; for (uint256 i; i < 4; ++i) { - typeID |= uint32(uint8(input[i])) << uint32((8 * (3 - i))); + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); } require( - typeID == SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID, + typeID == REGISTER_SUBNET_VALIDATOR_MESSAGE_TYPE_ID, "StakingMessages: Invalid message type" ); - // Unpack the subnet ID + // Unpack the subnetID bytes32 subnetID; for (uint256 i; i < 32; ++i) { - subnetID |= bytes32(uint256(uint8(input[i + 4])) << (8 * (31 - i))); + subnetID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); } - // Unpack the node ID + // Unpack the nodeID bytes32 nodeID; for (uint256 i; i < 32; ++i) { - nodeID |= bytes32(uint256(uint8(input[i + 36])) << (8 * (31 - i))); + nodeID |= bytes32(uint256(uint8(input[i + 38])) << (8 * (31 - i))); } // Unpack the weight uint64 weight; for (uint256 i; i < 8; ++i) { - weight |= uint64(uint8(input[i + 68])) << uint64((8 * (7 - i))); + weight |= uint64(uint8(input[i + 70])) << uint64((8 * (7 - i))); } - // Unpack the expiry - uint64 expiry; - for (uint256 i; i < 8; ++i) { - expiry |= uint64(uint8(input[i + 76])) << uint64((8 * (7 - i))); + // Unpack the blsPublicKey + bytes memory blsPublicKey = new bytes(48); + for (uint256 i; i < 48; ++i) { + blsPublicKey[i] = input[i + 78]; } - // Unpack the signature - bytes memory signature = new bytes(64); - for (uint256 i; i < 64; ++i) { - signature[i] = input[i + 84]; + // Unpack the registration expiry + uint64 expiry; + for (uint256 i; i < 8; ++i) { + expiry |= uint64(uint8(input[i + 126])) << uint64((8 * (7 - i))); } return ValidationInfo({ @@ -131,7 +173,7 @@ library StakingMessages { nodeID: nodeID, weight: weight, registrationExpiry: expiry, - signature: signature + blsPublicKey: blsPublicKey }); } @@ -139,13 +181,15 @@ library StakingMessages { * @notice Packs a SubnetValidatorRegistrationMessage into a byte array. * The message format specification is: * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ * | typeID : uint32 | 4 bytes | * +--------------+----------+----------+ * | validationID : [32]byte | 32 bytes | * +--------------+----------+----------+ * | valid : bool + 1 byte | * +--------------+----------+----------+ - * | 37 bytes | + * | 39 bytes | * +----------+ * * @param validationID The ID of the validation period. @@ -157,17 +201,22 @@ library StakingMessages { bytes32 validationID, bool valid ) internal pure returns (bytes memory) { - bytes memory res = new bytes(37); + bytes memory res = new bytes(39); + // Pack the codec ID. + for (uint256 i; i < 2; ++i) { + res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); + } // Pack the type ID. for (uint256 i; i < 4; ++i) { - res[i] = bytes1(uint8(SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID >> (8 * (3 - i)))); + res[i + 2] = + bytes1(uint8(SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID >> (8 * (3 - i)))); } // Pack the validation ID. for (uint256 i; i < 32; ++i) { - res[i + 4] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); + res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); } // Pack the validity. - res[36] = bytes1(valid ? 1 : 0); + res[38] = bytes1(valid ? 1 : 0); return res; } @@ -184,12 +233,18 @@ library StakingMessages { pure returns (bytes32, bool) { - require(input.length == 37, "StakingMessages: Invalid message length"); + require(input.length == 39, "StakingMessages: Invalid message length"); + // Unpack the codec ID + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + require(codecID == CODEC_ID, "StakingMessages: Invalid codec ID"); // Unpack the type ID uint32 typeID; for (uint256 i; i < 4; ++i) { - typeID |= uint32(uint8(input[i])) << uint32((8 * (3 - i))); + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); } require( typeID == SUBNET_VALIDATOR_REGISTRATION_MESSAGE_TYPE_ID, @@ -199,11 +254,11 @@ library StakingMessages { // Unpack the validation ID. bytes32 validationID; for (uint256 i; i < 32; ++i) { - validationID |= bytes32(uint256(uint8(input[i + 4])) << (8 * (31 - i))); + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); } // Unpack the validity - bool valid = input[36] != 0; + bool valid = input[38] != 0; return (validationID, valid); } @@ -212,6 +267,8 @@ library StakingMessages { * @notice Packs a SetSubnetValidatorWeightMessage message into a byte array. * The message format specification is: * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ * | typeID : uint32 | 4 bytes | * +--------------+----------+----------+ * | validationID : [32]byte | 32 bytes | @@ -220,7 +277,7 @@ library StakingMessages { * +--------------+----------+----------+ * | weight : uint64 | 8 bytes | * +--------------+----------+----------+ - * | 52 bytes | + * | 54 bytes | * +----------+ * * @param validationID The ID of the validation period. @@ -233,22 +290,26 @@ library StakingMessages { uint64 nonce, uint64 weight ) internal pure returns (bytes memory) { - bytes memory res = new bytes(52); + bytes memory res = new bytes(54); + // Pack the codec ID. + for (uint256 i; i < 2; ++i) { + res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); + } // Pack the type ID. for (uint256 i; i < 4; ++i) { - res[i] = bytes1(uint8(SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID >> (8 * (3 - i)))); + res[i + 2] = bytes1(uint8(SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID >> (8 * (3 - i)))); } // Pack the validation ID. for (uint256 i; i < 32; ++i) { - res[i + 4] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); + res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); } // Pack the nonce. for (uint256 i; i < 8; ++i) { - res[i + 36] = bytes1(uint8(nonce >> (8 * (7 - i)))); + res[i + 38] = bytes1(uint8(nonce >> (8 * (7 - i)))); } // Pack the weight. for (uint256 i; i < 8; ++i) { - res[i + 44] = bytes1(uint8(weight >> (8 * (7 - i)))); + res[i + 46] = bytes1(uint8(weight >> (8 * (7 - i)))); } return res; } @@ -265,12 +326,19 @@ library StakingMessages { pure returns (bytes32, uint64, uint64) { - require(input.length == 52, "StakingMessages: Invalid message length"); + require(input.length == 54, "StakingMessages: Invalid message length"); + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + require(codecID == CODEC_ID, "StakingMessages: Invalid codec ID"); // Unpack the type ID. uint32 typeID; for (uint256 i; i < 4; ++i) { - typeID |= uint32(uint8(input[i])) << uint32((8 * (3 - i))); + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); } require( typeID == SET_SUBNET_VALIDATOR_WEIGHT_MESSAGE_TYPE_ID, @@ -280,19 +348,19 @@ library StakingMessages { // Unpack the validation ID. bytes32 validationID; for (uint256 i; i < 32; ++i) { - validationID |= bytes32(uint256(uint8(input[i + 4])) << (8 * (31 - i))); + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); } // Unpack the nonce. uint64 nonce; for (uint256 i; i < 8; ++i) { - nonce |= uint64(uint8(input[i + 36])) << uint64((8 * (7 - i))); + nonce |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); } // Unpack the weight. uint64 weight; for (uint256 i; i < 8; ++i) { - weight |= uint64(uint8(input[i + 44])) << uint64((8 * (7 - i))); + weight |= uint64(uint8(input[i + 46])) << uint64((8 * (7 - i))); } return (validationID, nonce, weight); @@ -302,13 +370,15 @@ library StakingMessages { * @notice Packs a ValidationUptimeMessage into a byte array. * The message format specification is: * +--------------+----------+----------+ + * | codecID : uint16 | 2 bytes | + * +--------------+----------+----------+ * | typeID : uint32 | 4 bytes | * +--------------+----------+----------+ * | validationID : [32]byte | 32 bytes | * +--------------+----------+----------+ * | uptime : uint64 | 8 bytes | * +--------------+----------+----------+ - * | 44 bytes | + * | 46 bytes | * +----------+ * * @param validationID The ID of the validation period. @@ -319,18 +389,23 @@ library StakingMessages { bytes32 validationID, uint64 uptime ) internal pure returns (bytes memory) { - bytes memory res = new bytes(44); + bytes memory res = new bytes(46); + + // Pack the codec ID. + for (uint256 i; i < 2; ++i) { + res[i] = bytes1(uint8(CODEC_ID >> (8 * (1 - i)))); + } // Pack the type ID. for (uint256 i; i < 4; ++i) { - res[i] = bytes1(uint8(VALIDATION_UPTIME_MESSAGE_TYPE_ID >> (8 * (3 - i)))); + res[i + 2] = bytes1(uint8(VALIDATION_UPTIME_MESSAGE_TYPE_ID >> (8 * (3 - i)))); } // Pack the validation ID. for (uint256 i; i < 32; ++i) { - res[i + 4] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); + res[i + 6] = bytes1(uint8(uint256(validationID >> (8 * (31 - i))))); } // Pack the uptime. for (uint256 i; i < 8; ++i) { - res[i + 36] = bytes1(uint8(uptime >> (8 * (7 - i)))); + res[i + 38] = bytes1(uint8(uptime >> (8 * (7 - i)))); } return res; } @@ -347,12 +422,19 @@ library StakingMessages { pure returns (bytes32, uint64) { - require(input.length == 44, "StakingMessages: Invalid message length"); + require(input.length == 46, "StakingMessages: Invalid message length"); + + // Unpack the codec ID. + uint16 codecID; + for (uint256 i; i < 2; ++i) { + codecID |= uint16(uint8(input[i])) << uint16((8 * (1 - i))); + } + require(codecID == CODEC_ID, "StakingMessages: Invalid codec ID"); // Unpack the type ID. uint32 typeID; for (uint256 i; i < 4; ++i) { - typeID |= uint32(uint8(input[i])) << uint32((8 * (3 - i))); + typeID |= uint32(uint8(input[i + 2])) << uint32((8 * (3 - i))); } require( typeID == VALIDATION_UPTIME_MESSAGE_TYPE_ID, "StakingMessages: Invalid message type" @@ -361,119 +443,15 @@ library StakingMessages { // Unpack the validation ID. bytes32 validationID; for (uint256 i; i < 32; ++i) { - validationID |= bytes32(uint256(uint8(input[i + 4])) << (8 * (31 - i))); + validationID |= bytes32(uint256(uint8(input[i + 6])) << (8 * (31 - i))); } // Unpack the uptime. uint64 uptime; for (uint256 i; i < 8; ++i) { - uptime |= uint64(uint8(input[i + 36])) << uint64((8 * (7 - i))); + uptime |= uint64(uint8(input[i + 38])) << uint64((8 * (7 - i))); } return (validationID, uptime); } - - /** - * @notice Packs all of the information pertaining to a validation period into a byte array. - * The packed data is used to calculate the validationID as the SHA-256 hash of the packed data. - * The specification of the packed data is: - * +-----------+----------+-----------+ - * | subnetID : [32]byte | 32 bytes | - * +-----------+----------+-----------+ - * | nodeID : [32]byte | 32 bytes | - * +-----------+----------+-----------+ - * | weight : uint64 | 8 bytes | - * +-----------+----------+-----------+ - * | expiry : uint64 | 8 bytes | - * +-----------+----------+-----------+ - * | signature : [64]byte | 64 bytes | - * +-----------+----------+-----------+ - * | 144 bytes | - * +-----------+ - * - * @param validationInfo The information to pack. - * @return The validationID and the packed data. - */ - function packValidationInfo(ValidationInfo memory validationInfo) - internal - pure - returns (bytes32, bytes memory) - { - require(validationInfo.signature.length == 64, "StakingMessages: Invalid signature length"); - bytes memory res = new bytes(144); - // Pack the subnetID - for (uint256 i; i < 32; ++i) { - res[i] = validationInfo.subnetID[i]; - } - // Pack the nodeID - for (uint256 i; i < 32; ++i) { - res[i + 32] = validationInfo.nodeID[i]; - } - // Pack the weight - for (uint256 i; i < 8; ++i) { - res[i + 64] = bytes1(uint8(validationInfo.weight >> uint8((8 * (7 - i))))); - } - // Pack the registration expiry - for (uint256 i; i < 8; ++i) { - res[i + 72] = bytes1(uint8(validationInfo.registrationExpiry >> uint64((8 * (7 - i))))); - } - // Pack the signature - for (uint256 i; i < 64; ++i) { - res[i + 80] = validationInfo.signature[i]; - } - return (sha256(res), res); - } - - /** - * @notice Unpacks a byte array as a ValidationInfo. - * The message format specification is the same as the one used in above for packing. - * - * @param input The byte array to unpack. - * @return The unpacked ValidationInfo. - */ - function unpackValidationInfo(bytes memory input) - internal - pure - returns (ValidationInfo memory) - { - require(input.length == 144, "StakingMessages: Invalid message length"); - - // Unpack the subnetID - bytes32 subnetID; - for (uint256 i; i < 32; ++i) { - subnetID |= bytes32(uint256(uint8(input[i])) << (8 * (31 - i))); - } - - // Unpack the nodeID - bytes32 nodeID; - for (uint256 i; i < 32; ++i) { - nodeID |= bytes32(uint256(uint8(input[i + 32])) << (8 * (31 - i))); - } - - // Unpack the weight - uint64 weight; - for (uint256 i; i < 8; ++i) { - weight |= uint64(uint8(input[i + 64])) << uint64((8 * (7 - i))); - } - - // Unpack the registration expiry - uint64 expiry; - for (uint256 i; i < 8; ++i) { - expiry |= uint64(uint8(input[i + 72])) << uint64((8 * (7 - i))); - } - - // Unpack the signature - bytes memory signature = new bytes(64); - for (uint256 i; i < 64; ++i) { - signature[i] = input[i + 80]; - } - - return ValidationInfo({ - subnetID: subnetID, - nodeID: nodeID, - weight: weight, - registrationExpiry: expiry, - signature: signature - }); - } } diff --git a/contracts/staking/tests/StakingManagerTests.t.sol b/contracts/staking/tests/StakingManagerTests.t.sol index 171fad73a..148ebd254 100644 --- a/contracts/staking/tests/StakingManagerTests.t.sol +++ b/contracts/staking/tests/StakingManagerTests.t.sol @@ -19,8 +19,8 @@ abstract contract StakingManagerTest is Test { bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); bytes32 public constant DEFAULT_NODE_ID = bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); - bytes public constant DEFAULT_ED25519_SIGNATURE = bytes( - hex"12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" ); address public constant WARP_PRECOMPILE_ADDRESS = 0x0200000000000000000000000000000000000005; @@ -63,7 +63,7 @@ abstract contract StakingManagerTest is Test { DEFAULT_SUBNET_ID, DEFAULT_WEIGHT, DEFAULT_EXPIRY, - DEFAULT_ED25519_SIGNATURE + DEFAULT_BLS_PUBLIC_KEY ); } @@ -92,7 +92,7 @@ abstract contract StakingManagerTest is Test { DEFAULT_SUBNET_ID, DEFAULT_WEIGHT, DEFAULT_EXPIRY, - DEFAULT_ED25519_SIGNATURE + DEFAULT_BLS_PUBLIC_KEY ); (, bytes memory registerSubnetValidatorMessage) = StakingMessages .packRegisterSubnetValidatorMessage( @@ -101,7 +101,7 @@ abstract contract StakingManagerTest is Test { nodeID: DEFAULT_NODE_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY }) ); _mockSendWarpMessage(registerSubnetValidatorMessage, bytes32(0)); @@ -114,7 +114,7 @@ abstract contract StakingManagerTest is Test { subnetID: DEFAULT_SUBNET_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP }); } @@ -125,7 +125,7 @@ abstract contract StakingManagerTest is Test { subnetID: DEFAULT_SUBNET_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP }); @@ -145,7 +145,7 @@ abstract contract StakingManagerTest is Test { subnetID: DEFAULT_SUBNET_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP }); @@ -161,7 +161,7 @@ abstract contract StakingManagerTest is Test { subnetID: DEFAULT_SUBNET_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP }); @@ -183,7 +183,7 @@ abstract contract StakingManagerTest is Test { subnetID: DEFAULT_SUBNET_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE, + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY, registrationTimestamp: DEFAULT_REGISTRATION_TIMESTAMP, completionTimestamp: DEFAULT_COMPLETION_TIMESTAMP }); @@ -224,15 +224,15 @@ abstract contract StakingManagerTest is Test { bytes32 subnetID, uint64 weight, uint64 registrationExpiry, - bytes memory signature + bytes memory blsPublicKey ) internal returns (bytes32 validationID) { - (validationID,) = StakingMessages.packValidationInfo( + (validationID,) = StakingMessages.packRegisterSubnetValidatorMessage( StakingMessages.ValidationInfo({ nodeID: nodeID, subnetID: subnetID, weight: weight, registrationExpiry: registrationExpiry, - signature: signature + blsPublicKey: blsPublicKey }) ); (, bytes memory registerSubnetValidatorMessage) = StakingMessages @@ -242,7 +242,7 @@ abstract contract StakingManagerTest is Test { nodeID: nodeID, weight: weight, registrationExpiry: registrationExpiry, - signature: signature + blsPublicKey: blsPublicKey }) ); vm.warp(DEFAULT_EXPIRY - 1); @@ -255,7 +255,7 @@ abstract contract StakingManagerTest is Test { ); _initializeValidatorRegistration( - nodeID, registrationExpiry, signature, stakingManager.weightToValue(weight) + nodeID, registrationExpiry, blsPublicKey, stakingManager.weightToValue(weight) ); } @@ -264,11 +264,11 @@ abstract contract StakingManagerTest is Test { bytes32 subnetID, uint64 weight, uint64 registrationExpiry, - bytes memory signature, + bytes memory blsPublicKey, uint64 registrationTimestamp ) internal returns (bytes32 validationID) { validationID = _setUpInitializeValidatorRegistration( - nodeID, subnetID, weight, registrationExpiry, signature + nodeID, subnetID, weight, registrationExpiry, blsPublicKey ); bytes memory subnetValidatorRegistrationMessage = StakingMessages.packSubnetValidatorRegistrationMessage(validationID, true); @@ -287,7 +287,7 @@ abstract contract StakingManagerTest is Test { bytes32 subnetID, uint64 weight, uint64 registrationExpiry, - bytes memory signature, + bytes memory blsPublicKey, uint64 registrationTimestamp, uint64 completionTimestamp ) internal returns (bytes32 validationID) { @@ -296,7 +296,7 @@ abstract contract StakingManagerTest is Test { subnetID: subnetID, weight: weight, registrationExpiry: registrationExpiry, - signature: signature, + blsPublicKey: blsPublicKey, registrationTimestamp: registrationTimestamp }); @@ -342,7 +342,7 @@ abstract contract StakingManagerTest is Test { function _initializeValidatorRegistration( bytes32 nodeID, uint64 registrationExpiry, - bytes memory signature, + bytes memory blsPublicKey, uint256 stakeAmount ) internal virtual returns (bytes32); diff --git a/contracts/staking/tests/StakingMessagesTests.t.sol b/contracts/staking/tests/StakingMessagesTests.t.sol index 4b3b44dd9..5f730f64b 100644 --- a/contracts/staking/tests/StakingMessagesTests.t.sol +++ b/contracts/staking/tests/StakingMessagesTests.t.sol @@ -13,8 +13,8 @@ contract StakingMessagesTest is Test { bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); bytes32 public constant DEFAULT_NODE_ID = bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); - bytes public constant DEFAULT_ED25519_SIGNATURE = bytes( - hex"12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + bytes public constant DEFAULT_BLS_PUBLIC_KEY = bytes( + hex"123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" ); bytes32 public constant DEFAULT_VALIDATION_ID = bytes32(hex"1234567812345678123456781234567812345678123456781234567812345678"); @@ -29,7 +29,7 @@ contract StakingMessagesTest is Test { nodeID: DEFAULT_NODE_ID, weight: DEFAULT_WEIGHT, registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE + blsPublicKey: DEFAULT_BLS_PUBLIC_KEY }) ); @@ -39,9 +39,9 @@ contract StakingMessagesTest is Test { assertEq(info.nodeID, DEFAULT_NODE_ID); assertEq(info.weight, DEFAULT_WEIGHT); assertEq(info.registrationExpiry, DEFAULT_EXPIRY); - assertEq(info.signature, DEFAULT_ED25519_SIGNATURE); + assertEq(info.blsPublicKey, DEFAULT_BLS_PUBLIC_KEY); - (bytes32 recoveredID,) = StakingMessages.packValidationInfo(info); + (bytes32 recoveredID,) = StakingMessages.packRegisterSubnetValidatorMessage(info); assertEq(recoveredID, validationID); } @@ -73,22 +73,4 @@ contract StakingMessagesTest is Test { assertEq(validationID, DEFAULT_VALIDATION_ID); assertEq(uptime, 100); } - - function testValidationInfo() public pure { - (, bytes memory packed) = StakingMessages.packValidationInfo( - StakingMessages.ValidationInfo({ - subnetID: DEFAULT_SUBNET_ID, - nodeID: DEFAULT_NODE_ID, - weight: DEFAULT_WEIGHT, - registrationExpiry: DEFAULT_EXPIRY, - signature: DEFAULT_ED25519_SIGNATURE - }) - ); - StakingMessages.ValidationInfo memory info = StakingMessages.unpackValidationInfo(packed); - assertEq(info.subnetID, DEFAULT_SUBNET_ID); - assertEq(info.nodeID, DEFAULT_NODE_ID); - assertEq(info.weight, DEFAULT_WEIGHT); - assertEq(info.registrationExpiry, DEFAULT_EXPIRY); - assertEq(info.signature, DEFAULT_ED25519_SIGNATURE); - } } diff --git a/go.mod b/go.mod index 47defd6a5..1c725ac6f 100644 --- a/go.mod +++ b/go.mod @@ -3,16 +3,18 @@ module github.com/ava-labs/teleporter go 1.21.13 require ( - github.com/ava-labs/avalanchego v1.11.10 + github.com/ava-labs/avalanchego v1.11.11-0.20240814200552-b3b720666238 github.com/supranational/blst v0.3.11 // indirect ) require ( - github.com/ava-labs/subnet-evm v0.6.8 + github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12 + github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc github.com/ethereum/go-ethereum v1.13.8 - github.com/onsi/ginkgo/v2 v2.19.1 + github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 github.com/pkg/errors v0.9.1 + github.com/prometheus/client_golang v1.19.1 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 @@ -23,13 +25,13 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect - github.com/ava-labs/coreth v0.13.7 // indirect + github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cockroachdb/errors v1.9.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect @@ -58,18 +60,17 @@ require ( github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect + github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect github.com/google/renameio/v2 v2.0.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/rpc v1.2.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/hashicorp/go-bexpr v0.1.10 // indirect github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect github.com/hashicorp/hcl v1.0.0 // indirect @@ -87,7 +88,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect @@ -97,10 +97,9 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pires/go-proxyproto v0.6.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.48.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/rs/cors v1.7.0 // indirect @@ -140,9 +139,9 @@ require ( golang.org/x/text v0.17.0 // indirect golang.org/x/time v0.3.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/grpc v1.64.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect + google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect diff --git a/go.sum b/go.sum index bab5300d6..72927d301 100644 --- a/go.sum +++ b/go.sum @@ -56,12 +56,14 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.11.10 h1:QujciF5OEp5FwAoe/RciFF/i47rxU5rkEr6fVuUBS1Q= -github.com/ava-labs/avalanchego v1.11.10/go.mod h1:POgZPryqe80OeHCDNrXrPOKoFre736iFuMgmUBeKaLc= -github.com/ava-labs/coreth v0.13.7 h1:k8T9u/ROifl8f7oXjHRc1KvSISRl9txvy7gGVmHEz6g= -github.com/ava-labs/coreth v0.13.7/go.mod h1:tXDujonxXFOF6oK5HS2EmgtSXJK3Gy6RpZxb5WzR9rM= -github.com/ava-labs/subnet-evm v0.6.8 h1:IrHGajBYWs692YIYdd5J0oVWWt88Q/XAZQq/dOtkHFw= -github.com/ava-labs/subnet-evm v0.6.8/go.mod h1:qt8DXyGm40CY9yffNOe1+4yUyL9mD3v5RPWqAuGj5u4= +github.com/ava-labs/avalanchego v1.11.11-0.20240814200552-b3b720666238 h1:zxFjHBPwGo1WaNa7FLbIWgHeYk3y+ivm7RUdq4lZAW8= +github.com/ava-labs/avalanchego v1.11.11-0.20240814200552-b3b720666238/go.mod h1:8pnf2At/q0LRq5dvYJYn3CkhKzZNHRd5pjARC9psu+g= +github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12 h1:vcCa4wZTDPObQFauhjtkAqbHWty3vXQaoPJMFgptnWM= +github.com/ava-labs/awm-relayer v1.4.0-rc.2.0.20240814200841-1c435873fd12/go.mod h1:cpfI3E4g0NsEjhJ9VHJ4xMLyOOAqqL1by0MhTIito/c= +github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade h1:xWsvSGtZcGna3B2BLU2BvK3qskbcc9ZNtgC0ck91CkI= +github.com/ava-labs/coreth v0.13.8-fix-genesis-upgrade/go.mod h1:Ouul9dJouniUIJVX1gDqx8CrHyGvmwZkK28mrgKb/4I= +github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc h1:FZ09oIkRnrI+FLTReCKfWqNHFDrNQVr629NTkdfr22Y= +github.com/ava-labs/subnet-evm v0.6.9-0.20240813192818-4d5aebb6decc/go.mod h1:nWP5feXpdvF4Kv10V0vrP9bYqt5yYvp2I5bBXY2xa7U= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -96,8 +98,9 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -230,8 +233,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -297,8 +300,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= -github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg= github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4= @@ -319,8 +322,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -414,8 +417,6 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -455,8 +456,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.19.1 h1:QXgq3Z8Crl5EL1WBAC98A5sEBHARrAJNzAmMxzLcRF0= -github.com/onsi/ginkgo/v2 v2.19.1/go.mod h1:O3DtEWQkPa/F7fBMgmZQKKsluAy8pd3rEQdrjkPb9zA= +github.com/onsi/ginkgo/v2 v2.20.0 h1:PE84V2mHqoT1sglvHc8ZdQtPcwmvvt29WLEEO3xmdZw= +github.com/onsi/ginkgo/v2 v2.20.0/go.mod h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -479,15 +480,15 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= +github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -962,10 +963,10 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -984,8 +985,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA= -google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/scripts/abi_bindings.sh b/scripts/abi_bindings.sh index 737b13eec..4b2f09dce 100755 --- a/scripts/abi_bindings.sh +++ b/scripts/abi_bindings.sh @@ -16,7 +16,7 @@ export ARCH=$(uname -m) [ $ARCH = x86_64 ] && ARCH=amd64 echo "ARCH set to $ARCH" -DEFAULT_CONTRACT_LIST="TeleporterMessenger TeleporterRegistry ExampleERC20 TestMessenger ValidatorSetSig" +DEFAULT_CONTRACT_LIST="TeleporterMessenger TeleporterRegistry ExampleERC20 TestMessenger ValidatorSetSig NativeTokenStakingManager ERC20TokenStakingManager" CONTRACT_LIST= HELP= diff --git a/scripts/versions.sh b/scripts/versions.sh index e1b97e297..d3b6ff089 100755 --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -16,7 +16,7 @@ function getDepVersion() { grep -m1 "^\s*$1" $TELEPORTER_PATH/go.mod | cut -d ' ' -f2 } -extract_commit() { +function extract_commit() { local version=$1 if [[ $version == *-* ]]; then # Extract the substring after the last '-' @@ -29,9 +29,10 @@ extract_commit() { AWM_RELAYER_VERSION=${AWM_RELAYER_VERSION:-'v1.0.0'} # Don't export them as they're used in the context of other calls -AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$(getDepVersion github.com/ava-labs/avalanchego)} -GINKGO_VERSION=${GINKGO_VERSION:-$(getDepVersion github.com/onsi/ginkgo/v2)} -SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-$(getDepVersion github.com/ava-labs/subnet-evm)} +AVALANCHEGO_VERSION=${AVALANCHEGO_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/avalanchego)")} +GINKGO_VERSION=${GINKGO_VERSION:-$(extract_commit "$(getDepVersion github.com/onsi/ginkgo/v2)")} +SUBNET_EVM_VERSION=${SUBNET_EVM_VERSION:-$(extract_commit "$(getDepVersion github.com/ava-labs/subnet-evm)")} + # Set golangci-lint version GOLANGCI_LINT_VERSION=${GOLANGCI_LINT_VERSION:-'v1.55'} diff --git a/tests/flows/erc20_token_staking.go b/tests/flows/erc20_token_staking.go new file mode 100644 index 000000000..0f2fbccad --- /dev/null +++ b/tests/flows/erc20_token_staking.go @@ -0,0 +1,173 @@ +package flows + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a erc20 token staking validator on a subnet. The steps are as follows: + * - Deploy the ERCTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the subnet. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is delisted from the staking contract + */ +func ERC20TokenStakingManager(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + + // Deploy the staking manager contract + stakingManagerAddress, stakingManager, _, erc20 := utils.DeployAndInitializeERC20TokenStakingManager( + context.Background(), + fundedKey, + subnetAInfo, + pChainInfo, + ) + + // + // Register a validator + // + var validationID ids.ID // To be used in the delisting step + stakeAmount := uint64(1e18) + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + big.NewInt(int64(stakeAmount)), + ) + Expect(err).Should(BeNil()) + { + // Initiate validator registration + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + var receipt *types.Receipt + receipt, validationID = utils.InitializeERC20ValidatorRegistration( + fundedKey, + subnetAInfo, + stakeAmount, + erc20, + stakingManagerAddress, + nodeID, + blsPublicKey, + stakingManager, + ) + + // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateRegisterSubnetValidatorMessage( + signedWarpMessage, + nodeID, + weight, + subnetAInfo.SubnetID, + blsPublicKey, + ) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteERC20ValidatorRegistration( + fundedKey, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + } + + // + // Delist the validator + // + { + receipt := utils.InitializeEndERC20Validation( + fundedKey, + subnetAInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.StakeAmount.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, 0) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorRegistrationMessage( + validationID, + false, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndERC20Validation( + fundedKey, + subnetAInfo, + stakingManagerAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + } +} diff --git a/tests/flows/native_token_staking.go b/tests/flows/native_token_staking.go new file mode 100644 index 000000000..e66602083 --- /dev/null +++ b/tests/flows/native_token_staking.go @@ -0,0 +1,170 @@ +package flows + +import ( + "context" + "math/big" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ava-labs/teleporter/tests/utils" + . "github.com/onsi/gomega" +) + +/* + * Registers a native token staking validator on a subnet. The steps are as follows: + * - Deploy the NativeTokenStakingManager + * - Initiate validator registration + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is registered in the staking contract + * + * Delists the validator from the subnet. The steps are as follows: + * - Initiate validator delisting + * - Deliver the Warp message to the P-Chain (not implemented) + * - Aggregate P-Chain signatures on the response Warp message + * - Deliver the Warp message to the subnet + * - Verify that the validator is delisted from the staking contract + */ +func NativeTokenStakingManager(network interfaces.LocalNetwork) { + // Get the subnets info + cChainInfo := network.GetPrimaryNetworkInfo() + subnetAInfo, _ := utils.GetTwoSubnets(network) + _, fundedKey := network.GetFundedAccountInfo() + pChainInfo := utils.GetPChainInfo(cChainInfo) + + signatureAggregator := utils.NewSignatureAggregator( + cChainInfo.NodeURIs[0], + []ids.ID{ + subnetAInfo.SubnetID, + ids.Empty, // Primary network subnet ID + }, + ) + + // Deploy the staking manager contract + stakingManagerContractAddress, stakingManager := utils.DeployAndInitializeNativeTokenStakingManager( + context.Background(), + fundedKey, + subnetAInfo, + pChainInfo, + ) + + // + // Register a validator + // + var validationID ids.ID // To be used in the delisting step + stakeAmount := uint64(1e18) + weight, err := stakingManager.ValueToWeight( + &bind.CallOpts{}, + big.NewInt(int64(stakeAmount)), + ) + Expect(err).Should(BeNil()) + { + // Iniatiate validator registration + nodeID := ids.GenerateTestID() + blsPublicKey := [bls.PublicKeyLen]byte{} + var receipt *types.Receipt + receipt, validationID = utils.InitializeNativeValidatorRegistration( + fundedKey, + subnetAInfo, + stakeAmount, + nodeID, + blsPublicKey, + stakingManager, + ) + + // Gather subnet-evm Warp signatures for the RegisterSubnetValidatorMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateRegisterSubnetValidatorMessage( + signedWarpMessage, + nodeID, + weight, + subnetAInfo.SubnetID, + blsPublicKey, + ) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorRegistrationMessage( + validationID, + true, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteNativeValidatorRegistration( + fundedKey, + subnetAInfo, + stakingManagerContractAddress, + registrationSignedMessage, + ) + // Check that the validator is registered in the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodRegistered, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + } + + // + // Delist the validator + // + { + receipt := utils.InitializeEndNativeValidation( + fundedKey, + subnetAInfo, + stakingManager, + validationID, + ) + validatorRemovalEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidatorRemovalInitialized, + ) + Expect(err).Should(BeNil()) + Expect(validatorRemovalEvent.ValidationID[:]).Should(Equal(validationID[:])) + Expect(validatorRemovalEvent.StakeAmount.Uint64()).Should(Equal(weight)) + + // Gather subnet-evm Warp signatures for the SetSubnetValidatorWeightMessage & relay to the P-Chain + // (Sending to the P-Chain will be skipped for now) + signedWarpMessage := network.ConstructSignedWarpMessage(context.Background(), receipt, subnetAInfo, pChainInfo) + Expect(err).Should(BeNil()) + + // Validate the Warp message, (this will be done on the P-Chain in the future) + utils.ValidateSetSubnetValidatorWeightMessage(signedWarpMessage, validationID, 0, 0) + + // Construct a SubnetValidatorRegistrationMessage Warp message from the P-Chain + registrationSignedMessage := utils.ConstructSubnetValidatorRegistrationMessage( + validationID, + false, + subnetAInfo, + pChainInfo, + network, + signatureAggregator, + ) + + // Deliver the Warp message to the subnet + receipt = utils.CompleteEndNativeValidation( + fundedKey, + subnetAInfo, + stakingManagerContractAddress, + registrationSignedMessage, + ) + + // Check that the validator is has been delisted from the staking contract + registrationEvent, err := utils.GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodEnded, + ) + Expect(err).Should(BeNil()) + Expect(registrationEvent.ValidationID[:]).Should(Equal(validationID[:])) + } +} diff --git a/tests/local/e2e_test.go b/tests/local/e2e_test.go index 95d934855..8b84c6955 100644 --- a/tests/local/e2e_test.go +++ b/tests/local/e2e_test.go @@ -22,6 +22,7 @@ const ( upgradabilityLabel = "upgradability" utilsLabel = "utils" validatorSetSigLabel = "ValidatorSetSig" + stakingManagerLabel = "StakingManager" ) var ( @@ -189,6 +190,16 @@ var _ = ginkgo.Describe("[Teleporter integration tests]", func() { func() { flows.ValidatorChurn(LocalNetworkInstance) }) + ginkgo.It("Native token staking manager", + ginkgo.Label(stakingManagerLabel), + func() { + flows.NativeTokenStakingManager(LocalNetworkInstance) + }) + ginkgo.It("ERC20 token staking manager", + ginkgo.Label(stakingManagerLabel), + func() { + flows.ERC20TokenStakingManager(LocalNetworkInstance) + }) // Since the validator churn test modifies the network topology, we put it last for now. // It should not affect the other tests, but we get some errors if we run it before the other tests. // TODO: we should fix this so that the order of the tests does not matter. diff --git a/tests/local/network.go b/tests/local/network.go index 4472039d0..d2d4ce28b 100644 --- a/tests/local/network.go +++ b/tests/local/network.go @@ -50,21 +50,12 @@ type LocalNetwork struct { globalFundedKey *ecdsa.PrivateKey // Internal vars only used to set up the local network - tmpnet *tmpnet.Network - warpChainConfigPath string + tmpnet *tmpnet.Network } const ( - fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" - warpEnabledChainConfig = `{ - "warp-api-enabled": true, - "eth-apis":["eth","eth-filter","net","admin","web3", - "internal-eth","internal-blockchain","internal-transaction", - "internal-debug","internal-account","internal-personal", - "debug","debug-tracer","debug-file-tracer","debug-handler"] - }` - - timeout = 60 * time.Second + fundedKeyStr = "56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027" + timeout = 60 * time.Second ) type SubnetSpec struct { @@ -88,12 +79,6 @@ func NewLocalNetwork( // Create extra nodes to be used to add more validators later extraNodes := subnetEvmTestUtils.NewTmpnetNodes(extraNodeCount) - f, err := os.CreateTemp(os.TempDir(), "config.json") - Expect(err).Should(BeNil()) - _, err = f.Write([]byte(warpEnabledChainConfig)) - Expect(err).Should(BeNil()) - warpChainConfigPath := f.Name() - var allNodes []*tmpnet.Node allNodes = append(allNodes, extraNodes...) // to be appended w/ subnet validators @@ -111,7 +96,7 @@ func NewLocalNetwork( subnetSpec.TeleporterDeployedBytecode, subnetSpec.TeleporterDeployerAddress, ), - subnetEvmTestUtils.DefaultChainConfig, + utils.WarpEnabledChainConfig, nodes..., ) subnets = append(subnets, subnet) @@ -149,12 +134,11 @@ func NewLocalNetwork( } localNetwork := &LocalNetwork{ - primaryNetworkInfo: &interfaces.SubnetTestInfo{}, - subnetsInfo: make(map[ids.ID]*interfaces.SubnetTestInfo), - extraNodes: extraNodes, - globalFundedKey: globalFundedKey, - tmpnet: network, - warpChainConfigPath: warpChainConfigPath, + primaryNetworkInfo: &interfaces.SubnetTestInfo{}, + subnetsInfo: make(map[ids.ID]*interfaces.SubnetTestInfo), + extraNodes: extraNodes, + globalFundedKey: globalFundedKey, + tmpnet: network, } for _, subnet := range network.Subnets { localNetwork.setSubnetValues(subnet) @@ -486,7 +470,6 @@ func (n *LocalNetwork) TearDownNetwork() { Expect(n).ShouldNot(BeNil()) Expect(n.tmpnet).ShouldNot(BeNil()) Expect(n.tmpnet.Stop(context.Background())).Should(BeNil()) - Expect(os.Remove(n.warpChainConfigPath)).Should(BeNil()) } func (n *LocalNetwork) AddSubnetValidators(ctx context.Context, subnetID ids.ID, count uint) { diff --git a/tests/utils/chain.go b/tests/utils/chain.go new file mode 100644 index 000000000..07872d456 --- /dev/null +++ b/tests/utils/chain.go @@ -0,0 +1,564 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "encoding/json" + "errors" + "fmt" + "math/big" + "os" + "strconv" + "strings" + "time" + + "github.com/ava-labs/avalanchego/api/info" + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/message" + "github.com/ava-labs/avalanchego/tests/fixture/tmpnet" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/set" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + relayerConfig "github.com/ava-labs/awm-relayer/config" + "github.com/ava-labs/awm-relayer/peers" + "github.com/ava-labs/awm-relayer/signature-aggregator/aggregator" + sigAggConfig "github.com/ava-labs/awm-relayer/signature-aggregator/config" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/eth/tracers" + "github.com/ava-labs/subnet-evm/ethclient" + subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" + "github.com/ava-labs/teleporter/tests/interfaces" + gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" + "github.com/prometheus/client_golang/prometheus" +) + +const ( + CChainPathSpecifier = "C" +) + +var NativeTransferGas uint64 = 21_000 + +var WarpEnabledChainConfig = tmpnet.FlagsMap{ + "log-level": "debug", + "warp-api-enabled": true, + "local-txs-enabled": true, + "eth-apis": []string{ + "eth", + "eth-filter", + "net", + "admin", + "web3", + "internal-eth", + "internal-blockchain", + "internal-transaction", + "internal-debug", + "internal-account", + "internal-personal", + "debug", + "debug-tracer", + "debug-file-tracer", + "debug-handler", + }, +} + +// +// URL utils +// + +func HttpToWebsocketURI(uri string, blockchainID string) string { + return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +func HttpToRPCURI(uri string, blockchainID string) string { + return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) +} + +// Get the host and port from a URI. The URI should be in the format http://host:port or https://host:port +func GetURIHostAndPort(uri string) (string, uint32, error) { + // At a minimum uri should have http:// of 7 characters + Expect(len(uri)).Should(BeNumerically(">", 7)) + if uri[:7] == "http://" { + uri = uri[7:] + } else if uri[:8] == "https://" { + uri = uri[8:] + } else { + return "", 0, fmt.Errorf("invalid uri: %s", uri) + } + + // Split the uri into host and port + hostAndPort := strings.Split(uri, ":") + Expect(len(hostAndPort)).Should(Equal(2)) + + // Parse the port + port, err := strconv.ParseUint(hostAndPort[1], 10, 32) + if err != nil { + return "", 0, fmt.Errorf("failed to parse port: %w", err) + } + + return hostAndPort[0], uint32(port), nil +} + +// +// Transaction utils +// + +func CreateNativeTransferTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Transaction { + fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fromAddress) + + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: subnetInfo.EVMChainID, + Nonce: nonce, + To: &recipient, + Gas: NativeTransferGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: amount, + }) + + return SignTransaction(tx, fromKey, subnetInfo.EVMChainID) +} + +func SendNativeTransfer( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fromKey *ecdsa.PrivateKey, + recipient common.Address, + amount *big.Int, +) *types.Receipt { + tx := CreateNativeTransferTransaction(ctx, subnetInfo, fromKey, recipient, amount) + return SendTransactionAndWaitForSuccess(ctx, subnetInfo, tx) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals success. +func sendAndWaitForTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, + success bool, +) *types.Receipt { + err := subnetInfo.RPCClient.SendTransaction(ctx, tx) + Expect(err).Should(BeNil()) + + return waitForTransaction(ctx, subnetInfo, tx.Hash(), success) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals false. +func SendTransactionAndWaitForFailure( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, subnetInfo, tx, false) +} + +// Sends a tx, and waits for it to be mined. +// Asserts Receipt.status equals true. +func SendTransactionAndWaitForSuccess( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + tx *types.Transaction, +) *types.Receipt { + return sendAndWaitForTransaction(ctx, subnetInfo, tx, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals true. +func WaitForTransactionSuccess( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, subnetInfo, txHash, true) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals false. +func WaitForTransactionFailure( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, +) *types.Receipt { + return waitForTransaction(ctx, subnetInfo, txHash, false) +} + +// Waits for a transaction to be mined. +// Asserts Receipt.status equals success. +func waitForTransaction( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + txHash common.Hash, + success bool, +) *types.Receipt { + cctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + receipt, err := WaitMined(cctx, subnetInfo.RPCClient, txHash) + Expect(err).Should(BeNil()) + + if success { + if receipt.Status == types.ReceiptStatusFailed { + TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) + } + } else { + Expect(receipt.Status).Should(Equal(types.ReceiptStatusFailed)) + } + return receipt +} + +// Polls for a transaction receipt of the given txHash on each queryTicker tick until +// either a transaction receipt returned, or the context is cancelled or expired. +func waitForTransactionReceipt( + cctx context.Context, + rpcClient ethclient.Client, + txHash common.Hash, +) (*types.Receipt, error) { + queryTicker := time.NewTicker(200 * time.Millisecond) + defer queryTicker.Stop() + for { + receipt, err := rpcClient.TransactionReceipt(cctx, txHash) + if err == nil { + return receipt, nil + } + + if errors.Is(err, subnetEvmInterfaces.NotFound) { + log.Debug("Transaction not yet mined") + } else { + log.Error("Receipt retrieval failed", "err", err) + return nil, err + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return nil, cctx.Err() + case <-queryTicker.C: + } + } +} + +// Signs a transaction using the provided key for the specified chainID +func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { + txSigner := types.LatestSignerForChainID(chainID) + signedTx, err := types.SignTx(tx, txSigner, key) + Expect(err).Should(BeNil()) + + return signedTx +} + +// Returns the gasFeeCap, gasTipCap, and nonce the be used when constructing a transaction from fundedAddress +func CalculateTxParams( + ctx context.Context, + subnetInfo interfaces.SubnetTestInfo, + fundedAddress common.Address, +) (*big.Int, *big.Int, uint64) { + baseFee, err := subnetInfo.RPCClient.EstimateBaseFee(ctx) + Expect(err).Should(BeNil()) + + gasTipCap, err := subnetInfo.RPCClient.SuggestGasTipCap(ctx) + Expect(err).Should(BeNil()) + + nonce, err := subnetInfo.RPCClient.NonceAt(ctx, fundedAddress, nil) + Expect(err).Should(BeNil()) + + gasFeeCap := baseFee.Mul(baseFee, big.NewInt(gasUtils.BaseFeeFactor)) + gasFeeCap.Add(gasFeeCap, big.NewInt(gasUtils.MaxPriorityFeePerGas)) + + return gasFeeCap, gasTipCap, nonce +} + +// Gomega will print the transaction trace and exit +func TraceTransactionAndExit(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) { + Expect(TraceTransaction(ctx, rpcClient, txHash)).Should(Equal("")) +} + +func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) string { + var result interface{} + ct := "callTracer" + err := rpcClient.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) + Expect(err).Should(BeNil()) + + jsonStr, err := json.Marshal(result) + Expect(err).Should(BeNil()) + + return string(jsonStr) +} + +// +// Block utils +// + +// WaitMined waits for tx to be mined on the blockchain. +// It stops waiting when the context is canceled. +// Takes a tx hash instead of the full tx in the subnet-evm version of this function. +// Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 +func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { + cctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + + receipt, err := waitForTransactionReceipt(cctx, rpcClient, txHash) + if err != nil { + return nil, err + } + + // Check that the block height endpoint returns a block height as high as the block number that the transaction was + // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see + // transactions/blocks at different points in time. Ideally, all nodes in the network should have seen this block + // and transaction before returning from WaitMined. The block height endpoint of public RPC endpoints is + // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for + // it to be at least as high as the block height specified in the receipt should provide a relatively strong + // indication that the transaction has been seen widely throughout the network. + err = waitForBlockHeight(cctx, rpcClient, receipt.BlockNumber.Uint64()) + if err != nil { + return nil, err + } + + return receipt, nil +} + +// Polls for the eth_blockNumber endpoint for the latest blockheight on each queryTicker tick until +// either the returned height is greater than or equal to the expectedBlockNumber, or the context +// is cancelled or expired. +func waitForBlockHeight( + cctx context.Context, + rpcClient ethclient.Client, + expectedBlockNumber uint64, +) error { + queryTicker := time.NewTicker(2 * time.Second) + defer queryTicker.Stop() + for { + currentBlockNumber, err := rpcClient.BlockNumber(cctx) + if err != nil { + return err + } + + if currentBlockNumber >= expectedBlockNumber { + return nil + } else { + log.Info("Waiting for block height where transaction was included", + "blockNumber", expectedBlockNumber) + } + + // Wait for the next round. + select { + case <-cctx.Done(): + return cctx.Err() + case <-queryTicker.C: + } + } +} + +// +// Log utils +// + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +// Errors and prints a trace of the transaction if no log is found. +func GetEventFromLogsOrTrace[T any]( + ctx context.Context, + receipt *types.Receipt, + subnetInfo interfaces.SubnetTestInfo, + parser func(log types.Log) (T, error), +) T { + log, err := GetEventFromLogs(receipt.Logs, parser) + if err != nil { + TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) + } + return log +} + +// Returns the first log in 'logs' that is successfully parsed by 'parser' +func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { + for _, log := range logs { + event, err := parser(*log) + if err == nil { + return event, nil + } + } + return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) +} + +// +// Account utils +// + +func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { + return crypto.PubkeyToAddress(k.PublicKey) +} + +// Throws a Gomega error if there is a mismatch +func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, rpcClient ethclient.Client) { + bal, err := rpcClient.BalanceAt(ctx, addr, nil) + Expect(err).Should(BeNil()) + ExpectBigEqual(bal, expectedBalance) +} + +// +// Big int utils +// + +func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { + // Compare strings, so gomega will print the numbers if they differ + Expect(v1.String()).Should(Equal(v2.String())) +} + +func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Sub(v1, v2) +} + +func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { + return big.NewInt(0).Mul(v1, v2) +} + +// +// Network utils +// + +func GetPChainInfo(cChainInfo interfaces.SubnetTestInfo) interfaces.SubnetTestInfo { + pChainBlockchainID, err := info.NewClient(cChainInfo.NodeURIs[0]).GetBlockchainID(context.Background(), "P") + Expect(err).Should(BeNil()) + return interfaces.SubnetTestInfo{ + BlockchainID: pChainBlockchainID, + SubnetID: ids.Empty, + } +} + +func GetTwoSubnets(network interfaces.Network) ( + interfaces.SubnetTestInfo, + interfaces.SubnetTestInfo, +) { + subnets := network.GetSubnetsInfo() + Expect(len(subnets)).Should(BeNumerically(">=", 2)) + return subnets[0], subnets[1] +} + +type ChainConfigMap map[string]string + +// Sets the chain config in customChainConfigs for the specified subnet +func (m ChainConfigMap) Add(subnet interfaces.SubnetTestInfo, chainConfig string) { + if subnet.SubnetID == constants.PrimaryNetworkID { + m[CChainPathSpecifier] = chainConfig + } else { + m[subnet.BlockchainID.String()] = chainConfig + } +} + +func GetChainConfigWithOffChainMessages(offChainMessages []avalancheWarp.UnsignedMessage) string { + // Convert messages to hex + hexOffChainMessages := []string{} + for _, message := range offChainMessages { + hexOffChainMessages = append(hexOffChainMessages, hexutil.Encode(message.Bytes())) + } + + chainConfig := WarpEnabledChainConfig + chainConfig["warp-off-chain-messages"] = hexOffChainMessages + + // Marshal the map to JSON + offChainMessageJson, err := tmpnet.DefaultJSONMarshal(chainConfig) + Expect(err).Should(BeNil()) + + return string(offChainMessageJson) +} + +// read in the template file, make the substitutions declared at the beginning +// of the function, write out the instantiation to a temp file, and then return +// the path to that temp file. +func InstantiateGenesisTemplate( + templateFileName string, + chainID uint64, + teleporterContractAddress common.Address, + teleporterDeployedBytecode string, + teleporterDeployerAddress common.Address, +) string { + substitutions := []struct { + Target string + Value string + }{ + { + "", + strconv.FormatUint(chainID, 10), + }, + { + "", + teleporterContractAddress.Hex(), + }, + { + "", + teleporterDeployedBytecode, + }, + { + "", + teleporterDeployerAddress.Hex(), + }, + } + + templateFileBytes, err := os.ReadFile(templateFileName) + Expect(err).Should(BeNil()) + + subnetGenesisFile, err := os.CreateTemp(os.TempDir(), "") + Expect(err).Should(BeNil()) + + defer subnetGenesisFile.Close() + + var replaced string = string(templateFileBytes[:]) + for _, s := range substitutions { + replaced = strings.ReplaceAll(replaced, s.Target, s.Value) + } + + subnetGenesisFile.WriteString(replaced) + + return subnetGenesisFile.Name() +} + +// +// Aggregator utils +// + +func NewSignatureAggregator(apiUri string, subnets []ids.ID) *aggregator.SignatureAggregator { + logger := logging.NoLog{} + cfg := sigAggConfig.Config{ + PChainAPI: &relayerConfig.APIConfig{ + BaseURL: apiUri, + }, + InfoAPI: &relayerConfig.APIConfig{ + BaseURL: apiUri, + }, + } + trackedSubnets := set.NewSet[ids.ID](len(subnets)) + trackedSubnets.Add(subnets...) + registry := prometheus.NewRegistry() + appRequestNetwork, err := peers.NewNetwork( + logging.Debug, + registry, + trackedSubnets, + &cfg, + ) + Expect(err).Should(BeNil()) + + messageCreator, err := message.NewCreator( + logger, + registry, + constants.DefaultNetworkCompressionType, + constants.DefaultNetworkMaximumInboundTimeout, + ) + Expect(err).Should(BeNil()) + return aggregator.NewSignatureAggregator( + appRequestNetwork, + logger, + messageCreator, + ) +} diff --git a/tests/utils/erc20.go b/tests/utils/erc20.go new file mode 100644 index 000000000..b235dbf6d --- /dev/null +++ b/tests/utils/erc20.go @@ -0,0 +1,61 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "math/big" + + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +var ( + ExpectedExampleERC20DeployerBalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e10)) +) + +func DeployExampleERC20( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + source interfaces.SubnetTestInfo, +) (common.Address, *exampleerc20.ExampleERC20) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + + // Deploy Mock ERC20 contract + address, tx, token, err := exampleerc20.DeployExampleERC20(opts, source.RPCClient) + Expect(err).Should(BeNil()) + log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, source, tx.Hash()) + + // Check that the deployer has the expected initial balance + senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) + balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) + Expect(err).Should(BeNil()) + Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) + + return address, token +} + +func ERC20Approve( + ctx context.Context, + token *exampleerc20.ExampleERC20, + spender common.Address, + amount *big.Int, + source interfaces.SubnetTestInfo, + senderKey *ecdsa.PrivateKey, +) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := token.Approve(opts, spender, amount) + Expect(err).Should(BeNil()) + log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) + + WaitForTransactionSuccess(ctx, source, tx.Hash()) +} diff --git a/tests/utils/governance.go b/tests/utils/governance.go new file mode 100644 index 000000000..177d3f017 --- /dev/null +++ b/tests/utils/governance.go @@ -0,0 +1,108 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + . "github.com/onsi/gomega" +) + +func DeployValidatorSetSig( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + contractSubnet interfaces.SubnetTestInfo, + validatorSubnet interfaces.SubnetTestInfo, +) (common.Address, *validatorsetsig.ValidatorSetSig) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, contractSubnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, validatorSetSig, err := validatorsetsig.DeployValidatorSetSig( + opts, + contractSubnet.RPCClient, + validatorSubnet.BlockchainID, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, contractSubnet, tx.Hash()) + + return address, validatorSetSig +} + +// Returns Receipt for the transaction unlike TeleporterRegistry version since this is a non-teleporter case +// and we don't want to add the ValidatorSetSig ABI to the subnetInfo +func ExecuteValidatorSetSigCallAndVerify( + ctx context.Context, + network interfaces.Network, + source interfaces.SubnetTestInfo, + destination interfaces.SubnetTestInfo, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + unsignedMessage *avalancheWarp.UnsignedMessage, + expectSuccess bool, +) *types.Receipt { + signedWarpMsg := network.GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) + log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) + + signedPredicateTx := CreateExecuteCallPredicateTransaction( + ctx, + signedWarpMsg, + validatorSetSigAddress, + senderKey, + destination, + ) + + // Wait for tx to be accepted and verify events emitted + if expectSuccess { + return SendTransactionAndWaitForSuccess(ctx, destination, signedPredicateTx) + } + return SendTransactionAndWaitForFailure(ctx, destination, signedPredicateTx) +} + +func InitOffChainMessageChainConfigValidatorSetSig( + networkID uint32, + subnet interfaces.SubnetTestInfo, + validatorSetSigAddress common.Address, + validatorSetSigMessages []validatorsetsig.ValidatorSetSigMessage, +) ([]avalancheWarp.UnsignedMessage, string) { + unsignedMessages := []avalancheWarp.UnsignedMessage{} + for _, message := range validatorSetSigMessages { + unsignedMessage := CreateOffChainValidatorSetSigMessage(networkID, subnet, message) + unsignedMessages = append(unsignedMessages, *unsignedMessage) + log.Info("Adding validatorSetSig off-chain message to Warp chain config", + "messageID", unsignedMessage.ID(), + "blockchainID", subnet.BlockchainID.String()) + } + return unsignedMessages, GetChainConfigWithOffChainMessages(unsignedMessages) +} + +// Creates an off-chain Warp message pointing to a function, contract and payload to be executed +// if the validator set signs this message +func CreateOffChainValidatorSetSigMessage( + networkID uint32, + subnet interfaces.SubnetTestInfo, + message validatorsetsig.ValidatorSetSigMessage, +) *avalancheWarp.UnsignedMessage { + sourceAddress := []byte{} + payloadBytes, err := message.Pack() + Expect(err).Should(BeNil()) + + addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) + Expect(err).Should(BeNil()) + + unsignedMessage, err := avalancheWarp.NewUnsignedMessage( + networkID, + subnet.BlockchainID, + addressedPayload.Bytes(), + ) + Expect(err).Should(BeNil()) + + return unsignedMessage +} diff --git a/tests/utils/staking.go b/tests/utils/staking.go new file mode 100644 index 000000000..8be531e5c --- /dev/null +++ b/tests/utils/staking.go @@ -0,0 +1,453 @@ +package utils + +import ( + "context" + "crypto/ecdsa" + "math/big" + "time" + + "github.com/ava-labs/avalanchego/ids" + "github.com/ava-labs/avalanchego/utils/crypto/bls" + avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" + warpMessages "github.com/ava-labs/avalanchego/vms/platformvm/warp/messages" + warpPayload "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" + "github.com/ava-labs/awm-relayer/signature-aggregator/aggregator" + "github.com/ava-labs/subnet-evm/accounts/abi" + "github.com/ava-labs/subnet-evm/accounts/abi/bind" + "github.com/ava-labs/subnet-evm/core/types" + "github.com/ava-labs/subnet-evm/precompile/contracts/warp" + predicateutils "github.com/ava-labs/subnet-evm/predicate" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + erc20tokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/staking/ERC20TokenStakingManager" + nativetokenstakingmanager "github.com/ava-labs/teleporter/abi-bindings/go/staking/NativeTokenStakingManager" + "github.com/ava-labs/teleporter/tests/interfaces" + "github.com/ethereum/go-ethereum/common" + + . "github.com/onsi/gomega" +) + +// +// Deployment utils +// + +func DeployNativeTokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, +) (common.Address, *nativetokenstakingmanager.NativeTokenStakingManager) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, stakingManager, err := nativetokenstakingmanager.DeployNativeTokenStakingManager( + opts, + subnet.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, stakingManager +} + +func DeployAndInitializeNativeTokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, +) (common.Address, *nativetokenstakingmanager.NativeTokenStakingManager) { + stakingManagerContractAddress, stakingManager := DeployNativeTokenStakingManager( + ctx, + senderKey, + subnet, + ) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.Initialize( + opts, + nativetokenstakingmanager.StakingManagerSettings{ + PChainBlockchainID: pChainInfo.BlockchainID, + SubnetID: subnet.SubnetID, + MinimumStakeAmount: big.NewInt(0).SetUint64(1e6), + MaximumStakeAmount: big.NewInt(0).SetUint64(10e6), + MinimumStakeDuration: uint64(24 * time.Hour), + MaximumHourlyChurn: 0, + RewardCalculator: common.Address{}, + }, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + + return stakingManagerContractAddress, stakingManager +} + +func DeployERC20TokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, +) (common.Address, *erc20tokenstakingmanager.ERC20TokenStakingManager) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + address, tx, stakingManager, err := erc20tokenstakingmanager.DeployERC20TokenStakingManager( + opts, + subnet.RPCClient, + 0, // ICMInitializable.Allowed + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, stakingManager +} + +func DeployAndInitializeERC20TokenStakingManager( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, +) ( + common.Address, + *erc20tokenstakingmanager.ERC20TokenStakingManager, + common.Address, + *exampleerc20.ExampleERC20, +) { + stakingManagerContractAddress, stakingManager := DeployERC20TokenStakingManager( + ctx, + senderKey, + subnet, + ) + + erc20Address, erc20 := DeployExampleERC20(ctx, senderKey, subnet) + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.Initialize( + opts, + erc20tokenstakingmanager.StakingManagerSettings{ + PChainBlockchainID: pChainInfo.BlockchainID, + SubnetID: subnet.SubnetID, + MinimumStakeAmount: big.NewInt(0).SetUint64(1e6), + MaximumStakeAmount: big.NewInt(0).SetUint64(10e6), + MinimumStakeDuration: uint64(24 * time.Hour), + MaximumHourlyChurn: 0, + RewardCalculator: common.Address{}, + }, + erc20Address, + ) + Expect(err).Should(BeNil()) + WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + + return stakingManagerContractAddress, stakingManager, erc20Address, erc20 +} + +// +// Function call utils +// + +func InitializeNativeValidatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakeAmount uint64, + nodeID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + opts.Value = big.NewInt(0).SetUint64(stakeAmount) + + tx, err := stakingManager.InitializeValidatorRegistration( + opts, + nodeID, + uint64(time.Now().Add(24*time.Hour).Unix()), + blsPublicKey[:], + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodCreated, + ) + Expect(err).Should(BeNil()) + return receipt, ids.ID(registrationInitiatedEvent.ValidationID) +} + +func InitializeERC20ValidatorRegistration( + senderKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakeAmount uint64, + token *exampleerc20.ExampleERC20, + stakingManagerAddress common.Address, + nodeID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, +) (*types.Receipt, ids.ID) { + ERC20Approve( + context.Background(), + token, + stakingManagerAddress, + big.NewInt(0).SetUint64(stakeAmount), + subnet, + senderKey, + ) + + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + + tx, err := stakingManager.InitializeValidatorRegistration( + opts, + big.NewInt(0).SetUint64(stakeAmount), + nodeID, + uint64(time.Now().Add(24*time.Hour).Unix()), + blsPublicKey[:], + ) + Expect(err).Should(BeNil()) + receipt := WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) + registrationInitiatedEvent, err := GetEventFromLogs( + receipt.Logs, + stakingManager.ParseValidationPeriodCreated, + ) + Expect(err).Should(BeNil()) + return receipt, ids.ID(registrationInitiatedEvent.ValidationID) +} + +func CompleteNativeValidatorRegistration( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + return completeValidatorRegistration( + abi, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompleteERC20ValidatorRegistration( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + return completeValidatorRegistration( + abi, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func completeValidatorRegistration( + abi *abi.ABI, + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + callData, err := abi.Pack("completeValidatorRegistration", uint32(0)) + Expect(err).Should(BeNil()) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(context.Background(), subnet, PrivateKeyToAddress(sendingKey)) + registrationTx := predicateutils.NewPredicateTx( + subnet.EVMChainID, + nonce, + &stakingManagerContractAddress, + 2_000_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + registrationSignedMessage.Bytes(), + ) + signedRegistrationTx := SignTransaction(registrationTx, sendingKey, subnet.EVMChainID) + return SendTransactionAndWaitForSuccess(context.Background(), subnet, signedRegistrationTx) +} + +func InitializeEndNativeValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *nativetokenstakingmanager.NativeTokenStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndValidation( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func InitializeEndERC20Validation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManager *erc20tokenstakingmanager.ERC20TokenStakingManager, + validationID ids.ID, +) *types.Receipt { + opts, err := bind.NewKeyedTransactorWithChainID(sendingKey, subnet.EVMChainID) + Expect(err).Should(BeNil()) + tx, err := stakingManager.InitializeEndValidation( + opts, + validationID, + false, + 0, + ) + Expect(err).Should(BeNil()) + return WaitForTransactionSuccess(context.Background(), subnet, tx.Hash()) +} + +func CompleteEndNativeValidation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := nativetokenstakingmanager.NativeTokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + return callCompleteEndValidation( + abi, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func CompleteEndERC20Validation( + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + abi, err := erc20tokenstakingmanager.ERC20TokenStakingManagerMetaData.GetAbi() + Expect(err).Should(BeNil()) + return callCompleteEndValidation( + abi, + sendingKey, + subnet, + stakingManagerContractAddress, + registrationSignedMessage, + ) +} + +func callCompleteEndValidation( + abi *abi.ABI, + sendingKey *ecdsa.PrivateKey, + subnet interfaces.SubnetTestInfo, + stakingManagerContractAddress common.Address, + registrationSignedMessage *avalancheWarp.Message, +) *types.Receipt { + callData, err := abi.Pack("completeEndValidation", uint32(0), false) + Expect(err).Should(BeNil()) + gasFeeCap, gasTipCap, nonce := CalculateTxParams(context.Background(), subnet, PrivateKeyToAddress(sendingKey)) + registrationTx := predicateutils.NewPredicateTx( + subnet.EVMChainID, + nonce, + &stakingManagerContractAddress, + 2_000_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + registrationSignedMessage.Bytes(), + ) + signedRegistrationTx := SignTransaction(registrationTx, sendingKey, subnet.EVMChainID) + return SendTransactionAndWaitForSuccess(context.Background(), subnet, signedRegistrationTx) +} + +// +// P-Chain utils +// + +func ConstructSubnetValidatorRegistrationMessage( + validationID ids.ID, + valid bool, + subnet interfaces.SubnetTestInfo, + pChainInfo interfaces.SubnetTestInfo, + network interfaces.LocalNetwork, + signatureAggregator *aggregator.SignatureAggregator, +) *avalancheWarp.Message { + registrationPayload, err := warpMessages.NewSubnetValidatorRegistration(validationID, valid) + Expect(err).Should(BeNil()) + registrationAddressedCall, err := warpPayload.NewAddressedCall(common.Address{}.Bytes(), registrationPayload.Bytes()) + Expect(err).Should(BeNil()) + registrationUnsignedMessage, err := avalancheWarp.NewUnsignedMessage( + network.GetNetworkID(), + pChainInfo.BlockchainID, + registrationAddressedCall.Bytes(), + ) + Expect(err).Should(BeNil()) + + registrationSignedMessage, err := signatureAggregator.CreateSignedMessage( + registrationUnsignedMessage, + nil, + subnet.SubnetID, + 67, + ) + Expect(err).Should(BeNil()) + return registrationSignedMessage +} + +// +// Warp message validiation utils +// These will be replaced by the actual implementation on the P-Chain in the future +// + +func ValidateRegisterSubnetValidatorMessage( + signedWarpMessage *avalancheWarp.Message, + nodeID ids.ID, + weight uint64, + subnetID ids.ID, + blsPublicKey [bls.PublicKeyLen]byte, +) { + // Validate the Warp message, (this will be done on the P-Chain in the future) + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessages.Payload + ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + registerValidatorPayload, ok := payloadInterface.(*warpMessages.RegisterSubnetValidator) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(registerValidatorPayload.NodeID).Should(Equal(nodeID)) + Expect(registerValidatorPayload.Weight).Should(Equal(weight)) + Expect(registerValidatorPayload.SubnetID).Should(Equal(subnetID)) + Expect(registerValidatorPayload.BlsPubKey[:]).Should(Equal(blsPublicKey[:])) +} + +func ValidateSetSubnetValidatorWeightMessage( + signedWarpMessage *avalancheWarp.Message, + validationID ids.ID, + weight uint64, + nonce uint64, +) { + msg, err := warpPayload.ParseAddressedCall(signedWarpMessage.UnsignedMessage.Payload) + Expect(err).Should(BeNil()) + // Check that the addressed call payload is a registered Warp message type + var payloadInterface warpMessages.Payload + ver, err := warpMessages.Codec.Unmarshal(msg.Payload, &payloadInterface) + Expect(err).Should(BeNil()) + registerValidatorPayload, ok := payloadInterface.(*warpMessages.SetSubnetValidatorWeight) + Expect(ok).Should(BeTrue()) + + Expect(ver).Should(Equal(uint16(warpMessages.CodecVersion))) + Expect(registerValidatorPayload.ValidationID).Should(Equal(validationID)) + Expect(registerValidatorPayload.Weight).Should(Equal(weight)) + Expect(registerValidatorPayload.Nonce).Should(Equal(nonce)) +} diff --git a/tests/utils/utils.go b/tests/utils/teleporter.go similarity index 52% rename from tests/utils/utils.go rename to tests/utils/teleporter.go index 01df542d6..e8d9e9161 100644 --- a/tests/utils/utils.go +++ b/tests/utils/teleporter.go @@ -1,61 +1,112 @@ -// Copyright (C) 2023, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - package utils import ( "bytes" "context" "crypto/ecdsa" - "encoding/json" - "errors" - "fmt" "math/big" - "os" - "strconv" - "strings" - "time" - - validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" - exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" - teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/TeleporterMessenger" - teleporterregistry "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/registry/TeleporterRegistry" - testmessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/tests/TestMessenger" - deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" - gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/avalanchego/utils/constants" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" "github.com/ava-labs/subnet-evm/accounts/abi/bind" "github.com/ava-labs/subnet-evm/core/types" - "github.com/ava-labs/subnet-evm/eth/tracers" - "github.com/ava-labs/subnet-evm/ethclient" - subnetEvmInterfaces "github.com/ava-labs/subnet-evm/interfaces" "github.com/ava-labs/subnet-evm/precompile/contracts/warp" predicateutils "github.com/ava-labs/subnet-evm/predicate" + validatorsetsig "github.com/ava-labs/teleporter/abi-bindings/go/governance/ValidatorSetSig" + exampleerc20 "github.com/ava-labs/teleporter/abi-bindings/go/mocks/ExampleERC20" + teleportermessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/TeleporterMessenger" + teleporterregistry "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/registry/TeleporterRegistry" + testmessenger "github.com/ava-labs/teleporter/abi-bindings/go/teleporter/tests/TestMessenger" "github.com/ava-labs/teleporter/tests/interfaces" + deploymentUtils "github.com/ava-labs/teleporter/utils/deployment-utils" + gasUtils "github.com/ava-labs/teleporter/utils/gas-utils" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" . "github.com/onsi/gomega" ) var ( - NativeTransferGas uint64 = 21_000 - DefaultTeleporterTransactionGas uint64 = 300_000 - DefaultTeleporterTransactionValue = common.Big0 - ExpectedExampleERC20DeployerBalance = new(big.Int).Mul(big.NewInt(1e18), big.NewInt(1e10)) + DefaultTeleporterTransactionGas uint64 = 300_000 + DefaultTeleporterTransactionValue = common.Big0 ) -const ( - CChainPathSpecifier = "C" -) +// +// Deployment utils +// + +// Deploys a new version of Teleporter and returns its address +// Does NOT modify the global Teleporter contract address to provide greater testing flexibility. +func DeployNewTeleporterVersion( + ctx context.Context, + network interfaces.LocalNetwork, + fundedKey *ecdsa.PrivateKey, + teleporterByteCodeFile string, +) common.Address { + contractCreationGasPrice := (&big.Int{}).Add(deploymentUtils.GetDefaultContractCreationGasPrice(), big.NewInt(1)) + teleporterDeployerTransaction, + _, + teleporterDeployerAddress, + teleporterContractAddress, + err := deploymentUtils.ConstructKeylessTransaction( + teleporterByteCodeFile, + false, + contractCreationGasPrice, + ) + Expect(err).Should(BeNil()) + + network.DeployTeleporterContractToAllChains( + teleporterDeployerTransaction, + teleporterDeployerAddress, + teleporterContractAddress, + fundedKey, + ) + return teleporterContractAddress +} + +func DeployTestMessenger( + ctx context.Context, + senderKey *ecdsa.PrivateKey, + teleporterManager common.Address, + subnet interfaces.SubnetTestInfo, +) (common.Address, *testmessenger.TestMessenger) { + opts, err := bind.NewKeyedTransactorWithChainID( + senderKey, + subnet.EVMChainID, + ) + Expect(err).Should(BeNil()) + address, tx, exampleMessenger, err := testmessenger.DeployTestMessenger( + opts, + subnet.RPCClient, + subnet.TeleporterRegistryAddress, + teleporterManager, + ) + Expect(err).Should(BeNil()) + + // Wait for the transaction to be mined + WaitForTransactionSuccess(ctx, subnet, tx.Hash()) + + return address, exampleMessenger +} + +// +// Parsing utils +// + +func ParseTeleporterMessage(unsignedMessage avalancheWarp.UnsignedMessage) *teleportermessenger.TeleporterMessage { + addressedPayload, err := payload.ParseAddressedCall(unsignedMessage.Payload) + Expect(err).Should(BeNil()) + + teleporterMessage := teleportermessenger.TeleporterMessage{} + err = teleporterMessage.Unpack(addressedPayload.Payload) + Expect(err).Should(BeNil()) + + return &teleporterMessage +} // -// Test utility functions +// Function call utils // func SendAddFeeAmountAndWaitForAcceptance( @@ -190,183 +241,6 @@ func SendSpecifiedReceiptsAndWaitForAcceptance( return receipt, event.MessageID } -func HttpToWebsocketURI(uri string, blockchainID string) string { - return fmt.Sprintf("ws://%s/ext/bc/%s/ws", strings.TrimPrefix(uri, "http://"), blockchainID) -} - -func HttpToRPCURI(uri string, blockchainID string) string { - return fmt.Sprintf("http://%s/ext/bc/%s/rpc", strings.TrimPrefix(uri, "http://"), blockchainID) -} - -// Get the host and port from a URI. The URI should be in the format http://host:port or https://host:port -func GetURIHostAndPort(uri string) (string, uint32, error) { - // At a minimum uri should have http:// of 7 characters - Expect(len(uri)).Should(BeNumerically(">", 7)) - if uri[:7] == "http://" { - uri = uri[7:] - } else if uri[:8] == "https://" { - uri = uri[8:] - } else { - return "", 0, fmt.Errorf("invalid uri: %s", uri) - } - - // Split the uri into host and port - hostAndPort := strings.Split(uri, ":") - Expect(len(hostAndPort)).Should(Equal(2)) - - // Parse the port - port, err := strconv.ParseUint(hostAndPort[1], 10, 32) - if err != nil { - return "", 0, fmt.Errorf("failed to parse port: %w", err) - } - - return hostAndPort[0], uint32(port), nil -} - -// -// Transaction creation functions -// - -// Constructs a transaction to call sendCrossChainMessage -// Returns the signed transaction. -func CreateSendCrossChainMessageTransaction( - ctx context.Context, - source interfaces.SubnetTestInfo, - input teleportermessenger.TeleporterMessageInput, - senderKey *ecdsa.PrivateKey, - teleporterContractAddress common.Address, -) *types.Transaction { - data, err := teleportermessenger.PackSendCrossChainMessage(input) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) - - // Send a transaction to the Teleporter contract - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: source.EVMChainID, - Nonce: nonce, - To: &teleporterContractAddress, - Gas: DefaultTeleporterTransactionGas, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: DefaultTeleporterTransactionValue, - Data: data, - }) - - return SignTransaction(tx, senderKey, source.EVMChainID) -} - -// Constructs a transaction to call receiveCrossChainMessage -// Returns the signed transaction. -func CreateReceiveCrossChainMessageTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - requiredGasLimit *big.Int, - teleporterContractAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - // Construct the transaction to send the Warp message to the destination chain - log.Info("Constructing receiveCrossChainMessage transaction for the destination chain") - numSigners, err := signedMessage.Signature.NumSigners() - Expect(err).Should(BeNil()) - - teleporterMessage := ParseTeleporterMessage(signedMessage.UnsignedMessage) - gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( - numSigners, - requiredGasLimit, - len(signedMessage.Bytes()), - len(signedMessage.Payload), - len(teleporterMessage.Receipts), - ) - Expect(err).Should(BeNil()) - - callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &teleporterContractAddress, - gasLimit, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - -// Constructs a transaction to call addProtocolVersion -// Returns the signed transaction. -func CreateAddProtocolVersionTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - teleporterRegistryAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - // Construct the transaction to send the Warp message to the destination chain - log.Info("Constructing addProtocolVersion transaction for the destination chain") - - callData, err := teleporterregistry.PackAddProtocolVersion(0) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &teleporterRegistryAddress, - 500_000, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - -func CreateExecuteCallPredicateTransaction( - ctx context.Context, - signedMessage *avalancheWarp.Message, - validatorSetSigAddress common.Address, - senderKey *ecdsa.PrivateKey, - subnetInfo interfaces.SubnetTestInfo, -) *types.Transaction { - log.Info("Constructing executeCall transaction for the destination chain") - - callData, err := validatorsetsig.PackExecuteCall(0) - Expect(err).Should(BeNil()) - - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) - - destinationTx := predicateutils.NewPredicateTx( - subnetInfo.EVMChainID, - nonce, - &validatorSetSigAddress, - 500_000, - gasFeeCap, - gasTipCap, - big.NewInt(0), - callData, - types.AccessList{}, - warp.ContractAddress, - signedMessage.Bytes(), - ) - return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) -} - func AddProtocolVersionAndWaitForAcceptance( ctx context.Context, network interfaces.Network, @@ -404,113 +278,15 @@ func AddProtocolVersionAndWaitForAcceptance( Expect(versionUpdatedEvent.NewVersion.Cmp(expectedLatestVersion)).Should(Equal(0)) } -// Returns Receipt for the transaction unlike TeleporterRegistry version since this is a non-teleporter case -// and we don't want to add the ValidatorSetSig ABI to the subnetInfo -func ExecuteValidatorSetSigCallAndVerify( +func SendCrossChainMessageAndWaitForAcceptance( ctx context.Context, - network interfaces.Network, source interfaces.SubnetTestInfo, destination interfaces.SubnetTestInfo, - validatorSetSigAddress common.Address, + input teleportermessenger.TeleporterMessageInput, senderKey *ecdsa.PrivateKey, - unsignedMessage *avalancheWarp.UnsignedMessage, - expectSuccess bool, -) *types.Receipt { - signedWarpMsg := network.GetSignedMessage(ctx, source, destination, unsignedMessage.ID()) - log.Info("Got signed warp message", "messageID", signedWarpMsg.ID()) - - signedPredicateTx := CreateExecuteCallPredicateTransaction( - ctx, - signedWarpMsg, - validatorSetSigAddress, - senderKey, - destination, - ) - - // Wait for tx to be accepted and verify events emitted - if expectSuccess { - return SendTransactionAndWaitForSuccess(ctx, destination, signedPredicateTx) - } - return SendTransactionAndWaitForFailure(ctx, destination, signedPredicateTx) -} - -func CreateNativeTransferTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fromKey *ecdsa.PrivateKey, - recipient common.Address, - amount *big.Int, -) *types.Transaction { - fromAddress := crypto.PubkeyToAddress(fromKey.PublicKey) - gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, fromAddress) - - tx := types.NewTx(&types.DynamicFeeTx{ - ChainID: subnetInfo.EVMChainID, - Nonce: nonce, - To: &recipient, - Gas: NativeTransferGas, - GasFeeCap: gasFeeCap, - GasTipCap: gasTipCap, - Value: amount, - }) - - return SignTransaction(tx, fromKey, subnetInfo.EVMChainID) -} - -func SendNativeTransfer( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fromKey *ecdsa.PrivateKey, - recipient common.Address, - amount *big.Int, -) *types.Receipt { - tx := CreateNativeTransferTransaction(ctx, subnetInfo, fromKey, recipient, amount) - return SendTransactionAndWaitForSuccess(ctx, subnetInfo, tx) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals success. -func sendAndWaitForTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, - success bool, -) *types.Receipt { - err := subnetInfo.RPCClient.SendTransaction(ctx, tx) - Expect(err).Should(BeNil()) - - return waitForTransaction(ctx, subnetInfo, tx.Hash(), success) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals false. -func SendTransactionAndWaitForFailure( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, -) *types.Receipt { - return sendAndWaitForTransaction(ctx, subnetInfo, tx, false) -} - -// Sends a tx, and waits for it to be mined. -// Asserts Receipt.status equals true. -func SendTransactionAndWaitForSuccess( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - tx *types.Transaction, -) *types.Receipt { - return sendAndWaitForTransaction(ctx, subnetInfo, tx, true) -} - -func SendCrossChainMessageAndWaitForAcceptance( - ctx context.Context, - source interfaces.SubnetTestInfo, - destination interfaces.SubnetTestInfo, - input teleportermessenger.TeleporterMessageInput, - senderKey *ecdsa.PrivateKey, -) (*types.Receipt, ids.ID) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) +) (*types.Receipt, ids.ID) { + opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) + Expect(err).Should(BeNil()) // Send a transaction to the Teleporter contract tx, err := source.TeleporterMessenger.SendCrossChainMessage(opts, input) @@ -531,167 +307,6 @@ func SendCrossChainMessageAndWaitForAcceptance( return receipt, event.MessageID } -// Waits for a transaction to be mined. -// Asserts Receipt.status equals true. -func WaitForTransactionSuccess( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, -) *types.Receipt { - return waitForTransaction(ctx, subnetInfo, txHash, true) -} - -// Waits for a transaction to be mined. -// Asserts Receipt.status equals false. -func WaitForTransactionFailure( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, -) *types.Receipt { - return waitForTransaction(ctx, subnetInfo, txHash, false) -} - -// Waits for a transaction to be mined. -// Asserts Receipt.status equals success. -func waitForTransaction( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - txHash common.Hash, - success bool, -) *types.Receipt { - cctx, cancel := context.WithTimeout(ctx, 10*time.Second) - defer cancel() - - receipt, err := WaitMined(cctx, subnetInfo.RPCClient, txHash) - Expect(err).Should(BeNil()) - - if success { - if receipt.Status == types.ReceiptStatusFailed { - TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) - } - } else { - Expect(receipt.Status).Should(Equal(types.ReceiptStatusFailed)) - } - return receipt -} - -// Polls for a transaction receipt of the given txHash on each queryTicker tick until -// either a transaction receipt returned, or the context is cancelled or expired. -func waitForTransactionReceipt( - cctx context.Context, - rpcClient ethclient.Client, - txHash common.Hash, -) (*types.Receipt, error) { - queryTicker := time.NewTicker(200 * time.Millisecond) - defer queryTicker.Stop() - for { - receipt, err := rpcClient.TransactionReceipt(cctx, txHash) - if err == nil { - return receipt, nil - } - - if errors.Is(err, subnetEvmInterfaces.NotFound) { - log.Debug("Transaction not yet mined") - } else { - log.Error("Receipt retrieval failed", "err", err) - return nil, err - } - - // Wait for the next round. - select { - case <-cctx.Done(): - return nil, cctx.Err() - case <-queryTicker.C: - } - } -} - -// Polls for the eth_blockNumber endpoint for the latest blockheight on each queryTicker tick until -// either the returned height is greater than or equal to the expectedBlockNumber, or the context -// is cancelled or expired. -func waitForBlockHeight( - cctx context.Context, - rpcClient ethclient.Client, - expectedBlockNumber uint64, -) error { - queryTicker := time.NewTicker(2 * time.Second) - defer queryTicker.Stop() - for { - currentBlockNumber, err := rpcClient.BlockNumber(cctx) - if err != nil { - return err - } - - if currentBlockNumber >= expectedBlockNumber { - return nil - } else { - log.Info("Waiting for block height where transaction was included", - "blockNumber", expectedBlockNumber) - } - - // Wait for the next round. - select { - case <-cctx.Done(): - return cctx.Err() - case <-queryTicker.C: - } - } -} - -// WaitMined waits for tx to be mined on the blockchain. -// It stops waiting when the context is canceled. -// Takes a tx hash instead of the full tx in the subnet-evm version of this function. -// Copied and modified from https://github.com/ava-labs/subnet-evm/blob/v0.6.0-fuji/accounts/abi/bind/util.go#L42 -func WaitMined(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) (*types.Receipt, error) { - cctx, cancel := context.WithTimeout(ctx, 20*time.Second) - defer cancel() - - receipt, err := waitForTransactionReceipt(cctx, rpcClient, txHash) - if err != nil { - return nil, err - } - - // Check that the block height endpoint returns a block height as high as the block number that the transaction was - // included in. This is to workaround the issue where multiple nodes behind a public RPC endpoint see - // transactions/blocks at different points in time. Ideally, all nodes in the network should have seen this block - // and transaction before returning from WaitMined. The block height endpoint of public RPC endpoints is - // configured to return the lowest value currently returned by any node behind the load balancer, so waiting for - // it to be at least as high as the block height specified in the receipt should provide a relatively strong - // indication that the transaction has been seen widely throughout the network. - err = waitForBlockHeight(cctx, rpcClient, receipt.BlockNumber.Uint64()) - if err != nil { - return nil, err - } - - return receipt, nil -} - -// Returns the first log in 'logs' that is successfully parsed by 'parser' -// Errors and prints a trace of the transaction if no log is found. -func GetEventFromLogsOrTrace[T any]( - ctx context.Context, - receipt *types.Receipt, - subnetInfo interfaces.SubnetTestInfo, - parser func(log types.Log) (T, error), -) T { - log, err := GetEventFromLogs(receipt.Logs, parser) - if err != nil { - TraceTransactionAndExit(ctx, subnetInfo.RPCClient, receipt.TxHash) - } - return log -} - -// Returns the first log in 'logs' that is successfully parsed by 'parser' -func GetEventFromLogs[T any](logs []*types.Log, parser func(log types.Log) (T, error)) (T, error) { - for _, log := range logs { - event, err := parser(*log) - if err == nil { - return event, nil - } - } - return *new(T), fmt.Errorf("failed to find %T event in receipt logs", *new(T)) -} - // Returns true if the transaction receipt contains a ReceiptReceived log with the specified messageID func CheckReceiptReceived( receipt *types.Receipt, @@ -751,174 +366,6 @@ func GetOutstandingReceiptCount(source interfaces.SubnetTestInfo, destinationBlo return size } -// Signs a transaction using the provided key for the specified chainID -func SignTransaction(tx *types.Transaction, key *ecdsa.PrivateKey, chainID *big.Int) *types.Transaction { - txSigner := types.LatestSignerForChainID(chainID) - signedTx, err := types.SignTx(tx, txSigner, key) - Expect(err).Should(BeNil()) - - return signedTx -} - -// Returns the gasFeeCap, gasTipCap, and nonce the be used when constructing a transaction from fundedAddress -func CalculateTxParams( - ctx context.Context, - subnetInfo interfaces.SubnetTestInfo, - fundedAddress common.Address, -) (*big.Int, *big.Int, uint64) { - baseFee, err := subnetInfo.RPCClient.EstimateBaseFee(ctx) - Expect(err).Should(BeNil()) - - gasTipCap, err := subnetInfo.RPCClient.SuggestGasTipCap(ctx) - Expect(err).Should(BeNil()) - - nonce, err := subnetInfo.RPCClient.NonceAt(ctx, fundedAddress, nil) - Expect(err).Should(BeNil()) - - gasFeeCap := baseFee.Mul(baseFee, big.NewInt(gasUtils.BaseFeeFactor)) - gasFeeCap.Add(gasFeeCap, big.NewInt(gasUtils.MaxPriorityFeePerGas)) - - return gasFeeCap, gasTipCap, nonce -} - -func PrivateKeyToAddress(k *ecdsa.PrivateKey) common.Address { - return crypto.PubkeyToAddress(k.PublicKey) -} - -// Throws a Gomega error if there is a mismatch -func CheckBalance(ctx context.Context, addr common.Address, expectedBalance *big.Int, rpcClient ethclient.Client) { - bal, err := rpcClient.BalanceAt(ctx, addr, nil) - Expect(err).Should(BeNil()) - ExpectBigEqual(bal, expectedBalance) -} - -// Gomega will print the transaction trace and exit -func TraceTransactionAndExit(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) { - Expect(TraceTransaction(ctx, rpcClient, txHash)).Should(Equal("")) -} - -func TraceTransaction(ctx context.Context, rpcClient ethclient.Client, txHash common.Hash) string { - var result interface{} - ct := "callTracer" - err := rpcClient.Client().Call(&result, "debug_traceTransaction", txHash.String(), tracers.TraceConfig{Tracer: &ct}) - Expect(err).Should(BeNil()) - - jsonStr, err := json.Marshal(result) - Expect(err).Should(BeNil()) - - return string(jsonStr) -} - -func ExpectBigEqual(v1 *big.Int, v2 *big.Int) { - // Compare strings, so gomega will print the numbers if they differ - Expect(v1.String()).Should(Equal(v2.String())) -} - -func BigIntSub(v1 *big.Int, v2 *big.Int) *big.Int { - return big.NewInt(0).Sub(v1, v2) -} - -func BigIntMul(v1 *big.Int, v2 *big.Int) *big.Int { - return big.NewInt(0).Mul(v1, v2) -} - -func ERC20Approve( - ctx context.Context, - token *exampleerc20.ExampleERC20, - spender common.Address, - amount *big.Int, - source interfaces.SubnetTestInfo, - senderKey *ecdsa.PrivateKey, -) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) - tx, err := token.Approve(opts, spender, amount) - Expect(err).Should(BeNil()) - log.Info("Approved ERC20", "spender", spender.Hex(), "txHash", tx.Hash().Hex()) - - WaitForTransactionSuccess(ctx, source, tx.Hash()) -} - -func DeployExampleERC20( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - source interfaces.SubnetTestInfo, -) (common.Address, *exampleerc20.ExampleERC20) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, source.EVMChainID) - Expect(err).Should(BeNil()) - - // Deploy Mock ERC20 contract - address, tx, token, err := exampleerc20.DeployExampleERC20(opts, source.RPCClient) - Expect(err).Should(BeNil()) - log.Info("Deployed Mock ERC20 contract", "address", address.Hex(), "txHash", tx.Hash().Hex()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, source, tx.Hash()) - - // Check that the deployer has the expected initial balance - senderAddress := crypto.PubkeyToAddress(senderKey.PublicKey) - balance, err := token.BalanceOf(&bind.CallOpts{}, senderAddress) - Expect(err).Should(BeNil()) - Expect(balance).Should(Equal(ExpectedExampleERC20DeployerBalance)) - - return address, token -} - -func DeployTestMessenger( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - teleporterManager common.Address, - subnet interfaces.SubnetTestInfo, -) (common.Address, *testmessenger.TestMessenger) { - opts, err := bind.NewKeyedTransactorWithChainID( - senderKey, - subnet.EVMChainID, - ) - Expect(err).Should(BeNil()) - address, tx, exampleMessenger, err := testmessenger.DeployTestMessenger( - opts, - subnet.RPCClient, - subnet.TeleporterRegistryAddress, - teleporterManager, - ) - Expect(err).Should(BeNil()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, subnet, tx.Hash()) - - return address, exampleMessenger -} - -func DeployValidatorSetSig( - ctx context.Context, - senderKey *ecdsa.PrivateKey, - contractSubnet interfaces.SubnetTestInfo, - validatorSubnet interfaces.SubnetTestInfo, -) (common.Address, *validatorsetsig.ValidatorSetSig) { - opts, err := bind.NewKeyedTransactorWithChainID(senderKey, contractSubnet.EVMChainID) - Expect(err).Should(BeNil()) - address, tx, validatorSetSig, err := validatorsetsig.DeployValidatorSetSig( - opts, - contractSubnet.RPCClient, - validatorSubnet.BlockchainID, - ) - Expect(err).Should(BeNil()) - - // Wait for the transaction to be mined - WaitForTransactionSuccess(ctx, contractSubnet, tx.Hash()) - - return address, validatorSetSig -} - -func GetTwoSubnets(network interfaces.Network) ( - interfaces.SubnetTestInfo, - interfaces.SubnetTestInfo, -) { - subnets := network.GetSubnetsInfo() - Expect(len(subnets)).Should(BeNumerically(">=", 2)) - return subnets[0], subnets[1] -} - func SendExampleCrossChainMessageAndVerify( ctx context.Context, network interfaces.Network, @@ -995,6 +442,154 @@ func SendExampleCrossChainMessageAndVerify( } } +// +// Transaction utils +// + +// Constructs a transaction to call sendCrossChainMessage +// Returns the signed transaction. +func CreateSendCrossChainMessageTransaction( + ctx context.Context, + source interfaces.SubnetTestInfo, + input teleportermessenger.TeleporterMessageInput, + senderKey *ecdsa.PrivateKey, + teleporterContractAddress common.Address, +) *types.Transaction { + data, err := teleportermessenger.PackSendCrossChainMessage(input) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, source, PrivateKeyToAddress(senderKey)) + + // Send a transaction to the Teleporter contract + tx := types.NewTx(&types.DynamicFeeTx{ + ChainID: source.EVMChainID, + Nonce: nonce, + To: &teleporterContractAddress, + Gas: DefaultTeleporterTransactionGas, + GasFeeCap: gasFeeCap, + GasTipCap: gasTipCap, + Value: DefaultTeleporterTransactionValue, + Data: data, + }) + + return SignTransaction(tx, senderKey, source.EVMChainID) +} + +// Constructs a transaction to call receiveCrossChainMessage +// Returns the signed transaction. +func CreateReceiveCrossChainMessageTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + requiredGasLimit *big.Int, + teleporterContractAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing receiveCrossChainMessage transaction for the destination chain") + numSigners, err := signedMessage.Signature.NumSigners() + Expect(err).Should(BeNil()) + + teleporterMessage := ParseTeleporterMessage(signedMessage.UnsignedMessage) + gasLimit, err := gasUtils.CalculateReceiveMessageGasLimit( + numSigners, + requiredGasLimit, + len(signedMessage.Bytes()), + len(signedMessage.Payload), + len(teleporterMessage.Receipts), + ) + Expect(err).Should(BeNil()) + + callData, err := teleportermessenger.PackReceiveCrossChainMessage(0, PrivateKeyToAddress(senderKey)) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &teleporterContractAddress, + gasLimit, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +// Constructs a transaction to call addProtocolVersion +// Returns the signed transaction. +func CreateAddProtocolVersionTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + teleporterRegistryAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + // Construct the transaction to send the Warp message to the destination chain + log.Info("Constructing addProtocolVersion transaction for the destination chain") + + callData, err := teleporterregistry.PackAddProtocolVersion(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &teleporterRegistryAddress, + 500_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +func CreateExecuteCallPredicateTransaction( + ctx context.Context, + signedMessage *avalancheWarp.Message, + validatorSetSigAddress common.Address, + senderKey *ecdsa.PrivateKey, + subnetInfo interfaces.SubnetTestInfo, +) *types.Transaction { + log.Info("Constructing executeCall transaction for the destination chain") + + callData, err := validatorsetsig.PackExecuteCall(0) + Expect(err).Should(BeNil()) + + gasFeeCap, gasTipCap, nonce := CalculateTxParams(ctx, subnetInfo, PrivateKeyToAddress(senderKey)) + + destinationTx := predicateutils.NewPredicateTx( + subnetInfo.EVMChainID, + nonce, + &validatorSetSigAddress, + 500_000, + gasFeeCap, + gasTipCap, + big.NewInt(0), + callData, + types.AccessList{}, + warp.ContractAddress, + signedMessage.Bytes(), + ) + return SignTransaction(destinationTx, senderKey, subnetInfo.EVMChainID) +} + +// +// Off-chain message utils +// + // Creates an Warp message that registers a Teleporter protocol version with TeleporterRegistry. // Returns the Warp message, as well as the chain config adding the message to the list of approved // off-chain Warp messages @@ -1038,172 +633,3 @@ func CreateOffChainRegistryMessage( return unsignedMessage } - -func InitOffChainMessageChainConfigValidatorSetSig( - networkID uint32, - subnet interfaces.SubnetTestInfo, - validatorSetSigAddress common.Address, - validatorSetSigMessages []validatorsetsig.ValidatorSetSigMessage, -) ([]avalancheWarp.UnsignedMessage, string) { - unsignedMessages := []avalancheWarp.UnsignedMessage{} - for _, message := range validatorSetSigMessages { - unsignedMessage := CreateOffChainValidatorSetSigMessage(networkID, subnet, message) - unsignedMessages = append(unsignedMessages, *unsignedMessage) - log.Info("Adding validatorSetSig off-chain message to Warp chain config", - "messageID", unsignedMessage.ID(), - "blockchainID", subnet.BlockchainID.String()) - } - return unsignedMessages, GetChainConfigWithOffChainMessages(unsignedMessages) -} - -// Creates an off-chain Warp message pointing to a function, contract and payload to be executed -// if the validator set signs this message -func CreateOffChainValidatorSetSigMessage( - networkID uint32, - subnet interfaces.SubnetTestInfo, - message validatorsetsig.ValidatorSetSigMessage, -) *avalancheWarp.UnsignedMessage { - sourceAddress := []byte{} - payloadBytes, err := message.Pack() - Expect(err).Should(BeNil()) - - addressedPayload, err := payload.NewAddressedCall(sourceAddress, payloadBytes) - Expect(err).Should(BeNil()) - - unsignedMessage, err := avalancheWarp.NewUnsignedMessage( - networkID, - subnet.BlockchainID, - addressedPayload.Bytes(), - ) - Expect(err).Should(BeNil()) - - return unsignedMessage -} - -// Deploys a new version of Teleporter and returns its address -// Does NOT modify the global Teleporter contract address to provide greater testing flexibility. -func DeployNewTeleporterVersion( - ctx context.Context, - network interfaces.LocalNetwork, - fundedKey *ecdsa.PrivateKey, - teleporterByteCodeFile string, -) common.Address { - contractCreationGasPrice := (&big.Int{}).Add(deploymentUtils.GetDefaultContractCreationGasPrice(), big.NewInt(1)) - teleporterDeployerTransaction, - _, - teleporterDeployerAddress, - teleporterContractAddress, - err := deploymentUtils.ConstructKeylessTransaction( - teleporterByteCodeFile, - false, - contractCreationGasPrice, - ) - Expect(err).Should(BeNil()) - - network.DeployTeleporterContractToAllChains( - teleporterDeployerTransaction, - teleporterDeployerAddress, - teleporterContractAddress, - fundedKey, - ) - return teleporterContractAddress -} - -type ChainConfigMap map[string]string - -// Sets the chain config in customChainConfigs for the specified subnet -func (m ChainConfigMap) Add(subnet interfaces.SubnetTestInfo, chainConfig string) { - if subnet.SubnetID == constants.PrimaryNetworkID { - m[CChainPathSpecifier] = chainConfig - } else { - m[subnet.BlockchainID.String()] = chainConfig - } -} - -func ParseTeleporterMessage(unsignedMessage avalancheWarp.UnsignedMessage) *teleportermessenger.TeleporterMessage { - addressedPayload, err := payload.ParseAddressedCall(unsignedMessage.Payload) - Expect(err).Should(BeNil()) - - teleporterMessage := teleportermessenger.TeleporterMessage{} - err = teleporterMessage.Unpack(addressedPayload.Payload) - Expect(err).Should(BeNil()) - - return &teleporterMessage -} - -func GetChainConfigWithOffChainMessages(offChainMessages []avalancheWarp.UnsignedMessage) string { - // Convert messages to hex - hexOffChainMessages := []string{} - for _, message := range offChainMessages { - hexOffChainMessages = append(hexOffChainMessages, hexutil.Encode(message.Bytes())) - } - - // Create a map to represent the JSON structure - jsonMap := map[string]interface{}{ - "warp-api-enabled": true, - "warp-off-chain-messages": hexOffChainMessages, - "log-level": "debug", - "eth-apis": []string{ - "eth", "eth-filter", "net", "admin", "web3", - "internal-eth", "internal-blockchain", "internal-transaction", - "internal-debug", "internal-account", "internal-personal", - "debug", "debug-tracer", "debug-file-tracer", "debug-handler", - }, - } - - // Marshal the map to JSON - offChainMessageJson, err := json.Marshal(jsonMap) - Expect(err).Should(BeNil()) - - return string(offChainMessageJson) -} - -// read in the template file, make the substitutions declared at the beginning -// of the function, write out the instantiation to a temp file, and then return -// the path to that temp file. -func InstantiateGenesisTemplate( - templateFileName string, - chainID uint64, - teleporterContractAddress common.Address, - teleporterDeployedBytecode string, - teleporterDeployerAddress common.Address, -) string { - substitutions := []struct { - Target string - Value string - }{ - { - "", - strconv.FormatUint(chainID, 10), - }, - { - "", - teleporterContractAddress.Hex(), - }, - { - "", - teleporterDeployedBytecode, - }, - { - "", - teleporterDeployerAddress.Hex(), - }, - } - - templateFileBytes, err := os.ReadFile(templateFileName) - Expect(err).Should(BeNil()) - - subnetGenesisFile, err := os.CreateTemp(os.TempDir(), "") - Expect(err).Should(BeNil()) - - defer subnetGenesisFile.Close() - - var replaced string = string(templateFileBytes[:]) - for _, s := range substitutions { - replaced = strings.ReplaceAll(replaced, s.Target, s.Value) - } - - subnetGenesisFile.WriteString(replaced) - - return subnetGenesisFile.Name() -}