diff --git a/action/protocol/staking/ethabi/stake_base.go b/action/protocol/staking/ethabi/stake_base.go index e9b3b4c61a..0bf2f89e2c 100644 --- a/action/protocol/staking/ethabi/stake_base.go +++ b/action/protocol/staking/ethabi/stake_base.go @@ -5,6 +5,7 @@ import ( stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" v1 "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/v1" v2 "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/v2" + v3 "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/v3" ) // BuildReadStateRequest decode eth_call data to StateContext @@ -21,5 +22,9 @@ func BuildReadStateRequest(data []byte) (protocol.StateContext, error) { if err == nil { return methodSig, nil } + methodSig, err = v3.BuildReadStateRequest(data) + if err == nil { + return methodSig, nil + } return nil, stakingComm.ErrInvalidCallSig } diff --git a/action/protocol/staking/ethabi/v3/builder.go b/action/protocol/staking/ethabi/v3/builder.go new file mode 100644 index 0000000000..1835e5d9c9 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/builder.go @@ -0,0 +1,23 @@ +package v3 + +import ( + "encoding/hex" + + "github.com/iotexproject/iotex-core/action/protocol" + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +func BuildReadStateRequest(data []byte) (protocol.StateContext, error) { + switch methodSig := hex.EncodeToString(data[:4]); methodSig { + case hex.EncodeToString(_compositeBucketsMethod.ID): + return newCompositeBucketsStateContext(data[4:]) + case hex.EncodeToString(_compositeBucketsByCandidateMethod.ID): + return newCompositeBucketsByCandidateStateContext(data[4:]) + case hex.EncodeToString(_compositeBucketsByIndexesMethod.ID): + return newCompositeBucketsByIndexesStateContext(data[4:]) + case hex.EncodeToString(_compositeBucketsByVoterMethod.ID): + return newCompositeBucketsByVoterStateContext(data[4:]) + default: + return nil, stakingComm.ErrInvalidCallSig + } +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_buckets.go b/action/protocol/staking/ethabi/v3/stake_composite_buckets.go new file mode 100644 index 0000000000..c8361c3603 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_buckets.go @@ -0,0 +1,129 @@ +package v3 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + + "github.com/iotexproject/iotex-core/action/protocol" + "github.com/iotexproject/iotex-core/action/protocol/abiutil" + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +const _compositeBucketsInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "uint32", + "name": "offset", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "limit", + "type": "uint32" + } + ], + "name": "compositeBucketsV3", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "address", + "name": "candidateAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "stakedDuration", + "type": "uint32" + }, + { + "internalType": "int64", + "name": "createTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "stakeStartTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "unstakeStartTime", + "type": "int64" + }, + { + "internalType": "bool", + "name": "autoStake", + "type": "bool" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint64", + "name": "stakedDurationBlockNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "createBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "stakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "unstakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "endorsementExpireBlockHeight", + "type": "uint64" + } + ], + "internalType": "struct IStaking.CompositeVoteBucket[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _compositeBucketsMethod abi.Method + +func init() { + _compositeBucketsMethod = abiutil.MustLoadMethod(_compositeBucketsInterfaceABI, "compositeBucketsV3") +} + +// CompositeBucketsStateContext context for Composite Buckets +type CompositeBucketsStateContext struct { + *protocol.BaseStateContext +} + +func newCompositeBucketsStateContext(data []byte) (*stakingComm.BucketsStateContext, error) { + return stakingComm.NewBucketsStateContext(data, &_compositeBucketsMethod, iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_buckets_test.go b/action/protocol/staking/ethabi/v3/stake_composite_buckets_test.go new file mode 100644 index 0000000000..a3372fa734 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_buckets_test.go @@ -0,0 +1,100 @@ +package v3 + +import ( + "encoding/hex" + "reflect" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/timestamppb" + + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +func TestBuildReadStateRequestCompositeBuckets(t *testing.T) { + r := require.New(t) + + // data, err := _compositeBucketsMethod.Inputs.Pack(uint32(1), uint32(5)) + // r.NoError(err) + // data = append(_compositeBucketsMethod.ID, data...) + // t.Logf("data: %s", hex.EncodeToString(data)) + + data, _ := hex.DecodeString("520f1bdc00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005") + req, err := BuildReadStateRequest(data) + + r.Nil(err) + r.EqualValues("*common.BucketsStateContext", reflect.TypeOf(req).String()) + + method := &iotexapi.ReadStakingDataMethod{ + Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS, + } + methodBytes, _ := proto.Marshal(method) + r.EqualValues(methodBytes, req.Parameters().MethodName) + + arguments := &iotexapi.ReadStakingDataRequest{ + Request: &iotexapi.ReadStakingDataRequest_Buckets{ + Buckets: &iotexapi.ReadStakingDataRequest_VoteBuckets{ + Pagination: &iotexapi.PaginationParam{ + Offset: 1, + Limit: 5, + }, + }, + }, + } + argumentsBytes, _ := proto.Marshal(arguments) + r.EqualValues([][]byte{argumentsBytes}, req.Parameters().Arguments) +} + +func TestEncodeCompositeVoteBucketListToEth(t *testing.T) { + r := require.New(t) + + buckets := make([]*iotextypes.VoteBucket, 3) + + buckets[0] = &iotextypes.VoteBucket{ + Index: 1, + CandidateAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqryn4k9fw", + StakedAmount: "1000000000000000000", + StakedDuration: 1_000_000, + CreateTime: ×tamppb.Timestamp{Seconds: 1_000_000_000}, + StakeStartTime: ×tamppb.Timestamp{Seconds: 1_000_000_001}, + UnstakeStartTime: ×tamppb.Timestamp{Seconds: 1_000_000_002}, + AutoStake: true, + Owner: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxgce2xkh", + ContractAddress: "", + } + buckets[1] = &iotextypes.VoteBucket{ + Index: 2, + CandidateAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr9wrzs5u", + StakedAmount: "2000000000000000000", + AutoStake: false, + Owner: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxf907nt9", + ContractAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxf907nt9", + StakedDurationBlockNumber: 1_000_000, + CreateBlockHeight: 1_000_000_000, + StakeStartBlockHeight: 1_000_000_001, + UnstakeStartBlockHeight: 1_000_000_002, + } + buckets[2] = &iotextypes.VoteBucket{ + Index: 2, + CandidateAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr9wrzs5u", + StakedAmount: "2000000000000000000", + AutoStake: false, + Owner: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxf907nt9", + ContractAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqxf907nt9", + StakedDurationBlockNumber: 1_000_000, + CreateBlockHeight: 1_000_000_000, + StakeStartBlockHeight: 1_000_000_001, + UnstakeStartBlockHeight: 1_000_000_002, + EndorsementExpireBlockHeight: 300_000_000, + } + + data, err := stakingComm.EncodeVoteBucketListToEth(_compositeBucketsMethod.Outputs, &iotextypes.VoteBucketList{ + Buckets: buckets, + }) + // t.Logf("data: %s\n", data) + r.Nil(err) + r.EqualValues("00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000003b9aca01000000000000000000000000000000000000000000000000000000003b9aca02000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000003b9aca01000000000000000000000000000000000000000000000000000000003b9aca020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000650000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000000000000000000000000f4240000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000003b9aca01000000000000000000000000000000000000000000000000000000003b9aca020000000000000000000000000000000000000000000000000000000000000000", data) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate.go new file mode 100644 index 0000000000..ab6b45c95c --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate.go @@ -0,0 +1,129 @@ +package v3 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + + "github.com/iotexproject/iotex-core/action/protocol/abiutil" + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +const _compositeBucketsByCandidateInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "string", + "name": "candName", + "type": "string" + }, + { + "internalType": "uint32", + "name": "offset", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "limit", + "type": "uint32" + } + ], + "name": "compositeBucketsByCandidateV3", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "address", + "name": "candidateAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "stakedDuration", + "type": "uint32" + }, + { + "internalType": "int64", + "name": "createTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "stakeStartTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "unstakeStartTime", + "type": "int64" + }, + { + "internalType": "bool", + "name": "autoStake", + "type": "bool" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint64", + "name": "stakedDurationBlockNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "createBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "stakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "unstakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "endorsementExpireBlockHeight", + "type": "uint64" + } + ], + "internalType": "struct IStaking.CompositeVoteBucket[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _compositeBucketsByCandidateMethod abi.Method + +func init() { + _compositeBucketsByCandidateMethod = abiutil.MustLoadMethod(_compositeBucketsByCandidateInterfaceABI, "compositeBucketsByCandidateV3") +} + +func newCompositeBucketsByCandidateStateContext(data []byte) (*stakingComm.BucketsByCandidateStateContext, error) { + return stakingComm.NewBucketsByCandidateStateContext(data, &_compositeBucketsByCandidateMethod, iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_CANDIDATE) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate_test.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate_test.go new file mode 100644 index 0000000000..ac54e55153 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate_test.go @@ -0,0 +1,46 @@ +package v3 + +import ( + "encoding/hex" + "reflect" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestBuildReadStateRequestCompositeBucketsByCandidate(t *testing.T) { + r := require.New(t) + + // data, err := _compositeBucketsByCandidateMethod.Inputs.Pack("hello", uint32(0), uint32(1)) + // r.NoError(err) + // data = append(_compositeBucketsByCandidateMethod.ID, data...) + // t.Logf("data: %s", hex.EncodeToString(data)) + + data, _ := hex.DecodeString("71a3e9b9000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000") + req, err := BuildReadStateRequest(data) + + r.Nil(err) + r.EqualValues("*common.BucketsByCandidateStateContext", reflect.TypeOf(req).String()) + + method := &iotexapi.ReadStakingDataMethod{ + Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_CANDIDATE, + } + methodBytes, _ := proto.Marshal(method) + r.EqualValues(methodBytes, req.Parameters().MethodName) + + arguments := &iotexapi.ReadStakingDataRequest{ + Request: &iotexapi.ReadStakingDataRequest_BucketsByCandidate{ + BucketsByCandidate: &iotexapi.ReadStakingDataRequest_VoteBucketsByCandidate{ + CandName: "hello", + Pagination: &iotexapi.PaginationParam{ + Offset: 0, + Limit: 1, + }, + }, + }, + } + argumentsBytes, _ := proto.Marshal(arguments) + r.EqualValues([][]byte{argumentsBytes}, req.Parameters().Arguments) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices.go new file mode 100644 index 0000000000..9388d63754 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices.go @@ -0,0 +1,119 @@ +package v3 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + + "github.com/iotexproject/iotex-core/action/protocol/abiutil" + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +const _compositeBucketsByIndexesInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "uint64[]", + "name": "indexes", + "type": "uint64[]" + } + ], + "name": "compositeBucketsByIndexesV3", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "address", + "name": "candidateAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "stakedDuration", + "type": "uint32" + }, + { + "internalType": "int64", + "name": "createTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "stakeStartTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "unstakeStartTime", + "type": "int64" + }, + { + "internalType": "bool", + "name": "autoStake", + "type": "bool" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint64", + "name": "stakedDurationBlockNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "createBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "stakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "unstakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "endorsementExpireBlockHeight", + "type": "uint64" + } + ], + "internalType": "struct IStaking.CompositeVoteBucket[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _compositeBucketsByIndexesMethod abi.Method + +func init() { + _compositeBucketsByIndexesMethod = abiutil.MustLoadMethod(_compositeBucketsByIndexesInterfaceABI, "compositeBucketsByIndexesV3") +} + +func newCompositeBucketsByIndexesStateContext(data []byte) (*stakingComm.BucketsByIndexesStateContext, error) { + return stakingComm.NewBucketsByIndexesStateContext(data, &_compositeBucketsByIndexesMethod, iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_INDEXES) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices_test.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices_test.go new file mode 100644 index 0000000000..83e1a648c3 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices_test.go @@ -0,0 +1,42 @@ +package v3 + +import ( + "encoding/hex" + "reflect" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestBuildReadStateRequestCompositeBucketsByIndexes(t *testing.T) { + r := require.New(t) + + // data, err := _compositeBucketsByIndexesMethod.Inputs.Pack([]uint64{1, 2}) + // r.NoError(err) + // data = append(_compositeBucketsByIndexesMethod.ID, data...) + // t.Logf("data: %s", hex.EncodeToString(data)) + + data, _ := hex.DecodeString("d9dc6fae0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002") + req, err := BuildReadStateRequest(data) + + r.Nil(err) + r.EqualValues("*common.BucketsByIndexesStateContext", reflect.TypeOf(req).String()) + + method := &iotexapi.ReadStakingDataMethod{ + Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_INDEXES, + } + methodBytes, _ := proto.Marshal(method) + r.EqualValues(methodBytes, req.Parameters().MethodName) + + arguments := &iotexapi.ReadStakingDataRequest{ + Request: &iotexapi.ReadStakingDataRequest_BucketsByIndexes{ + BucketsByIndexes: &iotexapi.ReadStakingDataRequest_VoteBucketsByIndexes{ + Index: []uint64{1, 2}, + }, + }, + } + argumentsBytes, _ := proto.Marshal(arguments) + r.EqualValues([][]byte{argumentsBytes}, req.Parameters().Arguments) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter.go new file mode 100644 index 0000000000..b8979af73c --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter.go @@ -0,0 +1,129 @@ +package v3 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + + "github.com/iotexproject/iotex-core/action/protocol/abiutil" + stakingComm "github.com/iotexproject/iotex-core/action/protocol/staking/ethabi/common" +) + +var _compositeBucketsByVoterInterfaceABI = `[ + { + "inputs": [ + { + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "internalType": "uint32", + "name": "offset", + "type": "uint32" + }, + { + "internalType": "uint32", + "name": "limit", + "type": "uint32" + } + ], + "name": "compositeBucketsByVoterV3", + "outputs": [ + { + "components": [ + { + "internalType": "uint64", + "name": "index", + "type": "uint64" + }, + { + "internalType": "address", + "name": "candidateAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "stakedAmount", + "type": "uint256" + }, + { + "internalType": "uint32", + "name": "stakedDuration", + "type": "uint32" + }, + { + "internalType": "int64", + "name": "createTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "stakeStartTime", + "type": "int64" + }, + { + "internalType": "int64", + "name": "unstakeStartTime", + "type": "int64" + }, + { + "internalType": "bool", + "name": "autoStake", + "type": "bool" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "contractAddress", + "type": "address" + }, + { + "internalType": "uint64", + "name": "stakedDurationBlockNumber", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "createBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "stakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "unstakeStartBlockHeight", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "endorsementExpireBlockHeight", + "type": "uint64" + } + ], + "internalType": "struct IStaking.CompositeVoteBucket[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + } +]` + +var _compositeBucketsByVoterMethod abi.Method + +func init() { + _compositeBucketsByVoterMethod = abiutil.MustLoadMethod(_compositeBucketsByVoterInterfaceABI, "compositeBucketsByVoterV3") +} + +func newCompositeBucketsByVoterStateContext(data []byte) (*stakingComm.BucketsByVoterStateContext, error) { + return stakingComm.NewBucketsByVoterStateContext(data, &_compositeBucketsByVoterMethod, iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_VOTER) +} diff --git a/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter_test.go b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter_test.go new file mode 100644 index 0000000000..4c1287a0a0 --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter_test.go @@ -0,0 +1,48 @@ +package v3 + +import ( + "encoding/hex" + "reflect" + "testing" + + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" +) + +func TestBuildReadStateRequestCompositeBucketsByVoter(t *testing.T) { + r := require.New(t) + + // addr, err := address.FromString("io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqryn4k9fw") + // r.NoError(err) + // data, err := _compositeBucketsByVoterMethod.Inputs.Pack(common.BytesToAddress(addr.Bytes()), uint32(1), uint32(2)) + // r.NoError(err) + // data = append(_compositeBucketsByVoterMethod.ID, data...) + // t.Logf("data: %s", hex.EncodeToString(data)) + + data, _ := hex.DecodeString("2736514b000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002") + req, err := BuildReadStateRequest(data) + + r.Nil(err) + r.EqualValues("*common.BucketsByVoterStateContext", reflect.TypeOf(req).String()) + + method := &iotexapi.ReadStakingDataMethod{ + Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS_BY_VOTER, + } + methodBytes, _ := proto.Marshal(method) + r.EqualValues(methodBytes, req.Parameters().MethodName) + + arguments := &iotexapi.ReadStakingDataRequest{ + Request: &iotexapi.ReadStakingDataRequest_BucketsByVoter{ + BucketsByVoter: &iotexapi.ReadStakingDataRequest_VoteBucketsByVoter{ + VoterAddress: "io1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqryn4k9fw", + Pagination: &iotexapi.PaginationParam{ + Offset: 1, + Limit: 2, + }, + }, + }, + } + argumentsBytes, _ := proto.Marshal(arguments) + r.EqualValues([][]byte{argumentsBytes}, req.Parameters().Arguments) +}