From eae52b3f6f0b13a59195cd6b7b1d22c8fb0450cd Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 23 Sep 2022 12:37:26 +0200 Subject: [PATCH 1/6] Conjunction policy for sortition pool The ConjunctionPolicy requires all the provided policies to pass. It will allow to aggregate pre-params policy with beta operator policy together for tbtc. --- pkg/sortition/policy.go | 17 ++++++++++ pkg/sortition/policy_test.go | 65 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 pkg/sortition/policy.go create mode 100644 pkg/sortition/policy_test.go diff --git a/pkg/sortition/policy.go b/pkg/sortition/policy.go new file mode 100644 index 0000000000..fb53b8942e --- /dev/null +++ b/pkg/sortition/policy.go @@ -0,0 +1,17 @@ +package sortition + +// ConjunctionPolicy is a JoinPolicy implementation requiring all the provided +// policies to pass before allowing to join the sortition pool. +type ConjunctionPolicy struct { + policies []JoinPolicy +} + +func (cp *ConjunctionPolicy) ShouldJoin() bool { + for _, policy := range cp.policies { + if !policy.ShouldJoin() { + return false + } + } + + return true +} diff --git a/pkg/sortition/policy_test.go b/pkg/sortition/policy_test.go new file mode 100644 index 0000000000..06b89825e1 --- /dev/null +++ b/pkg/sortition/policy_test.go @@ -0,0 +1,65 @@ +package sortition + +import ( + "testing" + + "github.com/keep-network/keep-core/pkg/internal/testutils" +) + +func TestConjunctionPolicy(t *testing.T) { + var tests = map[string]struct { + policies []JoinPolicy + expectedResult bool + }{ + "empty policy": { + policies: []JoinPolicy{}, + expectedResult: true, + }, + "one positive policy": { + policies: []JoinPolicy{&mockPolicy{true}}, + expectedResult: true, + }, + "one negative policy": { + policies: []JoinPolicy{&mockPolicy{false}}, + expectedResult: false, + }, + "two policies: both negative": { + policies: []JoinPolicy{&mockPolicy{false}, &mockPolicy{false}}, + expectedResult: false, + }, + "two policies: both positive": { + policies: []JoinPolicy{&mockPolicy{true}, &mockPolicy{true}}, + expectedResult: true, + }, + "two policies: positive and negative": { + policies: []JoinPolicy{&mockPolicy{true}, &mockPolicy{false}}, + expectedResult: false, + }, + "two policies: negative and positive": { + policies: []JoinPolicy{&mockPolicy{false}, &mockPolicy{true}}, + expectedResult: false, + }, + } + + for testName, test := range tests { + t.Run(testName, func(t *testing.T) { + policy := ConjunctionPolicy{test.policies} + + actualResult := policy.ShouldJoin() + testutils.AssertBoolsEqual( + t, + "ShouldJoin() result", + test.expectedResult, + actualResult, + ) + }) + } +} + +type mockPolicy struct { + shouldJoin bool +} + +func (mp *mockPolicy) ShouldJoin() bool { + return mp.shouldJoin +} From 0a309af1b71121960592f78f94846bf13e6a54bf Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 23 Sep 2022 12:39:22 +0200 Subject: [PATCH 2/6] Moved all sortition policies to policy.go All sortition pool policies are now aggregated in a single file. --- pkg/sortition/policy.go | 19 +++++++++++++++++++ pkg/sortition/sortition.go | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/pkg/sortition/policy.go b/pkg/sortition/policy.go index fb53b8942e..e0e14dc2e4 100644 --- a/pkg/sortition/policy.go +++ b/pkg/sortition/policy.go @@ -1,5 +1,24 @@ package sortition +// JoinPolicy determines how the client is supposed to join to the sortition +// pool. The policy can encapsulate special conditions that the client want +// to fulfill before joining the sortition pool. +type JoinPolicy interface { + // ShouldJoin indicates whether the joining condition is fulfilled and + // the client should join the pool. + ShouldJoin() bool +} + +// UnconditionalJoinPolicy is a policy that doesn't enforce any conditions +// for joining the sortition pool. +var UnconditionalJoinPolicy = &unconditionalJoinPolicy{} + +type unconditionalJoinPolicy struct{} + +func (ujp *unconditionalJoinPolicy) ShouldJoin() bool { + return true +} + // ConjunctionPolicy is a JoinPolicy implementation requiring all the provided // policies to pass before allowing to join the sortition pool. type ConjunctionPolicy struct { diff --git a/pkg/sortition/sortition.go b/pkg/sortition/sortition.go index e14f9fb0d6..ad6968ec28 100644 --- a/pkg/sortition/sortition.go +++ b/pkg/sortition/sortition.go @@ -14,25 +14,6 @@ const ( var errOperatorUnknown = fmt.Errorf("operator not registered for the staking provider, check Threshold dashboard") -// JoinPolicy determines how the client is supposed to join to the sortition -// pool. The policy can encapsulate special conditions that the client want -// to fulfill before joining the sortition pool. -type JoinPolicy interface { - // ShouldJoin indicates whether the joining condition is fulfilled and - // the client should join the pool. - ShouldJoin() bool -} - -// UnconditionalJoinPolicy is a policy that doesn't enforce any conditions -// for joining the sortition pool. -var UnconditionalJoinPolicy = &unconditionalJoinPolicy{} - -type unconditionalJoinPolicy struct{} - -func (ujp *unconditionalJoinPolicy) ShouldJoin() bool { - return true -} - // MonitorPool periodically checks the status of the operator in the sortition // pool. If the operator is supposed to be in the sortition pool but is not // there yet, the function attempts to add the operator to the pool. If the From 41afa0755dc9afec06cf56b9581347c9a8430bdf Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 23 Sep 2022 13:43:07 +0200 Subject: [PATCH 3/6] Regenerated Go bindings for SortitionPool contract --- .../beacon/gen/abi/BeaconSortitionPool.go | 560 ++++++++- .../beacon/gen/cmd/BeaconSortitionPool.go | 225 ++++ .../gen/contract/BeaconSortitionPool.go | 1096 ++++++++++++++++- .../ecdsa/gen/abi/EcdsaSortitionPool.go | 560 ++++++++- .../ecdsa/gen/cmd/EcdsaSortitionPool.go | 225 ++++ .../ecdsa/gen/contract/EcdsaSortitionPool.go | 1096 ++++++++++++++++- 6 files changed, 3718 insertions(+), 44 deletions(-) diff --git a/pkg/chain/ethereum/beacon/gen/abi/BeaconSortitionPool.go b/pkg/chain/ethereum/beacon/gen/abi/BeaconSortitionPool.go index f9e75ac1d3..6a476eff27 100644 --- a/pkg/chain/ethereum/beacon/gen/abi/BeaconSortitionPool.go +++ b/pkg/chain/ethereum/beacon/gen/abi/BeaconSortitionPool.go @@ -30,7 +30,7 @@ var ( // BeaconSortitionPoolMetaData contains all meta data concerning the BeaconSortitionPool contract. var BeaconSortitionPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_poolWeightDivisor\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"IneligibleForRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"RewardEligibilityRestored\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"canRestoreRewardEligibility\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getAvailableRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"getIDOperator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"}],\"name\":\"getIDOperators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getOperatorID\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getPoolWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ineligibleEarnedRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"insertOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isEligibleForRewards\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorInPool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"isOperatorUpToDate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatorsInPool\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolWeightDivisor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"restoreRewardEligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"rewardsEligibilityRestorableAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"groupSize\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"seed\",\"type\":\"bytes32\"}],\"name\":\"selectGroup\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"operators\",\"type\":\"uint32[]\"},{\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"setRewardIneligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"updateOperatorStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawIneligible\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"withdrawRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_poolWeightDivisor\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"operators\",\"type\":\"address[]\"}],\"name\":\"BetaOperatorsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ChaosnetDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldChaosnetOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newChaosnetOwner\",\"type\":\"address\"}],\"name\":\"ChaosnetOwnerRoleTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"IneligibleForRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"RewardEligibilityRestored\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"operators\",\"type\":\"address[]\"}],\"name\":\"addBetaOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"canRestoreRewardEligibility\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chaosnetOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deactivateChaosnet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getAvailableRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"getIDOperator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"}],\"name\":\"getIDOperators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getOperatorID\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getPoolWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ineligibleEarnedRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"insertOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isBetaOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isChaosnetActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isEligibleForRewards\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorInPool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"isOperatorUpToDate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatorsInPool\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolWeightDivisor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"restoreRewardEligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"rewardsEligibilityRestorableAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"groupSize\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"seed\",\"type\":\"bytes32\"}],\"name\":\"selectGroup\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"operators\",\"type\":\"uint32[]\"},{\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"setRewardIneligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newChaosnetOwner\",\"type\":\"address\"}],\"name\":\"transferChaosnetOwnerRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"updateOperatorStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawIneligible\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"withdrawRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // BeaconSortitionPoolABI is the input ABI used to generate the binding from. @@ -210,6 +210,37 @@ func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) CanRestoreRewardEl return _BeaconSortitionPool.Contract.CanRestoreRewardEligibility(&_BeaconSortitionPool.CallOpts, operator) } +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_BeaconSortitionPool *BeaconSortitionPoolCaller) ChaosnetOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _BeaconSortitionPool.contract.Call(opts, &out, "chaosnetOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_BeaconSortitionPool *BeaconSortitionPoolSession) ChaosnetOwner() (common.Address, error) { + return _BeaconSortitionPool.Contract.ChaosnetOwner(&_BeaconSortitionPool.CallOpts) +} + +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) ChaosnetOwner() (common.Address, error) { + return _BeaconSortitionPool.Contract.ChaosnetOwner(&_BeaconSortitionPool.CallOpts) +} + // GetAvailableRewards is a free data retrieval call binding the contract method 0x873e31fa. // // Solidity: function getAvailableRewards(address operator) view returns(uint96) @@ -396,6 +427,68 @@ func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) IneligibleEarnedRe return _BeaconSortitionPool.Contract.IneligibleEarnedRewards(&_BeaconSortitionPool.CallOpts) } +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolCaller) IsBetaOperator(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _BeaconSortitionPool.contract.Call(opts, &out, "isBetaOperator", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolSession) IsBetaOperator(arg0 common.Address) (bool, error) { + return _BeaconSortitionPool.Contract.IsBetaOperator(&_BeaconSortitionPool.CallOpts, arg0) +} + +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) IsBetaOperator(arg0 common.Address) (bool, error) { + return _BeaconSortitionPool.Contract.IsBetaOperator(&_BeaconSortitionPool.CallOpts, arg0) +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolCaller) IsChaosnetActive(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _BeaconSortitionPool.contract.Call(opts, &out, "isChaosnetActive") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolSession) IsChaosnetActive() (bool, error) { + return _BeaconSortitionPool.Contract.IsChaosnetActive(&_BeaconSortitionPool.CallOpts) +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) IsChaosnetActive() (bool, error) { + return _BeaconSortitionPool.Contract.IsChaosnetActive(&_BeaconSortitionPool.CallOpts) +} + // IsEligibleForRewards is a free data retrieval call binding the contract method 0x660186e6. // // Solidity: function isEligibleForRewards(address operator) view returns(bool) @@ -768,6 +861,48 @@ func (_BeaconSortitionPool *BeaconSortitionPoolCallerSession) TotalWeight() (*bi return _BeaconSortitionPool.Contract.TotalWeight(&_BeaconSortitionPool.CallOpts) } +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactor) AddBetaOperators(opts *bind.TransactOpts, operators []common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.contract.Transact(opts, "addBetaOperators", operators) +} + +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolSession) AddBetaOperators(operators []common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.AddBetaOperators(&_BeaconSortitionPool.TransactOpts, operators) +} + +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactorSession) AddBetaOperators(operators []common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.AddBetaOperators(&_BeaconSortitionPool.TransactOpts, operators) +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactor) DeactivateChaosnet(opts *bind.TransactOpts) (*types.Transaction, error) { + return _BeaconSortitionPool.contract.Transact(opts, "deactivateChaosnet") +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_BeaconSortitionPool *BeaconSortitionPoolSession) DeactivateChaosnet() (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.DeactivateChaosnet(&_BeaconSortitionPool.TransactOpts) +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactorSession) DeactivateChaosnet() (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.DeactivateChaosnet(&_BeaconSortitionPool.TransactOpts) +} + // InsertOperator is a paid mutator transaction binding the contract method 0x241a4188. // // Solidity: function insertOperator(address operator, uint256 authorizedStake) returns() @@ -894,6 +1029,27 @@ func (_BeaconSortitionPool *BeaconSortitionPoolTransactorSession) SetRewardIneli return _BeaconSortitionPool.Contract.SetRewardIneligibility(&_BeaconSortitionPool.TransactOpts, operators, until) } +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactor) TransferChaosnetOwnerRole(opts *bind.TransactOpts, newChaosnetOwner common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.contract.Transact(opts, "transferChaosnetOwnerRole", newChaosnetOwner) +} + +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolSession) TransferChaosnetOwnerRole(newChaosnetOwner common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.TransferChaosnetOwnerRole(&_BeaconSortitionPool.TransactOpts, newChaosnetOwner) +} + +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_BeaconSortitionPool *BeaconSortitionPoolTransactorSession) TransferChaosnetOwnerRole(newChaosnetOwner common.Address) (*types.Transaction, error) { + return _BeaconSortitionPool.Contract.TransferChaosnetOwnerRole(&_BeaconSortitionPool.TransactOpts, newChaosnetOwner) +} + // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() @@ -999,6 +1155,408 @@ func (_BeaconSortitionPool *BeaconSortitionPoolTransactorSession) WithdrawReward return _BeaconSortitionPool.Contract.WithdrawRewards(&_BeaconSortitionPool.TransactOpts, operator, beneficiary) } +// BeaconSortitionPoolBetaOperatorsAddedIterator is returned from FilterBetaOperatorsAdded and is used to iterate over the raw logs and unpacked data for BetaOperatorsAdded events raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolBetaOperatorsAddedIterator struct { + Event *BeaconSortitionPoolBetaOperatorsAdded // 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 ethereum.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 *BeaconSortitionPoolBetaOperatorsAddedIterator) 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(BeaconSortitionPoolBetaOperatorsAdded) + 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(BeaconSortitionPoolBetaOperatorsAdded) + 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 *BeaconSortitionPoolBetaOperatorsAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *BeaconSortitionPoolBetaOperatorsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// BeaconSortitionPoolBetaOperatorsAdded represents a BetaOperatorsAdded event raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolBetaOperatorsAdded struct { + Operators []common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBetaOperatorsAdded is a free log retrieval operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) FilterBetaOperatorsAdded(opts *bind.FilterOpts) (*BeaconSortitionPoolBetaOperatorsAddedIterator, error) { + + logs, sub, err := _BeaconSortitionPool.contract.FilterLogs(opts, "BetaOperatorsAdded") + if err != nil { + return nil, err + } + return &BeaconSortitionPoolBetaOperatorsAddedIterator{contract: _BeaconSortitionPool.contract, event: "BetaOperatorsAdded", logs: logs, sub: sub}, nil +} + +// WatchBetaOperatorsAdded is a free log subscription operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) WatchBetaOperatorsAdded(opts *bind.WatchOpts, sink chan<- *BeaconSortitionPoolBetaOperatorsAdded) (event.Subscription, error) { + + logs, sub, err := _BeaconSortitionPool.contract.WatchLogs(opts, "BetaOperatorsAdded") + 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(BeaconSortitionPoolBetaOperatorsAdded) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "BetaOperatorsAdded", 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 +} + +// ParseBetaOperatorsAdded is a log parse operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) ParseBetaOperatorsAdded(log types.Log) (*BeaconSortitionPoolBetaOperatorsAdded, error) { + event := new(BeaconSortitionPoolBetaOperatorsAdded) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "BetaOperatorsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// BeaconSortitionPoolChaosnetDeactivatedIterator is returned from FilterChaosnetDeactivated and is used to iterate over the raw logs and unpacked data for ChaosnetDeactivated events raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolChaosnetDeactivatedIterator struct { + Event *BeaconSortitionPoolChaosnetDeactivated // 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 ethereum.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 *BeaconSortitionPoolChaosnetDeactivatedIterator) 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(BeaconSortitionPoolChaosnetDeactivated) + 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(BeaconSortitionPoolChaosnetDeactivated) + 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 *BeaconSortitionPoolChaosnetDeactivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *BeaconSortitionPoolChaosnetDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// BeaconSortitionPoolChaosnetDeactivated represents a ChaosnetDeactivated event raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolChaosnetDeactivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChaosnetDeactivated is a free log retrieval operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) FilterChaosnetDeactivated(opts *bind.FilterOpts) (*BeaconSortitionPoolChaosnetDeactivatedIterator, error) { + + logs, sub, err := _BeaconSortitionPool.contract.FilterLogs(opts, "ChaosnetDeactivated") + if err != nil { + return nil, err + } + return &BeaconSortitionPoolChaosnetDeactivatedIterator{contract: _BeaconSortitionPool.contract, event: "ChaosnetDeactivated", logs: logs, sub: sub}, nil +} + +// WatchChaosnetDeactivated is a free log subscription operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) WatchChaosnetDeactivated(opts *bind.WatchOpts, sink chan<- *BeaconSortitionPoolChaosnetDeactivated) (event.Subscription, error) { + + logs, sub, err := _BeaconSortitionPool.contract.WatchLogs(opts, "ChaosnetDeactivated") + 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(BeaconSortitionPoolChaosnetDeactivated) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "ChaosnetDeactivated", 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 +} + +// ParseChaosnetDeactivated is a log parse operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) ParseChaosnetDeactivated(log types.Log) (*BeaconSortitionPoolChaosnetDeactivated, error) { + event := new(BeaconSortitionPoolChaosnetDeactivated) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "ChaosnetDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator is returned from FilterChaosnetOwnerRoleTransferred and is used to iterate over the raw logs and unpacked data for ChaosnetOwnerRoleTransferred events raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator struct { + Event *BeaconSortitionPoolChaosnetOwnerRoleTransferred // 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 ethereum.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 *BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator) 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(BeaconSortitionPoolChaosnetOwnerRoleTransferred) + 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(BeaconSortitionPoolChaosnetOwnerRoleTransferred) + 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 *BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// BeaconSortitionPoolChaosnetOwnerRoleTransferred represents a ChaosnetOwnerRoleTransferred event raised by the BeaconSortitionPool contract. +type BeaconSortitionPoolChaosnetOwnerRoleTransferred struct { + OldChaosnetOwner common.Address + NewChaosnetOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChaosnetOwnerRoleTransferred is a free log retrieval operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) FilterChaosnetOwnerRoleTransferred(opts *bind.FilterOpts) (*BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator, error) { + + logs, sub, err := _BeaconSortitionPool.contract.FilterLogs(opts, "ChaosnetOwnerRoleTransferred") + if err != nil { + return nil, err + } + return &BeaconSortitionPoolChaosnetOwnerRoleTransferredIterator{contract: _BeaconSortitionPool.contract, event: "ChaosnetOwnerRoleTransferred", logs: logs, sub: sub}, nil +} + +// WatchChaosnetOwnerRoleTransferred is a free log subscription operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) WatchChaosnetOwnerRoleTransferred(opts *bind.WatchOpts, sink chan<- *BeaconSortitionPoolChaosnetOwnerRoleTransferred) (event.Subscription, error) { + + logs, sub, err := _BeaconSortitionPool.contract.WatchLogs(opts, "ChaosnetOwnerRoleTransferred") + 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(BeaconSortitionPoolChaosnetOwnerRoleTransferred) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "ChaosnetOwnerRoleTransferred", 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 +} + +// ParseChaosnetOwnerRoleTransferred is a log parse operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_BeaconSortitionPool *BeaconSortitionPoolFilterer) ParseChaosnetOwnerRoleTransferred(log types.Log) (*BeaconSortitionPoolChaosnetOwnerRoleTransferred, error) { + event := new(BeaconSortitionPoolChaosnetOwnerRoleTransferred) + if err := _BeaconSortitionPool.contract.UnpackLog(event, "ChaosnetOwnerRoleTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // BeaconSortitionPoolIneligibleForRewardsIterator is returned from FilterIneligibleForRewards and is used to iterate over the raw logs and unpacked data for IneligibleForRewards events raised by the BeaconSortitionPool contract. type BeaconSortitionPoolIneligibleForRewardsIterator struct { Event *BeaconSortitionPoolIneligibleForRewards // Event containing the contract specifics and raw log diff --git a/pkg/chain/ethereum/beacon/gen/cmd/BeaconSortitionPool.go b/pkg/chain/ethereum/beacon/gen/cmd/BeaconSortitionPool.go index 19c15cb7b8..89ea4eb008 100644 --- a/pkg/chain/ethereum/beacon/gen/cmd/BeaconSortitionPool.go +++ b/pkg/chain/ethereum/beacon/gen/cmd/BeaconSortitionPool.go @@ -51,11 +51,14 @@ func init() { BeaconSortitionPoolCommand.AddCommand( bspCanRestoreRewardEligibilityCommand(), + bspChaosnetOwnerCommand(), bspGetAvailableRewardsCommand(), bspGetIDOperatorCommand(), bspGetOperatorIDCommand(), bspGetPoolWeightCommand(), bspIneligibleEarnedRewardsCommand(), + bspIsBetaOperatorCommand(), + bspIsChaosnetActiveCommand(), bspIsEligibleForRewardsCommand(), bspIsLockedCommand(), bspIsOperatorInPoolCommand(), @@ -67,11 +70,13 @@ func init() { bspRewardTokenCommand(), bspRewardsEligibilityRestorableAtCommand(), bspTotalWeightCommand(), + bspDeactivateChaosnetCommand(), bspInsertOperatorCommand(), bspLockCommand(), bspReceiveApprovalCommand(), bspRenounceOwnershipCommand(), bspRestoreRewardEligibilityCommand(), + bspTransferChaosnetOwnerRoleCommand(), bspTransferOwnershipCommand(), bspUnlockCommand(), bspUpdateOperatorStatusCommand(), @@ -127,6 +132,40 @@ func bspCanRestoreRewardEligibility(c *cobra.Command, args []string) error { return nil } +func bspChaosnetOwnerCommand() *cobra.Command { + c := &cobra.Command{ + Use: "chaosnet-owner", + Short: "Calls the view method chaosnetOwner on the BeaconSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: bspChaosnetOwner, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func bspChaosnetOwner(c *cobra.Command, args []string) error { + contract, err := initializeBeaconSortitionPool(c) + if err != nil { + return err + } + + result, err := contract.ChaosnetOwnerAtBlock( + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + func bspGetAvailableRewardsCommand() *cobra.Command { c := &cobra.Command{ Use: "get-available-rewards [arg_operator]", @@ -333,6 +372,83 @@ func bspIneligibleEarnedRewards(c *cobra.Command, args []string) error { return nil } +func bspIsBetaOperatorCommand() *cobra.Command { + c := &cobra.Command{ + Use: "is-beta-operator [arg0]", + Short: "Calls the view method isBetaOperator on the BeaconSortitionPool contract.", + Args: cmd.ArgCountChecker(1), + RunE: bspIsBetaOperator, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func bspIsBetaOperator(c *cobra.Command, args []string) error { + contract, err := initializeBeaconSortitionPool(c) + if err != nil { + return err + } + + arg0, err := chainutil.AddressFromHex(args[0]) + if err != nil { + return fmt.Errorf( + "couldn't parse parameter arg0, a address, from passed value %v", + args[0], + ) + } + + result, err := contract.IsBetaOperatorAtBlock( + arg0, + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + +func bspIsChaosnetActiveCommand() *cobra.Command { + c := &cobra.Command{ + Use: "is-chaosnet-active", + Short: "Calls the view method isChaosnetActive on the BeaconSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: bspIsChaosnetActive, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func bspIsChaosnetActive(c *cobra.Command, args []string) error { + contract, err := initializeBeaconSortitionPool(c) + if err != nil { + return err + } + + result, err := contract.IsChaosnetActiveAtBlock( + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + func bspIsEligibleForRewardsCommand() *cobra.Command { c := &cobra.Command{ Use: "is-eligible-for-rewards [arg_operator]", @@ -762,6 +878,55 @@ func bspTotalWeight(c *cobra.Command, args []string) error { /// ------------------- Non-const methods ------------------- +func bspDeactivateChaosnetCommand() *cobra.Command { + c := &cobra.Command{ + Use: "deactivate-chaosnet", + Short: "Calls the nonpayable method deactivateChaosnet on the BeaconSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: bspDeactivateChaosnet, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + c.PreRunE = cmd.NonConstArgsChecker + cmd.InitNonConstFlags(c) + + return c +} + +func bspDeactivateChaosnet(c *cobra.Command, args []string) error { + contract, err := initializeBeaconSortitionPool(c) + if err != nil { + return err + } + + var ( + transaction *types.Transaction + ) + + if shouldSubmit, _ := c.Flags().GetBool(cmd.SubmitFlag); shouldSubmit { + // Do a regular submission. Take payable into account. + transaction, err = contract.DeactivateChaosnet() + if err != nil { + return err + } + + cmd.PrintOutput(transaction.Hash()) + } else { + // Do a call. + err = contract.CallDeactivateChaosnet( + cmd.BlockFlagValue.Int, + ) + if err != nil { + return err + } + + cmd.PrintOutput("success") + } + + return nil +} + func bspInsertOperatorCommand() *cobra.Command { c := &cobra.Command{ Use: "insert-operator [arg_operator] [arg_authorizedStake]", @@ -1076,6 +1241,66 @@ func bspRestoreRewardEligibility(c *cobra.Command, args []string) error { return nil } +func bspTransferChaosnetOwnerRoleCommand() *cobra.Command { + c := &cobra.Command{ + Use: "transfer-chaosnet-owner-role [arg_newChaosnetOwner]", + Short: "Calls the nonpayable method transferChaosnetOwnerRole on the BeaconSortitionPool contract.", + Args: cmd.ArgCountChecker(1), + RunE: bspTransferChaosnetOwnerRole, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + c.PreRunE = cmd.NonConstArgsChecker + cmd.InitNonConstFlags(c) + + return c +} + +func bspTransferChaosnetOwnerRole(c *cobra.Command, args []string) error { + contract, err := initializeBeaconSortitionPool(c) + if err != nil { + return err + } + + arg_newChaosnetOwner, err := chainutil.AddressFromHex(args[0]) + if err != nil { + return fmt.Errorf( + "couldn't parse parameter arg_newChaosnetOwner, a address, from passed value %v", + args[0], + ) + } + + var ( + transaction *types.Transaction + ) + + if shouldSubmit, _ := c.Flags().GetBool(cmd.SubmitFlag); shouldSubmit { + // Do a regular submission. Take payable into account. + transaction, err = contract.TransferChaosnetOwnerRole( + arg_newChaosnetOwner, + ) + if err != nil { + return err + } + + cmd.PrintOutput(transaction.Hash()) + } else { + // Do a call. + err = contract.CallTransferChaosnetOwnerRole( + arg_newChaosnetOwner, + cmd.BlockFlagValue.Int, + ) + if err != nil { + return err + } + + cmd.PrintOutput("success") + } + + return nil +} + func bspTransferOwnershipCommand() *cobra.Command { c := &cobra.Command{ Use: "transfer-ownership [arg_newOwner]", diff --git a/pkg/chain/ethereum/beacon/gen/contract/BeaconSortitionPool.go b/pkg/chain/ethereum/beacon/gen/contract/BeaconSortitionPool.go index dc1d281366..bb851778ba 100644 --- a/pkg/chain/ethereum/beacon/gen/contract/BeaconSortitionPool.go +++ b/pkg/chain/ethereum/beacon/gen/contract/BeaconSortitionPool.go @@ -104,6 +104,268 @@ func NewBeaconSortitionPool( // ----- Non-const Methods ------ +// Transaction submission. +func (bsp *BeaconSortitionPool) AddBetaOperators( + arg_operators []common.Address, + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + bspLogger.Debug( + "submitting transaction addBetaOperators", + " params: ", + fmt.Sprint( + arg_operators, + ), + ) + + bsp.transactionMutex.Lock() + defer bsp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *bsp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := bsp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := bsp.contract.AddBetaOperators( + transactorOptions, + arg_operators, + ) + if err != nil { + return transaction, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "addBetaOperators", + arg_operators, + ) + } + + bspLogger.Infof( + "submitted transaction addBetaOperators with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go bsp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := bsp.contract.AddBetaOperators( + newTransactorOptions, + arg_operators, + ) + if err != nil { + return nil, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "addBetaOperators", + arg_operators, + ) + } + + bspLogger.Infof( + "submitted transaction addBetaOperators with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + bsp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (bsp *BeaconSortitionPool) CallAddBetaOperators( + arg_operators []common.Address, + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + bsp.transactorOptions.From, + blockNumber, nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "addBetaOperators", + &result, + arg_operators, + ) + + return err +} + +func (bsp *BeaconSortitionPool) AddBetaOperatorsGasEstimate( + arg_operators []common.Address, +) (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + bsp.callerOptions.From, + bsp.contractAddress, + "addBetaOperators", + bsp.contractABI, + bsp.transactor, + arg_operators, + ) + + return result, err +} + +// Transaction submission. +func (bsp *BeaconSortitionPool) DeactivateChaosnet( + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + bspLogger.Debug( + "submitting transaction deactivateChaosnet", + ) + + bsp.transactionMutex.Lock() + defer bsp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *bsp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := bsp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := bsp.contract.DeactivateChaosnet( + transactorOptions, + ) + if err != nil { + return transaction, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "deactivateChaosnet", + ) + } + + bspLogger.Infof( + "submitted transaction deactivateChaosnet with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go bsp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := bsp.contract.DeactivateChaosnet( + newTransactorOptions, + ) + if err != nil { + return nil, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "deactivateChaosnet", + ) + } + + bspLogger.Infof( + "submitted transaction deactivateChaosnet with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + bsp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (bsp *BeaconSortitionPool) CallDeactivateChaosnet( + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + bsp.transactorOptions.From, + blockNumber, nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "deactivateChaosnet", + &result, + ) + + return err +} + +func (bsp *BeaconSortitionPool) DeactivateChaosnetGasEstimate() (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + bsp.callerOptions.From, + bsp.contractAddress, + "deactivateChaosnet", + bsp.contractABI, + bsp.transactor, + ) + + return result, err +} + // Transaction submission. func (bsp *BeaconSortitionPool) InsertOperator( arg_operator common.Address, @@ -955,16 +1217,16 @@ func (bsp *BeaconSortitionPool) SetRewardIneligibilityGasEstimate( } // Transaction submission. -func (bsp *BeaconSortitionPool) TransferOwnership( - arg_newOwner common.Address, +func (bsp *BeaconSortitionPool) TransferChaosnetOwnerRole( + arg_newChaosnetOwner common.Address, transactionOptions ...chainutil.TransactionOptions, ) (*types.Transaction, error) { bspLogger.Debug( - "submitting transaction transferOwnership", + "submitting transaction transferChaosnetOwnerRole", " params: ", fmt.Sprint( - arg_newOwner, + arg_newChaosnetOwner, ), ) @@ -990,22 +1252,22 @@ func (bsp *BeaconSortitionPool) TransferOwnership( transactorOptions.Nonce = new(big.Int).SetUint64(nonce) - transaction, err := bsp.contract.TransferOwnership( + transaction, err := bsp.contract.TransferChaosnetOwnerRole( transactorOptions, - arg_newOwner, + arg_newChaosnetOwner, ) if err != nil { return transaction, bsp.errorResolver.ResolveError( err, bsp.transactorOptions.From, nil, - "transferOwnership", - arg_newOwner, + "transferChaosnetOwnerRole", + arg_newChaosnetOwner, ) } bspLogger.Infof( - "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + "submitted transaction transferChaosnetOwnerRole with id: [%s] and nonce [%v]", transaction.Hash(), transaction.Nonce(), ) @@ -1024,22 +1286,22 @@ func (bsp *BeaconSortitionPool) TransferOwnership( newTransactorOptions.GasLimit = transactorOptions.GasLimit } - transaction, err := bsp.contract.TransferOwnership( + transaction, err := bsp.contract.TransferChaosnetOwnerRole( newTransactorOptions, - arg_newOwner, + arg_newChaosnetOwner, ) if err != nil { return nil, bsp.errorResolver.ResolveError( err, bsp.transactorOptions.From, nil, - "transferOwnership", - arg_newOwner, + "transferChaosnetOwnerRole", + arg_newChaosnetOwner, ) } bspLogger.Infof( - "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + "submitted transaction transferChaosnetOwnerRole with id: [%s] and nonce [%v]", transaction.Hash(), transaction.Nonce(), ) @@ -1054,8 +1316,8 @@ func (bsp *BeaconSortitionPool) TransferOwnership( } // Non-mutating call, not a transaction submission. -func (bsp *BeaconSortitionPool) CallTransferOwnership( - arg_newOwner common.Address, +func (bsp *BeaconSortitionPool) CallTransferChaosnetOwnerRole( + arg_newChaosnetOwner common.Address, blockNumber *big.Int, ) error { var result interface{} = nil @@ -1067,23 +1329,161 @@ func (bsp *BeaconSortitionPool) CallTransferOwnership( bsp.caller, bsp.errorResolver, bsp.contractAddress, - "transferOwnership", + "transferChaosnetOwnerRole", &result, - arg_newOwner, + arg_newChaosnetOwner, ) return err } -func (bsp *BeaconSortitionPool) TransferOwnershipGasEstimate( - arg_newOwner common.Address, +func (bsp *BeaconSortitionPool) TransferChaosnetOwnerRoleGasEstimate( + arg_newChaosnetOwner common.Address, ) (uint64, error) { var result uint64 result, err := chainutil.EstimateGas( bsp.callerOptions.From, bsp.contractAddress, - "transferOwnership", + "transferChaosnetOwnerRole", + bsp.contractABI, + bsp.transactor, + arg_newChaosnetOwner, + ) + + return result, err +} + +// Transaction submission. +func (bsp *BeaconSortitionPool) TransferOwnership( + arg_newOwner common.Address, + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + bspLogger.Debug( + "submitting transaction transferOwnership", + " params: ", + fmt.Sprint( + arg_newOwner, + ), + ) + + bsp.transactionMutex.Lock() + defer bsp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *bsp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := bsp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := bsp.contract.TransferOwnership( + transactorOptions, + arg_newOwner, + ) + if err != nil { + return transaction, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "transferOwnership", + arg_newOwner, + ) + } + + bspLogger.Infof( + "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go bsp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := bsp.contract.TransferOwnership( + newTransactorOptions, + arg_newOwner, + ) + if err != nil { + return nil, bsp.errorResolver.ResolveError( + err, + bsp.transactorOptions.From, + nil, + "transferOwnership", + arg_newOwner, + ) + } + + bspLogger.Infof( + "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + bsp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (bsp *BeaconSortitionPool) CallTransferOwnership( + arg_newOwner common.Address, + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + bsp.transactorOptions.From, + blockNumber, nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "transferOwnership", + &result, + arg_newOwner, + ) + + return err +} + +func (bsp *BeaconSortitionPool) TransferOwnershipGasEstimate( + arg_newOwner common.Address, +) (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + bsp.callerOptions.From, + bsp.contractAddress, + "transferOwnership", bsp.contractABI, bsp.transactor, arg_newOwner, @@ -1695,6 +2095,43 @@ func (bsp *BeaconSortitionPool) CanRestoreRewardEligibilityAtBlock( return result, err } +func (bsp *BeaconSortitionPool) ChaosnetOwner() (common.Address, error) { + result, err := bsp.contract.ChaosnetOwner( + bsp.callerOptions, + ) + + if err != nil { + return result, bsp.errorResolver.ResolveError( + err, + bsp.callerOptions.From, + nil, + "chaosnetOwner", + ) + } + + return result, err +} + +func (bsp *BeaconSortitionPool) ChaosnetOwnerAtBlock( + blockNumber *big.Int, +) (common.Address, error) { + var result common.Address + + err := chainutil.CallAtBlock( + bsp.callerOptions.From, + blockNumber, + nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "chaosnetOwner", + &result, + ) + + return result, err +} + func (bsp *BeaconSortitionPool) GetAvailableRewards( arg_operator common.Address, ) (*big.Int, error) { @@ -1947,6 +2384,86 @@ func (bsp *BeaconSortitionPool) IneligibleEarnedRewardsAtBlock( return result, err } +func (bsp *BeaconSortitionPool) IsBetaOperator( + arg0 common.Address, +) (bool, error) { + result, err := bsp.contract.IsBetaOperator( + bsp.callerOptions, + arg0, + ) + + if err != nil { + return result, bsp.errorResolver.ResolveError( + err, + bsp.callerOptions.From, + nil, + "isBetaOperator", + arg0, + ) + } + + return result, err +} + +func (bsp *BeaconSortitionPool) IsBetaOperatorAtBlock( + arg0 common.Address, + blockNumber *big.Int, +) (bool, error) { + var result bool + + err := chainutil.CallAtBlock( + bsp.callerOptions.From, + blockNumber, + nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "isBetaOperator", + &result, + arg0, + ) + + return result, err +} + +func (bsp *BeaconSortitionPool) IsChaosnetActive() (bool, error) { + result, err := bsp.contract.IsChaosnetActive( + bsp.callerOptions, + ) + + if err != nil { + return result, bsp.errorResolver.ResolveError( + err, + bsp.callerOptions.From, + nil, + "isChaosnetActive", + ) + } + + return result, err +} + +func (bsp *BeaconSortitionPool) IsChaosnetActiveAtBlock( + blockNumber *big.Int, +) (bool, error) { + var result bool + + err := chainutil.CallAtBlock( + bsp.callerOptions.From, + blockNumber, + nil, + bsp.contractABI, + bsp.caller, + bsp.errorResolver, + bsp.contractAddress, + "isChaosnetActive", + &result, + ) + + return result, err +} + func (bsp *BeaconSortitionPool) IsEligibleForRewards( arg_operator common.Address, ) (bool, error) { @@ -2439,6 +2956,543 @@ func (bsp *BeaconSortitionPool) TotalWeightAtBlock( // ------ Events ------- +func (bsp *BeaconSortitionPool) BetaOperatorsAddedEvent( + opts *ethereum.SubscribeOpts, +) *BspBetaOperatorsAddedSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &BspBetaOperatorsAddedSubscription{ + bsp, + opts, + } +} + +type BspBetaOperatorsAddedSubscription struct { + contract *BeaconSortitionPool + opts *ethereum.SubscribeOpts +} + +type beaconSortitionPoolBetaOperatorsAddedFunc func( + Operators []common.Address, + blockNumber uint64, +) + +func (boas *BspBetaOperatorsAddedSubscription) OnEvent( + handler beaconSortitionPoolBetaOperatorsAddedFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.BeaconSortitionPoolBetaOperatorsAdded) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.Operators, + event.Raw.BlockNumber, + ) + } + } + }() + + sub := boas.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (boas *BspBetaOperatorsAddedSubscription) Pipe( + sink chan *abi.BeaconSortitionPoolBetaOperatorsAdded, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(boas.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := boas.contract.blockCounter.CurrentBlock() + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - boas.opts.PastBlocks + + bspLogger.Infof( + "subscription monitoring fetching past BetaOperatorsAdded events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := boas.contract.PastBetaOperatorsAddedEvents( + fromBlock, + nil, + ) + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + bspLogger.Infof( + "subscription monitoring fetched [%v] past BetaOperatorsAdded events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := boas.contract.watchBetaOperatorsAdded( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (bsp *BeaconSortitionPool) watchBetaOperatorsAdded( + sink chan *abi.BeaconSortitionPoolBetaOperatorsAdded, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return bsp.contract.WatchBetaOperatorsAdded( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + bspLogger.Errorf( + "subscription to event BetaOperatorsAdded had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + bspLogger.Errorf( + "subscription to event BetaOperatorsAdded failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (bsp *BeaconSortitionPool) PastBetaOperatorsAddedEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.BeaconSortitionPoolBetaOperatorsAdded, error) { + iterator, err := bsp.contract.FilterBetaOperatorsAdded( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past BetaOperatorsAdded events: [%v]", + err, + ) + } + + events := make([]*abi.BeaconSortitionPoolBetaOperatorsAdded, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + +func (bsp *BeaconSortitionPool) ChaosnetDeactivatedEvent( + opts *ethereum.SubscribeOpts, +) *BspChaosnetDeactivatedSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &BspChaosnetDeactivatedSubscription{ + bsp, + opts, + } +} + +type BspChaosnetDeactivatedSubscription struct { + contract *BeaconSortitionPool + opts *ethereum.SubscribeOpts +} + +type beaconSortitionPoolChaosnetDeactivatedFunc func( + blockNumber uint64, +) + +func (cds *BspChaosnetDeactivatedSubscription) OnEvent( + handler beaconSortitionPoolChaosnetDeactivatedFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.BeaconSortitionPoolChaosnetDeactivated) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.Raw.BlockNumber, + ) + } + } + }() + + sub := cds.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (cds *BspChaosnetDeactivatedSubscription) Pipe( + sink chan *abi.BeaconSortitionPoolChaosnetDeactivated, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(cds.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := cds.contract.blockCounter.CurrentBlock() + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - cds.opts.PastBlocks + + bspLogger.Infof( + "subscription monitoring fetching past ChaosnetDeactivated events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := cds.contract.PastChaosnetDeactivatedEvents( + fromBlock, + nil, + ) + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + bspLogger.Infof( + "subscription monitoring fetched [%v] past ChaosnetDeactivated events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := cds.contract.watchChaosnetDeactivated( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (bsp *BeaconSortitionPool) watchChaosnetDeactivated( + sink chan *abi.BeaconSortitionPoolChaosnetDeactivated, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return bsp.contract.WatchChaosnetDeactivated( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + bspLogger.Errorf( + "subscription to event ChaosnetDeactivated had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + bspLogger.Errorf( + "subscription to event ChaosnetDeactivated failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (bsp *BeaconSortitionPool) PastChaosnetDeactivatedEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.BeaconSortitionPoolChaosnetDeactivated, error) { + iterator, err := bsp.contract.FilterChaosnetDeactivated( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past ChaosnetDeactivated events: [%v]", + err, + ) + } + + events := make([]*abi.BeaconSortitionPoolChaosnetDeactivated, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + +func (bsp *BeaconSortitionPool) ChaosnetOwnerRoleTransferredEvent( + opts *ethereum.SubscribeOpts, +) *BspChaosnetOwnerRoleTransferredSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &BspChaosnetOwnerRoleTransferredSubscription{ + bsp, + opts, + } +} + +type BspChaosnetOwnerRoleTransferredSubscription struct { + contract *BeaconSortitionPool + opts *ethereum.SubscribeOpts +} + +type beaconSortitionPoolChaosnetOwnerRoleTransferredFunc func( + OldChaosnetOwner common.Address, + NewChaosnetOwner common.Address, + blockNumber uint64, +) + +func (corts *BspChaosnetOwnerRoleTransferredSubscription) OnEvent( + handler beaconSortitionPoolChaosnetOwnerRoleTransferredFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.BeaconSortitionPoolChaosnetOwnerRoleTransferred) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.OldChaosnetOwner, + event.NewChaosnetOwner, + event.Raw.BlockNumber, + ) + } + } + }() + + sub := corts.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (corts *BspChaosnetOwnerRoleTransferredSubscription) Pipe( + sink chan *abi.BeaconSortitionPoolChaosnetOwnerRoleTransferred, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(corts.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := corts.contract.blockCounter.CurrentBlock() + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - corts.opts.PastBlocks + + bspLogger.Infof( + "subscription monitoring fetching past ChaosnetOwnerRoleTransferred events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := corts.contract.PastChaosnetOwnerRoleTransferredEvents( + fromBlock, + nil, + ) + if err != nil { + bspLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + bspLogger.Infof( + "subscription monitoring fetched [%v] past ChaosnetOwnerRoleTransferred events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := corts.contract.watchChaosnetOwnerRoleTransferred( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (bsp *BeaconSortitionPool) watchChaosnetOwnerRoleTransferred( + sink chan *abi.BeaconSortitionPoolChaosnetOwnerRoleTransferred, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return bsp.contract.WatchChaosnetOwnerRoleTransferred( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + bspLogger.Errorf( + "subscription to event ChaosnetOwnerRoleTransferred had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + bspLogger.Errorf( + "subscription to event ChaosnetOwnerRoleTransferred failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (bsp *BeaconSortitionPool) PastChaosnetOwnerRoleTransferredEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.BeaconSortitionPoolChaosnetOwnerRoleTransferred, error) { + iterator, err := bsp.contract.FilterChaosnetOwnerRoleTransferred( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past ChaosnetOwnerRoleTransferred events: [%v]", + err, + ) + } + + events := make([]*abi.BeaconSortitionPoolChaosnetOwnerRoleTransferred, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + func (bsp *BeaconSortitionPool) IneligibleForRewardsEvent( opts *ethereum.SubscribeOpts, ) *BspIneligibleForRewardsSubscription { diff --git a/pkg/chain/ethereum/ecdsa/gen/abi/EcdsaSortitionPool.go b/pkg/chain/ethereum/ecdsa/gen/abi/EcdsaSortitionPool.go index 117c519dd1..48747b2f3a 100644 --- a/pkg/chain/ethereum/ecdsa/gen/abi/EcdsaSortitionPool.go +++ b/pkg/chain/ethereum/ecdsa/gen/abi/EcdsaSortitionPool.go @@ -30,7 +30,7 @@ var ( // EcdsaSortitionPoolMetaData contains all meta data concerning the EcdsaSortitionPool contract. var EcdsaSortitionPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_poolWeightDivisor\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"IneligibleForRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"RewardEligibilityRestored\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"canRestoreRewardEligibility\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getAvailableRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"getIDOperator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"}],\"name\":\"getIDOperators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getOperatorID\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getPoolWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ineligibleEarnedRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"insertOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isEligibleForRewards\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorInPool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"isOperatorUpToDate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatorsInPool\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolWeightDivisor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"restoreRewardEligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"rewardsEligibilityRestorableAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"groupSize\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"seed\",\"type\":\"bytes32\"}],\"name\":\"selectGroup\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"operators\",\"type\":\"uint32[]\"},{\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"setRewardIneligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"updateOperatorStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawIneligible\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"withdrawRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_poolWeightDivisor\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"operators\",\"type\":\"address[]\"}],\"name\":\"BetaOperatorsAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[],\"name\":\"ChaosnetDeactivated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"oldChaosnetOwner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newChaosnetOwner\",\"type\":\"address\"}],\"name\":\"ChaosnetOwnerRoleTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"IneligibleForRewards\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"RewardEligibilityRestored\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"operators\",\"type\":\"address[]\"}],\"name\":\"addBetaOperators\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"canRestoreRewardEligibility\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"chaosnetOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"deactivateChaosnet\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getAvailableRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"id\",\"type\":\"uint32\"}],\"name\":\"getIDOperator\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"ids\",\"type\":\"uint32[]\"}],\"name\":\"getIDOperators\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getOperatorID\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"getPoolWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"ineligibleEarnedRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"insertOperator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"isBetaOperator\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isChaosnetActive\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isEligibleForRewards\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isLocked\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorInPool\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"isOperatorRegistered\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"isOperatorUpToDate\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatorsInPool\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"poolWeightDivisor\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"receiveApproval\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"restoreRewardEligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contractIERC20WithPermit\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"}],\"name\":\"rewardsEligibilityRestorableAt\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"groupSize\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"seed\",\"type\":\"bytes32\"}],\"name\":\"selectGroup\",\"outputs\":[{\"internalType\":\"uint32[]\",\"name\":\"\",\"type\":\"uint32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"operators\",\"type\":\"uint32[]\"},{\"internalType\":\"uint256\",\"name\":\"until\",\"type\":\"uint256\"}],\"name\":\"setRewardIneligibility\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newChaosnetOwner\",\"type\":\"address\"}],\"name\":\"transferChaosnetOwnerRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unlock\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"authorizedStake\",\"type\":\"uint256\"}],\"name\":\"updateOperatorStatus\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawIneligible\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"operator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"beneficiary\",\"type\":\"address\"}],\"name\":\"withdrawRewards\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // EcdsaSortitionPoolABI is the input ABI used to generate the binding from. @@ -210,6 +210,37 @@ func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) CanRestoreRewardElig return _EcdsaSortitionPool.Contract.CanRestoreRewardEligibility(&_EcdsaSortitionPool.CallOpts, operator) } +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCaller) ChaosnetOwner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _EcdsaSortitionPool.contract.Call(opts, &out, "chaosnetOwner") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) ChaosnetOwner() (common.Address, error) { + return _EcdsaSortitionPool.Contract.ChaosnetOwner(&_EcdsaSortitionPool.CallOpts) +} + +// ChaosnetOwner is a free data retrieval call binding the contract method 0x7c2cf6cd. +// +// Solidity: function chaosnetOwner() view returns(address) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) ChaosnetOwner() (common.Address, error) { + return _EcdsaSortitionPool.Contract.ChaosnetOwner(&_EcdsaSortitionPool.CallOpts) +} + // GetAvailableRewards is a free data retrieval call binding the contract method 0x873e31fa. // // Solidity: function getAvailableRewards(address operator) view returns(uint96) @@ -396,6 +427,68 @@ func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) IneligibleEarnedRewa return _EcdsaSortitionPool.Contract.IneligibleEarnedRewards(&_EcdsaSortitionPool.CallOpts) } +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCaller) IsBetaOperator(opts *bind.CallOpts, arg0 common.Address) (bool, error) { + var out []interface{} + err := _EcdsaSortitionPool.contract.Call(opts, &out, "isBetaOperator", arg0) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) IsBetaOperator(arg0 common.Address) (bool, error) { + return _EcdsaSortitionPool.Contract.IsBetaOperator(&_EcdsaSortitionPool.CallOpts, arg0) +} + +// IsBetaOperator is a free data retrieval call binding the contract method 0x398ece9c. +// +// Solidity: function isBetaOperator(address ) view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) IsBetaOperator(arg0 common.Address) (bool, error) { + return _EcdsaSortitionPool.Contract.IsBetaOperator(&_EcdsaSortitionPool.CallOpts, arg0) +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCaller) IsChaosnetActive(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _EcdsaSortitionPool.contract.Call(opts, &out, "isChaosnetActive") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) IsChaosnetActive() (bool, error) { + return _EcdsaSortitionPool.Contract.IsChaosnetActive(&_EcdsaSortitionPool.CallOpts) +} + +// IsChaosnetActive is a free data retrieval call binding the contract method 0xb0f3828e. +// +// Solidity: function isChaosnetActive() view returns(bool) +func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) IsChaosnetActive() (bool, error) { + return _EcdsaSortitionPool.Contract.IsChaosnetActive(&_EcdsaSortitionPool.CallOpts) +} + // IsEligibleForRewards is a free data retrieval call binding the contract method 0x660186e6. // // Solidity: function isEligibleForRewards(address operator) view returns(bool) @@ -768,6 +861,48 @@ func (_EcdsaSortitionPool *EcdsaSortitionPoolCallerSession) TotalWeight() (*big. return _EcdsaSortitionPool.Contract.TotalWeight(&_EcdsaSortitionPool.CallOpts) } +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactor) AddBetaOperators(opts *bind.TransactOpts, operators []common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.contract.Transact(opts, "addBetaOperators", operators) +} + +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) AddBetaOperators(operators []common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.AddBetaOperators(&_EcdsaSortitionPool.TransactOpts, operators) +} + +// AddBetaOperators is a paid mutator transaction binding the contract method 0x3e723fc9. +// +// Solidity: function addBetaOperators(address[] operators) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactorSession) AddBetaOperators(operators []common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.AddBetaOperators(&_EcdsaSortitionPool.TransactOpts, operators) +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactor) DeactivateChaosnet(opts *bind.TransactOpts) (*types.Transaction, error) { + return _EcdsaSortitionPool.contract.Transact(opts, "deactivateChaosnet") +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) DeactivateChaosnet() (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.DeactivateChaosnet(&_EcdsaSortitionPool.TransactOpts) +} + +// DeactivateChaosnet is a paid mutator transaction binding the contract method 0xf23baf4a. +// +// Solidity: function deactivateChaosnet() returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactorSession) DeactivateChaosnet() (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.DeactivateChaosnet(&_EcdsaSortitionPool.TransactOpts) +} + // InsertOperator is a paid mutator transaction binding the contract method 0x241a4188. // // Solidity: function insertOperator(address operator, uint256 authorizedStake) returns() @@ -894,6 +1029,27 @@ func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactorSession) SetRewardIneligi return _EcdsaSortitionPool.Contract.SetRewardIneligibility(&_EcdsaSortitionPool.TransactOpts, operators, until) } +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactor) TransferChaosnetOwnerRole(opts *bind.TransactOpts, newChaosnetOwner common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.contract.Transact(opts, "transferChaosnetOwnerRole", newChaosnetOwner) +} + +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolSession) TransferChaosnetOwnerRole(newChaosnetOwner common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.TransferChaosnetOwnerRole(&_EcdsaSortitionPool.TransactOpts, newChaosnetOwner) +} + +// TransferChaosnetOwnerRole is a paid mutator transaction binding the contract method 0xc545b3a9. +// +// Solidity: function transferChaosnetOwnerRole(address newChaosnetOwner) returns() +func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactorSession) TransferChaosnetOwnerRole(newChaosnetOwner common.Address) (*types.Transaction, error) { + return _EcdsaSortitionPool.Contract.TransferChaosnetOwnerRole(&_EcdsaSortitionPool.TransactOpts, newChaosnetOwner) +} + // TransferOwnership is a paid mutator transaction binding the contract method 0xf2fde38b. // // Solidity: function transferOwnership(address newOwner) returns() @@ -999,6 +1155,408 @@ func (_EcdsaSortitionPool *EcdsaSortitionPoolTransactorSession) WithdrawRewards( return _EcdsaSortitionPool.Contract.WithdrawRewards(&_EcdsaSortitionPool.TransactOpts, operator, beneficiary) } +// EcdsaSortitionPoolBetaOperatorsAddedIterator is returned from FilterBetaOperatorsAdded and is used to iterate over the raw logs and unpacked data for BetaOperatorsAdded events raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolBetaOperatorsAddedIterator struct { + Event *EcdsaSortitionPoolBetaOperatorsAdded // 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 ethereum.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 *EcdsaSortitionPoolBetaOperatorsAddedIterator) 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(EcdsaSortitionPoolBetaOperatorsAdded) + 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(EcdsaSortitionPoolBetaOperatorsAdded) + 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 *EcdsaSortitionPoolBetaOperatorsAddedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EcdsaSortitionPoolBetaOperatorsAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EcdsaSortitionPoolBetaOperatorsAdded represents a BetaOperatorsAdded event raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolBetaOperatorsAdded struct { + Operators []common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBetaOperatorsAdded is a free log retrieval operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) FilterBetaOperatorsAdded(opts *bind.FilterOpts) (*EcdsaSortitionPoolBetaOperatorsAddedIterator, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.FilterLogs(opts, "BetaOperatorsAdded") + if err != nil { + return nil, err + } + return &EcdsaSortitionPoolBetaOperatorsAddedIterator{contract: _EcdsaSortitionPool.contract, event: "BetaOperatorsAdded", logs: logs, sub: sub}, nil +} + +// WatchBetaOperatorsAdded is a free log subscription operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) WatchBetaOperatorsAdded(opts *bind.WatchOpts, sink chan<- *EcdsaSortitionPoolBetaOperatorsAdded) (event.Subscription, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.WatchLogs(opts, "BetaOperatorsAdded") + 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(EcdsaSortitionPoolBetaOperatorsAdded) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "BetaOperatorsAdded", 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 +} + +// ParseBetaOperatorsAdded is a log parse operation binding the contract event 0x79b60dc9f29a0514f5ce9bf1e89b7add7a22440cde3b203c03a842e3b534071b. +// +// Solidity: event BetaOperatorsAdded(address[] operators) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) ParseBetaOperatorsAdded(log types.Log) (*EcdsaSortitionPoolBetaOperatorsAdded, error) { + event := new(EcdsaSortitionPoolBetaOperatorsAdded) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "BetaOperatorsAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EcdsaSortitionPoolChaosnetDeactivatedIterator is returned from FilterChaosnetDeactivated and is used to iterate over the raw logs and unpacked data for ChaosnetDeactivated events raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolChaosnetDeactivatedIterator struct { + Event *EcdsaSortitionPoolChaosnetDeactivated // 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 ethereum.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 *EcdsaSortitionPoolChaosnetDeactivatedIterator) 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(EcdsaSortitionPoolChaosnetDeactivated) + 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(EcdsaSortitionPoolChaosnetDeactivated) + 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 *EcdsaSortitionPoolChaosnetDeactivatedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EcdsaSortitionPoolChaosnetDeactivatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EcdsaSortitionPoolChaosnetDeactivated represents a ChaosnetDeactivated event raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolChaosnetDeactivated struct { + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChaosnetDeactivated is a free log retrieval operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) FilterChaosnetDeactivated(opts *bind.FilterOpts) (*EcdsaSortitionPoolChaosnetDeactivatedIterator, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.FilterLogs(opts, "ChaosnetDeactivated") + if err != nil { + return nil, err + } + return &EcdsaSortitionPoolChaosnetDeactivatedIterator{contract: _EcdsaSortitionPool.contract, event: "ChaosnetDeactivated", logs: logs, sub: sub}, nil +} + +// WatchChaosnetDeactivated is a free log subscription operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) WatchChaosnetDeactivated(opts *bind.WatchOpts, sink chan<- *EcdsaSortitionPoolChaosnetDeactivated) (event.Subscription, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.WatchLogs(opts, "ChaosnetDeactivated") + 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(EcdsaSortitionPoolChaosnetDeactivated) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "ChaosnetDeactivated", 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 +} + +// ParseChaosnetDeactivated is a log parse operation binding the contract event 0xbea11dc6cfde2788be7e8a6ceef5c8d181bb1c628ba6d71675fca0e754367c74. +// +// Solidity: event ChaosnetDeactivated() +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) ParseChaosnetDeactivated(log types.Log) (*EcdsaSortitionPoolChaosnetDeactivated, error) { + event := new(EcdsaSortitionPoolChaosnetDeactivated) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "ChaosnetDeactivated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator is returned from FilterChaosnetOwnerRoleTransferred and is used to iterate over the raw logs and unpacked data for ChaosnetOwnerRoleTransferred events raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator struct { + Event *EcdsaSortitionPoolChaosnetOwnerRoleTransferred // 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 ethereum.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 *EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator) 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(EcdsaSortitionPoolChaosnetOwnerRoleTransferred) + 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(EcdsaSortitionPoolChaosnetOwnerRoleTransferred) + 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 *EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EcdsaSortitionPoolChaosnetOwnerRoleTransferred represents a ChaosnetOwnerRoleTransferred event raised by the EcdsaSortitionPool contract. +type EcdsaSortitionPoolChaosnetOwnerRoleTransferred struct { + OldChaosnetOwner common.Address + NewChaosnetOwner common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterChaosnetOwnerRoleTransferred is a free log retrieval operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) FilterChaosnetOwnerRoleTransferred(opts *bind.FilterOpts) (*EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.FilterLogs(opts, "ChaosnetOwnerRoleTransferred") + if err != nil { + return nil, err + } + return &EcdsaSortitionPoolChaosnetOwnerRoleTransferredIterator{contract: _EcdsaSortitionPool.contract, event: "ChaosnetOwnerRoleTransferred", logs: logs, sub: sub}, nil +} + +// WatchChaosnetOwnerRoleTransferred is a free log subscription operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) WatchChaosnetOwnerRoleTransferred(opts *bind.WatchOpts, sink chan<- *EcdsaSortitionPoolChaosnetOwnerRoleTransferred) (event.Subscription, error) { + + logs, sub, err := _EcdsaSortitionPool.contract.WatchLogs(opts, "ChaosnetOwnerRoleTransferred") + 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(EcdsaSortitionPoolChaosnetOwnerRoleTransferred) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "ChaosnetOwnerRoleTransferred", 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 +} + +// ParseChaosnetOwnerRoleTransferred is a log parse operation binding the contract event 0xf7d2871c195d5dcbeca7c9bfb4f7ae4149d0915a5d3d03c8c2286c9a24e932be. +// +// Solidity: event ChaosnetOwnerRoleTransferred(address oldChaosnetOwner, address newChaosnetOwner) +func (_EcdsaSortitionPool *EcdsaSortitionPoolFilterer) ParseChaosnetOwnerRoleTransferred(log types.Log) (*EcdsaSortitionPoolChaosnetOwnerRoleTransferred, error) { + event := new(EcdsaSortitionPoolChaosnetOwnerRoleTransferred) + if err := _EcdsaSortitionPool.contract.UnpackLog(event, "ChaosnetOwnerRoleTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + // EcdsaSortitionPoolIneligibleForRewardsIterator is returned from FilterIneligibleForRewards and is used to iterate over the raw logs and unpacked data for IneligibleForRewards events raised by the EcdsaSortitionPool contract. type EcdsaSortitionPoolIneligibleForRewardsIterator struct { Event *EcdsaSortitionPoolIneligibleForRewards // Event containing the contract specifics and raw log diff --git a/pkg/chain/ethereum/ecdsa/gen/cmd/EcdsaSortitionPool.go b/pkg/chain/ethereum/ecdsa/gen/cmd/EcdsaSortitionPool.go index a50f2e31f4..5b741c77c1 100644 --- a/pkg/chain/ethereum/ecdsa/gen/cmd/EcdsaSortitionPool.go +++ b/pkg/chain/ethereum/ecdsa/gen/cmd/EcdsaSortitionPool.go @@ -51,11 +51,14 @@ func init() { EcdsaSortitionPoolCommand.AddCommand( espCanRestoreRewardEligibilityCommand(), + espChaosnetOwnerCommand(), espGetAvailableRewardsCommand(), espGetIDOperatorCommand(), espGetOperatorIDCommand(), espGetPoolWeightCommand(), espIneligibleEarnedRewardsCommand(), + espIsBetaOperatorCommand(), + espIsChaosnetActiveCommand(), espIsEligibleForRewardsCommand(), espIsLockedCommand(), espIsOperatorInPoolCommand(), @@ -67,11 +70,13 @@ func init() { espRewardTokenCommand(), espRewardsEligibilityRestorableAtCommand(), espTotalWeightCommand(), + espDeactivateChaosnetCommand(), espInsertOperatorCommand(), espLockCommand(), espReceiveApprovalCommand(), espRenounceOwnershipCommand(), espRestoreRewardEligibilityCommand(), + espTransferChaosnetOwnerRoleCommand(), espTransferOwnershipCommand(), espUnlockCommand(), espUpdateOperatorStatusCommand(), @@ -127,6 +132,40 @@ func espCanRestoreRewardEligibility(c *cobra.Command, args []string) error { return nil } +func espChaosnetOwnerCommand() *cobra.Command { + c := &cobra.Command{ + Use: "chaosnet-owner", + Short: "Calls the view method chaosnetOwner on the EcdsaSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: espChaosnetOwner, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func espChaosnetOwner(c *cobra.Command, args []string) error { + contract, err := initializeEcdsaSortitionPool(c) + if err != nil { + return err + } + + result, err := contract.ChaosnetOwnerAtBlock( + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + func espGetAvailableRewardsCommand() *cobra.Command { c := &cobra.Command{ Use: "get-available-rewards [arg_operator]", @@ -333,6 +372,83 @@ func espIneligibleEarnedRewards(c *cobra.Command, args []string) error { return nil } +func espIsBetaOperatorCommand() *cobra.Command { + c := &cobra.Command{ + Use: "is-beta-operator [arg0]", + Short: "Calls the view method isBetaOperator on the EcdsaSortitionPool contract.", + Args: cmd.ArgCountChecker(1), + RunE: espIsBetaOperator, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func espIsBetaOperator(c *cobra.Command, args []string) error { + contract, err := initializeEcdsaSortitionPool(c) + if err != nil { + return err + } + + arg0, err := chainutil.AddressFromHex(args[0]) + if err != nil { + return fmt.Errorf( + "couldn't parse parameter arg0, a address, from passed value %v", + args[0], + ) + } + + result, err := contract.IsBetaOperatorAtBlock( + arg0, + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + +func espIsChaosnetActiveCommand() *cobra.Command { + c := &cobra.Command{ + Use: "is-chaosnet-active", + Short: "Calls the view method isChaosnetActive on the EcdsaSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: espIsChaosnetActive, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + cmd.InitConstFlags(c) + + return c +} + +func espIsChaosnetActive(c *cobra.Command, args []string) error { + contract, err := initializeEcdsaSortitionPool(c) + if err != nil { + return err + } + + result, err := contract.IsChaosnetActiveAtBlock( + cmd.BlockFlagValue.Int, + ) + + if err != nil { + return err + } + + cmd.PrintOutput(result) + + return nil +} + func espIsEligibleForRewardsCommand() *cobra.Command { c := &cobra.Command{ Use: "is-eligible-for-rewards [arg_operator]", @@ -762,6 +878,55 @@ func espTotalWeight(c *cobra.Command, args []string) error { /// ------------------- Non-const methods ------------------- +func espDeactivateChaosnetCommand() *cobra.Command { + c := &cobra.Command{ + Use: "deactivate-chaosnet", + Short: "Calls the nonpayable method deactivateChaosnet on the EcdsaSortitionPool contract.", + Args: cmd.ArgCountChecker(0), + RunE: espDeactivateChaosnet, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + c.PreRunE = cmd.NonConstArgsChecker + cmd.InitNonConstFlags(c) + + return c +} + +func espDeactivateChaosnet(c *cobra.Command, args []string) error { + contract, err := initializeEcdsaSortitionPool(c) + if err != nil { + return err + } + + var ( + transaction *types.Transaction + ) + + if shouldSubmit, _ := c.Flags().GetBool(cmd.SubmitFlag); shouldSubmit { + // Do a regular submission. Take payable into account. + transaction, err = contract.DeactivateChaosnet() + if err != nil { + return err + } + + cmd.PrintOutput(transaction.Hash()) + } else { + // Do a call. + err = contract.CallDeactivateChaosnet( + cmd.BlockFlagValue.Int, + ) + if err != nil { + return err + } + + cmd.PrintOutput("success") + } + + return nil +} + func espInsertOperatorCommand() *cobra.Command { c := &cobra.Command{ Use: "insert-operator [arg_operator] [arg_authorizedStake]", @@ -1076,6 +1241,66 @@ func espRestoreRewardEligibility(c *cobra.Command, args []string) error { return nil } +func espTransferChaosnetOwnerRoleCommand() *cobra.Command { + c := &cobra.Command{ + Use: "transfer-chaosnet-owner-role [arg_newChaosnetOwner]", + Short: "Calls the nonpayable method transferChaosnetOwnerRole on the EcdsaSortitionPool contract.", + Args: cmd.ArgCountChecker(1), + RunE: espTransferChaosnetOwnerRole, + SilenceUsage: true, + DisableFlagsInUseLine: true, + } + + c.PreRunE = cmd.NonConstArgsChecker + cmd.InitNonConstFlags(c) + + return c +} + +func espTransferChaosnetOwnerRole(c *cobra.Command, args []string) error { + contract, err := initializeEcdsaSortitionPool(c) + if err != nil { + return err + } + + arg_newChaosnetOwner, err := chainutil.AddressFromHex(args[0]) + if err != nil { + return fmt.Errorf( + "couldn't parse parameter arg_newChaosnetOwner, a address, from passed value %v", + args[0], + ) + } + + var ( + transaction *types.Transaction + ) + + if shouldSubmit, _ := c.Flags().GetBool(cmd.SubmitFlag); shouldSubmit { + // Do a regular submission. Take payable into account. + transaction, err = contract.TransferChaosnetOwnerRole( + arg_newChaosnetOwner, + ) + if err != nil { + return err + } + + cmd.PrintOutput(transaction.Hash()) + } else { + // Do a call. + err = contract.CallTransferChaosnetOwnerRole( + arg_newChaosnetOwner, + cmd.BlockFlagValue.Int, + ) + if err != nil { + return err + } + + cmd.PrintOutput("success") + } + + return nil +} + func espTransferOwnershipCommand() *cobra.Command { c := &cobra.Command{ Use: "transfer-ownership [arg_newOwner]", diff --git a/pkg/chain/ethereum/ecdsa/gen/contract/EcdsaSortitionPool.go b/pkg/chain/ethereum/ecdsa/gen/contract/EcdsaSortitionPool.go index e3818798f6..62992d1d92 100644 --- a/pkg/chain/ethereum/ecdsa/gen/contract/EcdsaSortitionPool.go +++ b/pkg/chain/ethereum/ecdsa/gen/contract/EcdsaSortitionPool.go @@ -104,6 +104,268 @@ func NewEcdsaSortitionPool( // ----- Non-const Methods ------ +// Transaction submission. +func (esp *EcdsaSortitionPool) AddBetaOperators( + arg_operators []common.Address, + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + espLogger.Debug( + "submitting transaction addBetaOperators", + " params: ", + fmt.Sprint( + arg_operators, + ), + ) + + esp.transactionMutex.Lock() + defer esp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *esp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := esp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := esp.contract.AddBetaOperators( + transactorOptions, + arg_operators, + ) + if err != nil { + return transaction, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "addBetaOperators", + arg_operators, + ) + } + + espLogger.Infof( + "submitted transaction addBetaOperators with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go esp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := esp.contract.AddBetaOperators( + newTransactorOptions, + arg_operators, + ) + if err != nil { + return nil, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "addBetaOperators", + arg_operators, + ) + } + + espLogger.Infof( + "submitted transaction addBetaOperators with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + esp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (esp *EcdsaSortitionPool) CallAddBetaOperators( + arg_operators []common.Address, + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + esp.transactorOptions.From, + blockNumber, nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "addBetaOperators", + &result, + arg_operators, + ) + + return err +} + +func (esp *EcdsaSortitionPool) AddBetaOperatorsGasEstimate( + arg_operators []common.Address, +) (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + esp.callerOptions.From, + esp.contractAddress, + "addBetaOperators", + esp.contractABI, + esp.transactor, + arg_operators, + ) + + return result, err +} + +// Transaction submission. +func (esp *EcdsaSortitionPool) DeactivateChaosnet( + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + espLogger.Debug( + "submitting transaction deactivateChaosnet", + ) + + esp.transactionMutex.Lock() + defer esp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *esp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := esp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := esp.contract.DeactivateChaosnet( + transactorOptions, + ) + if err != nil { + return transaction, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "deactivateChaosnet", + ) + } + + espLogger.Infof( + "submitted transaction deactivateChaosnet with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go esp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := esp.contract.DeactivateChaosnet( + newTransactorOptions, + ) + if err != nil { + return nil, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "deactivateChaosnet", + ) + } + + espLogger.Infof( + "submitted transaction deactivateChaosnet with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + esp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (esp *EcdsaSortitionPool) CallDeactivateChaosnet( + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + esp.transactorOptions.From, + blockNumber, nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "deactivateChaosnet", + &result, + ) + + return err +} + +func (esp *EcdsaSortitionPool) DeactivateChaosnetGasEstimate() (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + esp.callerOptions.From, + esp.contractAddress, + "deactivateChaosnet", + esp.contractABI, + esp.transactor, + ) + + return result, err +} + // Transaction submission. func (esp *EcdsaSortitionPool) InsertOperator( arg_operator common.Address, @@ -955,16 +1217,16 @@ func (esp *EcdsaSortitionPool) SetRewardIneligibilityGasEstimate( } // Transaction submission. -func (esp *EcdsaSortitionPool) TransferOwnership( - arg_newOwner common.Address, +func (esp *EcdsaSortitionPool) TransferChaosnetOwnerRole( + arg_newChaosnetOwner common.Address, transactionOptions ...chainutil.TransactionOptions, ) (*types.Transaction, error) { espLogger.Debug( - "submitting transaction transferOwnership", + "submitting transaction transferChaosnetOwnerRole", " params: ", fmt.Sprint( - arg_newOwner, + arg_newChaosnetOwner, ), ) @@ -990,22 +1252,22 @@ func (esp *EcdsaSortitionPool) TransferOwnership( transactorOptions.Nonce = new(big.Int).SetUint64(nonce) - transaction, err := esp.contract.TransferOwnership( + transaction, err := esp.contract.TransferChaosnetOwnerRole( transactorOptions, - arg_newOwner, + arg_newChaosnetOwner, ) if err != nil { return transaction, esp.errorResolver.ResolveError( err, esp.transactorOptions.From, nil, - "transferOwnership", - arg_newOwner, + "transferChaosnetOwnerRole", + arg_newChaosnetOwner, ) } espLogger.Infof( - "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + "submitted transaction transferChaosnetOwnerRole with id: [%s] and nonce [%v]", transaction.Hash(), transaction.Nonce(), ) @@ -1024,22 +1286,22 @@ func (esp *EcdsaSortitionPool) TransferOwnership( newTransactorOptions.GasLimit = transactorOptions.GasLimit } - transaction, err := esp.contract.TransferOwnership( + transaction, err := esp.contract.TransferChaosnetOwnerRole( newTransactorOptions, - arg_newOwner, + arg_newChaosnetOwner, ) if err != nil { return nil, esp.errorResolver.ResolveError( err, esp.transactorOptions.From, nil, - "transferOwnership", - arg_newOwner, + "transferChaosnetOwnerRole", + arg_newChaosnetOwner, ) } espLogger.Infof( - "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + "submitted transaction transferChaosnetOwnerRole with id: [%s] and nonce [%v]", transaction.Hash(), transaction.Nonce(), ) @@ -1054,8 +1316,8 @@ func (esp *EcdsaSortitionPool) TransferOwnership( } // Non-mutating call, not a transaction submission. -func (esp *EcdsaSortitionPool) CallTransferOwnership( - arg_newOwner common.Address, +func (esp *EcdsaSortitionPool) CallTransferChaosnetOwnerRole( + arg_newChaosnetOwner common.Address, blockNumber *big.Int, ) error { var result interface{} = nil @@ -1067,23 +1329,161 @@ func (esp *EcdsaSortitionPool) CallTransferOwnership( esp.caller, esp.errorResolver, esp.contractAddress, - "transferOwnership", + "transferChaosnetOwnerRole", &result, - arg_newOwner, + arg_newChaosnetOwner, ) return err } -func (esp *EcdsaSortitionPool) TransferOwnershipGasEstimate( - arg_newOwner common.Address, +func (esp *EcdsaSortitionPool) TransferChaosnetOwnerRoleGasEstimate( + arg_newChaosnetOwner common.Address, ) (uint64, error) { var result uint64 result, err := chainutil.EstimateGas( esp.callerOptions.From, esp.contractAddress, - "transferOwnership", + "transferChaosnetOwnerRole", + esp.contractABI, + esp.transactor, + arg_newChaosnetOwner, + ) + + return result, err +} + +// Transaction submission. +func (esp *EcdsaSortitionPool) TransferOwnership( + arg_newOwner common.Address, + + transactionOptions ...chainutil.TransactionOptions, +) (*types.Transaction, error) { + espLogger.Debug( + "submitting transaction transferOwnership", + " params: ", + fmt.Sprint( + arg_newOwner, + ), + ) + + esp.transactionMutex.Lock() + defer esp.transactionMutex.Unlock() + + // create a copy + transactorOptions := new(bind.TransactOpts) + *transactorOptions = *esp.transactorOptions + + if len(transactionOptions) > 1 { + return nil, fmt.Errorf( + "could not process multiple transaction options sets", + ) + } else if len(transactionOptions) > 0 { + transactionOptions[0].Apply(transactorOptions) + } + + nonce, err := esp.nonceManager.CurrentNonce() + if err != nil { + return nil, fmt.Errorf("failed to retrieve account nonce: %v", err) + } + + transactorOptions.Nonce = new(big.Int).SetUint64(nonce) + + transaction, err := esp.contract.TransferOwnership( + transactorOptions, + arg_newOwner, + ) + if err != nil { + return transaction, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "transferOwnership", + arg_newOwner, + ) + } + + espLogger.Infof( + "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + go esp.miningWaiter.ForceMining( + transaction, + transactorOptions, + func(newTransactorOptions *bind.TransactOpts) (*types.Transaction, error) { + // If original transactor options has a non-zero gas limit, that + // means the client code set it on their own. In that case, we + // should rewrite the gas limit from the original transaction + // for each resubmission. If the gas limit is not set by the client + // code, let the the submitter re-estimate the gas limit on each + // resubmission. + if transactorOptions.GasLimit != 0 { + newTransactorOptions.GasLimit = transactorOptions.GasLimit + } + + transaction, err := esp.contract.TransferOwnership( + newTransactorOptions, + arg_newOwner, + ) + if err != nil { + return nil, esp.errorResolver.ResolveError( + err, + esp.transactorOptions.From, + nil, + "transferOwnership", + arg_newOwner, + ) + } + + espLogger.Infof( + "submitted transaction transferOwnership with id: [%s] and nonce [%v]", + transaction.Hash(), + transaction.Nonce(), + ) + + return transaction, nil + }, + ) + + esp.nonceManager.IncrementNonce() + + return transaction, err +} + +// Non-mutating call, not a transaction submission. +func (esp *EcdsaSortitionPool) CallTransferOwnership( + arg_newOwner common.Address, + blockNumber *big.Int, +) error { + var result interface{} = nil + + err := chainutil.CallAtBlock( + esp.transactorOptions.From, + blockNumber, nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "transferOwnership", + &result, + arg_newOwner, + ) + + return err +} + +func (esp *EcdsaSortitionPool) TransferOwnershipGasEstimate( + arg_newOwner common.Address, +) (uint64, error) { + var result uint64 + + result, err := chainutil.EstimateGas( + esp.callerOptions.From, + esp.contractAddress, + "transferOwnership", esp.contractABI, esp.transactor, arg_newOwner, @@ -1695,6 +2095,43 @@ func (esp *EcdsaSortitionPool) CanRestoreRewardEligibilityAtBlock( return result, err } +func (esp *EcdsaSortitionPool) ChaosnetOwner() (common.Address, error) { + result, err := esp.contract.ChaosnetOwner( + esp.callerOptions, + ) + + if err != nil { + return result, esp.errorResolver.ResolveError( + err, + esp.callerOptions.From, + nil, + "chaosnetOwner", + ) + } + + return result, err +} + +func (esp *EcdsaSortitionPool) ChaosnetOwnerAtBlock( + blockNumber *big.Int, +) (common.Address, error) { + var result common.Address + + err := chainutil.CallAtBlock( + esp.callerOptions.From, + blockNumber, + nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "chaosnetOwner", + &result, + ) + + return result, err +} + func (esp *EcdsaSortitionPool) GetAvailableRewards( arg_operator common.Address, ) (*big.Int, error) { @@ -1947,6 +2384,86 @@ func (esp *EcdsaSortitionPool) IneligibleEarnedRewardsAtBlock( return result, err } +func (esp *EcdsaSortitionPool) IsBetaOperator( + arg0 common.Address, +) (bool, error) { + result, err := esp.contract.IsBetaOperator( + esp.callerOptions, + arg0, + ) + + if err != nil { + return result, esp.errorResolver.ResolveError( + err, + esp.callerOptions.From, + nil, + "isBetaOperator", + arg0, + ) + } + + return result, err +} + +func (esp *EcdsaSortitionPool) IsBetaOperatorAtBlock( + arg0 common.Address, + blockNumber *big.Int, +) (bool, error) { + var result bool + + err := chainutil.CallAtBlock( + esp.callerOptions.From, + blockNumber, + nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "isBetaOperator", + &result, + arg0, + ) + + return result, err +} + +func (esp *EcdsaSortitionPool) IsChaosnetActive() (bool, error) { + result, err := esp.contract.IsChaosnetActive( + esp.callerOptions, + ) + + if err != nil { + return result, esp.errorResolver.ResolveError( + err, + esp.callerOptions.From, + nil, + "isChaosnetActive", + ) + } + + return result, err +} + +func (esp *EcdsaSortitionPool) IsChaosnetActiveAtBlock( + blockNumber *big.Int, +) (bool, error) { + var result bool + + err := chainutil.CallAtBlock( + esp.callerOptions.From, + blockNumber, + nil, + esp.contractABI, + esp.caller, + esp.errorResolver, + esp.contractAddress, + "isChaosnetActive", + &result, + ) + + return result, err +} + func (esp *EcdsaSortitionPool) IsEligibleForRewards( arg_operator common.Address, ) (bool, error) { @@ -2439,6 +2956,543 @@ func (esp *EcdsaSortitionPool) TotalWeightAtBlock( // ------ Events ------- +func (esp *EcdsaSortitionPool) BetaOperatorsAddedEvent( + opts *ethereum.SubscribeOpts, +) *EspBetaOperatorsAddedSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &EspBetaOperatorsAddedSubscription{ + esp, + opts, + } +} + +type EspBetaOperatorsAddedSubscription struct { + contract *EcdsaSortitionPool + opts *ethereum.SubscribeOpts +} + +type ecdsaSortitionPoolBetaOperatorsAddedFunc func( + Operators []common.Address, + blockNumber uint64, +) + +func (boas *EspBetaOperatorsAddedSubscription) OnEvent( + handler ecdsaSortitionPoolBetaOperatorsAddedFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.EcdsaSortitionPoolBetaOperatorsAdded) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.Operators, + event.Raw.BlockNumber, + ) + } + } + }() + + sub := boas.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (boas *EspBetaOperatorsAddedSubscription) Pipe( + sink chan *abi.EcdsaSortitionPoolBetaOperatorsAdded, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(boas.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := boas.contract.blockCounter.CurrentBlock() + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - boas.opts.PastBlocks + + espLogger.Infof( + "subscription monitoring fetching past BetaOperatorsAdded events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := boas.contract.PastBetaOperatorsAddedEvents( + fromBlock, + nil, + ) + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + espLogger.Infof( + "subscription monitoring fetched [%v] past BetaOperatorsAdded events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := boas.contract.watchBetaOperatorsAdded( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (esp *EcdsaSortitionPool) watchBetaOperatorsAdded( + sink chan *abi.EcdsaSortitionPoolBetaOperatorsAdded, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return esp.contract.WatchBetaOperatorsAdded( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + espLogger.Errorf( + "subscription to event BetaOperatorsAdded had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + espLogger.Errorf( + "subscription to event BetaOperatorsAdded failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (esp *EcdsaSortitionPool) PastBetaOperatorsAddedEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.EcdsaSortitionPoolBetaOperatorsAdded, error) { + iterator, err := esp.contract.FilterBetaOperatorsAdded( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past BetaOperatorsAdded events: [%v]", + err, + ) + } + + events := make([]*abi.EcdsaSortitionPoolBetaOperatorsAdded, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + +func (esp *EcdsaSortitionPool) ChaosnetDeactivatedEvent( + opts *ethereum.SubscribeOpts, +) *EspChaosnetDeactivatedSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &EspChaosnetDeactivatedSubscription{ + esp, + opts, + } +} + +type EspChaosnetDeactivatedSubscription struct { + contract *EcdsaSortitionPool + opts *ethereum.SubscribeOpts +} + +type ecdsaSortitionPoolChaosnetDeactivatedFunc func( + blockNumber uint64, +) + +func (cds *EspChaosnetDeactivatedSubscription) OnEvent( + handler ecdsaSortitionPoolChaosnetDeactivatedFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.EcdsaSortitionPoolChaosnetDeactivated) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.Raw.BlockNumber, + ) + } + } + }() + + sub := cds.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (cds *EspChaosnetDeactivatedSubscription) Pipe( + sink chan *abi.EcdsaSortitionPoolChaosnetDeactivated, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(cds.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := cds.contract.blockCounter.CurrentBlock() + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - cds.opts.PastBlocks + + espLogger.Infof( + "subscription monitoring fetching past ChaosnetDeactivated events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := cds.contract.PastChaosnetDeactivatedEvents( + fromBlock, + nil, + ) + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + espLogger.Infof( + "subscription monitoring fetched [%v] past ChaosnetDeactivated events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := cds.contract.watchChaosnetDeactivated( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (esp *EcdsaSortitionPool) watchChaosnetDeactivated( + sink chan *abi.EcdsaSortitionPoolChaosnetDeactivated, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return esp.contract.WatchChaosnetDeactivated( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + espLogger.Errorf( + "subscription to event ChaosnetDeactivated had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + espLogger.Errorf( + "subscription to event ChaosnetDeactivated failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (esp *EcdsaSortitionPool) PastChaosnetDeactivatedEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.EcdsaSortitionPoolChaosnetDeactivated, error) { + iterator, err := esp.contract.FilterChaosnetDeactivated( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past ChaosnetDeactivated events: [%v]", + err, + ) + } + + events := make([]*abi.EcdsaSortitionPoolChaosnetDeactivated, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + +func (esp *EcdsaSortitionPool) ChaosnetOwnerRoleTransferredEvent( + opts *ethereum.SubscribeOpts, +) *EspChaosnetOwnerRoleTransferredSubscription { + if opts == nil { + opts = new(ethereum.SubscribeOpts) + } + if opts.Tick == 0 { + opts.Tick = chainutil.DefaultSubscribeOptsTick + } + if opts.PastBlocks == 0 { + opts.PastBlocks = chainutil.DefaultSubscribeOptsPastBlocks + } + + return &EspChaosnetOwnerRoleTransferredSubscription{ + esp, + opts, + } +} + +type EspChaosnetOwnerRoleTransferredSubscription struct { + contract *EcdsaSortitionPool + opts *ethereum.SubscribeOpts +} + +type ecdsaSortitionPoolChaosnetOwnerRoleTransferredFunc func( + OldChaosnetOwner common.Address, + NewChaosnetOwner common.Address, + blockNumber uint64, +) + +func (corts *EspChaosnetOwnerRoleTransferredSubscription) OnEvent( + handler ecdsaSortitionPoolChaosnetOwnerRoleTransferredFunc, +) subscription.EventSubscription { + eventChan := make(chan *abi.EcdsaSortitionPoolChaosnetOwnerRoleTransferred) + ctx, cancelCtx := context.WithCancel(context.Background()) + + go func() { + for { + select { + case <-ctx.Done(): + return + case event := <-eventChan: + handler( + event.OldChaosnetOwner, + event.NewChaosnetOwner, + event.Raw.BlockNumber, + ) + } + } + }() + + sub := corts.Pipe(eventChan) + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (corts *EspChaosnetOwnerRoleTransferredSubscription) Pipe( + sink chan *abi.EcdsaSortitionPoolChaosnetOwnerRoleTransferred, +) subscription.EventSubscription { + ctx, cancelCtx := context.WithCancel(context.Background()) + go func() { + ticker := time.NewTicker(corts.opts.Tick) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + lastBlock, err := corts.contract.blockCounter.CurrentBlock() + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + } + fromBlock := lastBlock - corts.opts.PastBlocks + + espLogger.Infof( + "subscription monitoring fetching past ChaosnetOwnerRoleTransferred events "+ + "starting from block [%v]", + fromBlock, + ) + events, err := corts.contract.PastChaosnetOwnerRoleTransferredEvents( + fromBlock, + nil, + ) + if err != nil { + espLogger.Errorf( + "subscription failed to pull events: [%v]", + err, + ) + continue + } + espLogger.Infof( + "subscription monitoring fetched [%v] past ChaosnetOwnerRoleTransferred events", + len(events), + ) + + for _, event := range events { + sink <- event + } + } + } + }() + + sub := corts.contract.watchChaosnetOwnerRoleTransferred( + sink, + ) + + return subscription.NewEventSubscription(func() { + sub.Unsubscribe() + cancelCtx() + }) +} + +func (esp *EcdsaSortitionPool) watchChaosnetOwnerRoleTransferred( + sink chan *abi.EcdsaSortitionPoolChaosnetOwnerRoleTransferred, +) event.Subscription { + subscribeFn := func(ctx context.Context) (event.Subscription, error) { + return esp.contract.WatchChaosnetOwnerRoleTransferred( + &bind.WatchOpts{Context: ctx}, + sink, + ) + } + + thresholdViolatedFn := func(elapsed time.Duration) { + espLogger.Errorf( + "subscription to event ChaosnetOwnerRoleTransferred had to be "+ + "retried [%s] since the last attempt; please inspect "+ + "host chain connectivity", + elapsed, + ) + } + + subscriptionFailedFn := func(err error) { + espLogger.Errorf( + "subscription to event ChaosnetOwnerRoleTransferred failed "+ + "with error: [%v]; resubscription attempt will be "+ + "performed", + err, + ) + } + + return chainutil.WithResubscription( + chainutil.SubscriptionBackoffMax, + subscribeFn, + chainutil.SubscriptionAlertThreshold, + thresholdViolatedFn, + subscriptionFailedFn, + ) +} + +func (esp *EcdsaSortitionPool) PastChaosnetOwnerRoleTransferredEvents( + startBlock uint64, + endBlock *uint64, +) ([]*abi.EcdsaSortitionPoolChaosnetOwnerRoleTransferred, error) { + iterator, err := esp.contract.FilterChaosnetOwnerRoleTransferred( + &bind.FilterOpts{ + Start: startBlock, + End: endBlock, + }, + ) + if err != nil { + return nil, fmt.Errorf( + "error retrieving past ChaosnetOwnerRoleTransferred events: [%v]", + err, + ) + } + + events := make([]*abi.EcdsaSortitionPoolChaosnetOwnerRoleTransferred, 0) + + for iterator.Next() { + event := iterator.Event + events = append(events, event) + } + + return events, nil +} + func (esp *EcdsaSortitionPool) IneligibleForRewardsEvent( opts *ethereum.SubscribeOpts, ) *EspIneligibleForRewardsSubscription { From a132e4056fc40ec201ab748fab1cd6d4c2c62e9d Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 23 Sep 2022 13:53:43 +0200 Subject: [PATCH 4/6] Chaosnet SortitionPool functions added to chain implementations --- pkg/chain/ethereum/beacon.go | 27 +++++++++++++++++++-------- pkg/chain/ethereum/tbtc.go | 25 ++++++++++++++++++------- pkg/chain/local_v1/local.go | 8 ++++++++ pkg/sortition/chain.go | 7 +++++++ pkg/sortition/internal/local/chain.go | 19 +++++++++++++++++++ 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/pkg/chain/ethereum/beacon.go b/pkg/chain/ethereum/beacon.go index 3851d4a3fa..cfc9f67c4b 100644 --- a/pkg/chain/ethereum/beacon.go +++ b/pkg/chain/ethereum/beacon.go @@ -230,6 +230,17 @@ func (bc *BeaconChain) RestoreRewardEligibility() error { return err } +// Returns true if the chaosnet phase is active, false otherwise. +func (bc *BeaconChain) IsChaosnetActive() (bool, error) { + return bc.sortitionPool.IsChaosnetActive() +} + +// Returns true if operator is a beta operator, false otherwise. +// Chaosnet status does not matter. +func (bc *BeaconChain) IsBetaOperator() (bool, error) { + return bc.sortitionPool.IsBetaOperator(bc.key.Address) +} + // SelectGroup returns the group members for the group generated by // the given seed. This function can return an error if the beacon chain's // state does not allow for group selection at the moment. @@ -281,8 +292,8 @@ func (bc *BeaconChain) IsStaleGroup(groupPublicKey []byte) (bool, error) { } // TODO: Implement a real OnDKGStarted event subscription. The current -// implementation generates a fake event every 500th block where the -// seed is the keccak256 of the block number. +// implementation generates a fake event every 500th block where the +// seed is the keccak256 of the block number. func (bc *BeaconChain) OnDKGStarted( handler func(event *event.DKGStarted), ) subscription.EventSubscription { @@ -290,8 +301,8 @@ func (bc *BeaconChain) OnDKGStarted( } // TODO: Implement a real SubmitDKGResult action. The current implementation -// just creates and pipes the DKG submission event to the handlers -// registered in the dkgResultSubmissionHandlers map. +// just creates and pipes the DKG submission event to the handlers +// registered in the dkgResultSubmissionHandlers map. func (bc *BeaconChain) SubmitDKGResult( participantIndex beaconchain.GroupMemberIndex, dkgResult *beaconchain.DKGResult, @@ -305,9 +316,9 @@ func (bc *BeaconChain) SubmitDKGResult( } // TODO: Implement a real OnDKGResultSubmitted event subscription. The current -// implementation just pipes the DKG submission event generated within -// SubmitDKGResult to the handlers registered in the -// dkgResultSubmissionHandlers map. +// implementation just pipes the DKG submission event generated within +// SubmitDKGResult to the handlers registered in the +// dkgResultSubmissionHandlers map. func (bc *BeaconChain) OnDKGResultSubmitted( handler func(event *event.DKGResultSubmission), ) subscription.EventSubscription { @@ -422,7 +433,7 @@ func (bc *BeaconChain) CurrentRequestGroupPublicKey() ([]byte, error) { } // TODO: Temporary mock that simulates the behavior of the RandomBeacon -// contract. Should be removed eventually. +// contract. Should be removed eventually. type mockRandomBeacon struct { blockCounter chain.BlockCounter diff --git a/pkg/chain/ethereum/tbtc.go b/pkg/chain/ethereum/tbtc.go index 7795c0e018..78411c2608 100644 --- a/pkg/chain/ethereum/tbtc.go +++ b/pkg/chain/ethereum/tbtc.go @@ -284,6 +284,17 @@ func (tc *TbtcChain) RestoreRewardEligibility() error { return err } +// Returns true if the chaosnet phase is active, false otherwise. +func (tc *TbtcChain) IsChaosnetActive() (bool, error) { + return tc.sortitionPool.IsChaosnetActive() +} + +// Returns true if operator is a beta operator, false otherwise. +// Chaosnet status does not matter. +func (tc *TbtcChain) IsBetaOperator() (bool, error) { + return tc.sortitionPool.IsBetaOperator(tc.key.Address) +} + // SelectGroup returns the group members for the group generated by // the given seed. This function can return an error if the beacon chain's // state does not allow for group selection at the moment. @@ -325,9 +336,9 @@ func (tc *TbtcChain) OnDKGStarted( } // TODO: Implement a real OnDKGResultSubmitted event subscription. The current -// implementation just pipes the DKG submission event generated within -// SubmitDKGResult to the handlers registered in the -// dkgResultSubmissionHandlers map. +// implementation just pipes the DKG submission event generated within +// SubmitDKGResult to the handlers registered in the +// dkgResultSubmissionHandlers map. func (tc *TbtcChain) OnDKGResultSubmitted( handler func(event *tbtc.DKGResultSubmittedEvent), ) subscription.EventSubscription { @@ -335,8 +346,8 @@ func (tc *TbtcChain) OnDKGResultSubmitted( } // TODO: Implement a real SubmitDKGResult action. The current implementation -// just creates and pipes the DKG submission event to the handlers -// registered in the dkgResultSubmissionHandlers map. +// just creates and pipes the DKG submission event to the handlers +// registered in the dkgResultSubmissionHandlers map. func (tc *TbtcChain) SubmitDKGResult( memberIndex group.MemberIndex, result *dkg.Result, @@ -377,7 +388,7 @@ func (tc *TbtcChain) CalculateDKGResultHash( } // TODO: This is a temporary function that should be removed once the client -// is integrated with real on-chain contracts. +// is integrated with real on-chain contracts. func (tc *TbtcChain) OnSignatureRequested( handler func(event *tbtc.SignatureRequestedEvent), ) subscription.EventSubscription { @@ -385,7 +396,7 @@ func (tc *TbtcChain) OnSignatureRequested( } // TODO: Temporary mock that simulates the behavior of the WalletRegistry -// contract. Should be removed eventually. +// contract. Should be removed eventually. type mockWalletRegistry struct { blockCounter chain.BlockCounter diff --git a/pkg/chain/local_v1/local.go b/pkg/chain/local_v1/local.go index 2b2282ec8c..108ffa60f8 100644 --- a/pkg/chain/local_v1/local.go +++ b/pkg/chain/local_v1/local.go @@ -427,6 +427,14 @@ func (c *localChain) RestoreRewardEligibility() error { panic("unsupported") } +func (c *localChain) IsChaosnetActive() (bool, error) { + panic("unsupported") +} + +func (c *localChain) IsBetaOperator() (bool, error) { + panic("unsupported") +} + func generateHandlerID() int { // #nosec G404 (insecure random number source (rand)) // Local chain implementation doesn't require secure randomness. diff --git a/pkg/sortition/chain.go b/pkg/sortition/chain.go index fe8cb407bc..da15f0682d 100644 --- a/pkg/sortition/chain.go +++ b/pkg/sortition/chain.go @@ -57,4 +57,11 @@ type Chain interface { // Restores reward eligibility for the operator. RestoreRewardEligibility() error + + // Returns true if the chaosnet phase is active, false otherwise. + IsChaosnetActive() (bool, error) + + // Returns true if operator is a beta operator, false otherwise. + // Chaosnet status does not matter. + IsBetaOperator() (bool, error) } diff --git a/pkg/sortition/internal/local/chain.go b/pkg/sortition/internal/local/chain.go index 14616c18e3..641a5a7387 100644 --- a/pkg/sortition/internal/local/chain.go +++ b/pkg/sortition/internal/local/chain.go @@ -32,6 +32,9 @@ type Chain struct { ineligibleForRewardsUntil map[chain.Address]*big.Int ineligibleForRewardsUntilMutex sync.RWMutex + isChaosnetActive bool + isBetaOperator bool + isPoolLocked bool currentTimestamp *big.Int } @@ -204,6 +207,14 @@ func (c *Chain) RestoreRewardEligibility() error { return nil } +func (c *Chain) IsChaosnetActive() (bool, error) { + return c.isChaosnetActive, nil +} + +func (c *Chain) IsBetaOperator() (bool, error) { + return c.isBetaOperator, nil +} + func (c *Chain) SetCurrentTimestamp(currentTimestamp *big.Int) { c.currentTimestamp = currentTimestamp } @@ -214,3 +225,11 @@ func (c *Chain) SetRewardIneligibility(until *big.Int) { c.ineligibleForRewardsUntil[c.operatorAddress] = until } + +func (c *Chain) SetChaosnetStatus(isChaosnetActive bool) { + c.isChaosnetActive = isChaosnetActive +} + +func (c *Chain) SetBetaOperatorStatus(isBeta bool) { + c.isBetaOperator = isBeta +} From cd55d6993df9b389c4d4bca60323dac4c6c0795d Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Fri, 23 Sep 2022 14:23:14 +0200 Subject: [PATCH 5/6] Beta operator sortition pool policy for tbtc and random beacon BetaOperatorPolicy is a JoinPolicy implementation checking chaosnet and beta operator status. If chaosnet has been deactivated, the operator is allowed to join the pool. If chaosnet is active and the operator is beta operator, the operator is allowed to join the pool. If chaosnet is active and the operator is not beta operator, the operator is not allowed to join the pool. The BetaOperatorPolicy is applied both to the random beacon and tbtc. --- pkg/beacon/beacon.go | 2 +- pkg/sortition/policy.go | 49 ++++++++++++++++++++++++++++++++++++ pkg/sortition/policy_test.go | 48 +++++++++++++++++++++++++++++++++++ pkg/tbtc/tbtc.go | 11 +++++--- 4 files changed, 105 insertions(+), 5 deletions(-) diff --git a/pkg/beacon/beacon.go b/pkg/beacon/beacon.go index b8ec51aeff..10d45359f4 100644 --- a/pkg/beacon/beacon.go +++ b/pkg/beacon/beacon.go @@ -51,7 +51,7 @@ func Initialize( logger, beaconChain, sortition.DefaultStatusCheckTick, - sortition.UnconditionalJoinPolicy, + sortition.NewBetaOperatorPolicy(beaconChain, logger), ) if err != nil { return fmt.Errorf( diff --git a/pkg/sortition/policy.go b/pkg/sortition/policy.go index e0e14dc2e4..50401fd2c3 100644 --- a/pkg/sortition/policy.go +++ b/pkg/sortition/policy.go @@ -1,5 +1,7 @@ package sortition +import "github.com/ipfs/go-log" + // JoinPolicy determines how the client is supposed to join to the sortition // pool. The policy can encapsulate special conditions that the client want // to fulfill before joining the sortition pool. @@ -25,6 +27,12 @@ type ConjunctionPolicy struct { policies []JoinPolicy } +func NewConjunctionPolicy( + policies ...JoinPolicy, +) *ConjunctionPolicy { + return &ConjunctionPolicy{policies} +} + func (cp *ConjunctionPolicy) ShouldJoin() bool { for _, policy := range cp.policies { if !policy.ShouldJoin() { @@ -34,3 +42,44 @@ func (cp *ConjunctionPolicy) ShouldJoin() bool { return true } + +// BetaOperatorPolicy is a JoinPolicy implementation checking chaosnet and +// beta operator status. If chaosnet has been deactivated, the operator is +// allowed to join the pool. If chaosnet is active and the operator is beta +// operator, the operator is allowed to join the pool. If chaosnet is active and +// the operator is not beta operator, the operator is not allowed to join the +// pool. +type BetaOperatorPolicy struct { + chain Chain + logger log.StandardLogger +} + +func NewBetaOperatorPolicy( + chain Chain, + logger log.StandardLogger, +) *BetaOperatorPolicy { + return &BetaOperatorPolicy{ + chain, + logger, + } +} + +func (bop *BetaOperatorPolicy) ShouldJoin() bool { + isChaosnetActive, err := bop.chain.IsChaosnetActive() + if err != nil { + bop.logger.Errorf("could not determine if chaosnet is active: [%v]", err) + return false + } + + if !isChaosnetActive { + return true + } + + isBetaOperator, err := bop.chain.IsBetaOperator() + if err != nil { + bop.logger.Errorf("could not determine beta operator status: [%v]", err) + return false + } + + return isBetaOperator +} diff --git a/pkg/sortition/policy_test.go b/pkg/sortition/policy_test.go index 06b89825e1..9416f6e298 100644 --- a/pkg/sortition/policy_test.go +++ b/pkg/sortition/policy_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/keep-network/keep-core/pkg/internal/testutils" + "github.com/keep-network/keep-core/pkg/sortition/internal/local" ) func TestConjunctionPolicy(t *testing.T) { @@ -63,3 +64,50 @@ type mockPolicy struct { func (mp *mockPolicy) ShouldJoin() bool { return mp.shouldJoin } + +func TestBetaOperatorPolicy(t *testing.T) { + var tests = map[string]struct { + setupChain func(*local.Chain) + expectedResult bool + }{ + "chaosnet deactivated": { + setupChain: func(chain *local.Chain) { + chain.SetChaosnetStatus(false) + }, + expectedResult: true, + }, + "chaosnet active, not a beta operator": { + setupChain: func(chain *local.Chain) { + chain.SetChaosnetStatus(true) + }, + expectedResult: false, + }, + "chaosnet active, beta operator": { + setupChain: func(chain *local.Chain) { + chain.SetChaosnetStatus(true) + chain.SetBetaOperatorStatus(true) + }, + expectedResult: true, + }, + } + + for testName, test := range tests { + t.Run(testName, func(t *testing.T) { + localChain := local.Connect(testOperatorAddress) + test.setupChain(localChain) + + policy := BetaOperatorPolicy{ + localChain, + &testutils.MockLogger{}, + } + + actualResult := policy.ShouldJoin() + testutils.AssertBoolsEqual( + t, + "ShouldJoin() result", + test.expectedResult, + actualResult, + ) + }) + } +} diff --git a/pkg/tbtc/tbtc.go b/pkg/tbtc/tbtc.go index b2a81775bd..8de31f81dc 100644 --- a/pkg/tbtc/tbtc.go +++ b/pkg/tbtc/tbtc.go @@ -80,10 +80,13 @@ func Initialize( logger, chain, sortition.DefaultStatusCheckTick, - &enoughPreParamsInPoolPolicy{ - node: node, - config: config, - }, + sortition.NewConjunctionPolicy( + sortition.NewBetaOperatorPolicy(chain, logger), + &enoughPreParamsInPoolPolicy{ + node: node, + config: config, + }, + ), ) if err != nil { return fmt.Errorf( From 4acc73b7b69199645a3b03d046761e064d204fc8 Mon Sep 17 00:00:00 2001 From: Piotr Dyraga Date: Sun, 25 Sep 2022 16:24:55 +0200 Subject: [PATCH 6/6] Improved JoinPolicy documentation Just grammar improvements, nothing more. --- pkg/sortition/policy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/sortition/policy.go b/pkg/sortition/policy.go index 50401fd2c3..2df8b95237 100644 --- a/pkg/sortition/policy.go +++ b/pkg/sortition/policy.go @@ -2,8 +2,8 @@ package sortition import "github.com/ipfs/go-log" -// JoinPolicy determines how the client is supposed to join to the sortition -// pool. The policy can encapsulate special conditions that the client want +// JoinPolicy determines how the client is supposed to join the sortition +// pool. The policy can encapsulate special conditions that the client wants // to fulfill before joining the sortition pool. type JoinPolicy interface { // ShouldJoin indicates whether the joining condition is fulfilled and