From 5f8a651929ed0e7e536bac675de4ed6e0bf050d5 Mon Sep 17 00:00:00 2001 From: envestcc Date: Fri, 17 May 2024 13:04:11 +0800 Subject: [PATCH 1/3] draft for v3 --- action/protocol/staking/ethabi/v3/builder.go | 27 +++ .../ethabi/v3/stake_composite_buckets.go | 182 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 action/protocol/staking/ethabi/v3/builder.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_buckets.go diff --git a/action/protocol/staking/ethabi/v3/builder.go b/action/protocol/staking/ethabi/v3/builder.go new file mode 100644 index 0000000000..3a271c33ed --- /dev/null +++ b/action/protocol/staking/ethabi/v3/builder.go @@ -0,0 +1,27 @@ +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) { + if len(data) < 4 { + return nil, stakingComm.ErrInvalidCallData + } + + 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..f5bd60245f --- /dev/null +++ b/action/protocol/staking/ethabi/v3/stake_composite_buckets.go @@ -0,0 +1,182 @@ +package v3 + +import ( + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/iotextypes" + "google.golang.org/protobuf/proto" + + "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) (*CompositeBucketsStateContext, error) { + paramsMap := map[string]interface{}{} + ok := false + if err := _compositeBucketsMethod.Inputs.UnpackIntoMap(paramsMap, data); err != nil { + return nil, err + } + var offset, limit uint32 + if offset, ok = paramsMap["offset"].(uint32); !ok { + return nil, stakingComm.ErrDecodeFailure + } + if limit, ok = paramsMap["limit"].(uint32); !ok { + return nil, stakingComm.ErrDecodeFailure + } + + method := &iotexapi.ReadStakingDataMethod{ + Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS, + } + methodBytes, err := proto.Marshal(method) + if err != nil { + return nil, err + } + arguments := &iotexapi.ReadStakingDataRequest{ + Request: &iotexapi.ReadStakingDataRequest_Buckets{ + Buckets: &iotexapi.ReadStakingDataRequest_VoteBuckets{ + Pagination: &iotexapi.PaginationParam{ + Offset: offset, + Limit: limit, + }, + }, + }, + } + argumentsBytes, err := proto.Marshal(arguments) + if err != nil { + return nil, err + } + return &CompositeBucketsStateContext{ + &protocol.BaseStateContext{ + Parameter: &protocol.Parameters{ + MethodName: methodBytes, + Arguments: [][]byte{argumentsBytes}, + }, + }, + }, nil +} + +// EncodeToEth encode proto to eth +func (r *CompositeBucketsStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { + var result iotextypes.VoteBucketList + if err := proto.Unmarshal(resp.Data, &result); err != nil { + return "", err + } + + return stakingComm.EncodeVoteBucketListToEth(_compositeBucketsMethod.Outputs, &result) +} From 084a4bbf19fe5e93c5cd249d39be445ec5ecc7ff Mon Sep 17 00:00:00 2001 From: envestcc Date: Mon, 20 May 2024 08:56:07 +0800 Subject: [PATCH 2/3] add v3 --- action/protocol/staking/ethabi/v3/builder.go | 12 +- .../ethabi/v3/stake_composite_buckets.go | 57 +------- .../ethabi/v3/stake_composite_buckets_test.go | 100 ++++++++++++++ .../v3/stake_composite_bucketsbycandidate.go | 129 ++++++++++++++++++ ...stake_composite_bucketsbycandidate_test.go | 46 +++++++ .../v3/stake_composite_bucketsbyindices.go | 119 ++++++++++++++++ .../stake_composite_bucketsbyindices_test.go | 42 ++++++ .../v3/stake_composite_bucketsbyvoter.go | 129 ++++++++++++++++++ .../v3/stake_composite_bucketsbyvoter_test.go | 48 +++++++ 9 files changed, 621 insertions(+), 61 deletions(-) create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_buckets_test.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbycandidate_test.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbyindices_test.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter.go create mode 100644 action/protocol/staking/ethabi/v3/stake_composite_bucketsbyvoter_test.go diff --git a/action/protocol/staking/ethabi/v3/builder.go b/action/protocol/staking/ethabi/v3/builder.go index 3a271c33ed..8637d96a4f 100644 --- a/action/protocol/staking/ethabi/v3/builder.go +++ b/action/protocol/staking/ethabi/v3/builder.go @@ -15,12 +15,12 @@ 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:]) + 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 index f5bd60245f..c8361c3603 100644 --- a/action/protocol/staking/ethabi/v3/stake_composite_buckets.go +++ b/action/protocol/staking/ethabi/v3/stake_composite_buckets.go @@ -3,8 +3,6 @@ package v3 import ( "github.com/ethereum/go-ethereum/accounts/abi" "github.com/iotexproject/iotex-proto/golang/iotexapi" - "github.com/iotexproject/iotex-proto/golang/iotextypes" - "google.golang.org/protobuf/proto" "github.com/iotexproject/iotex-core/action/protocol" "github.com/iotexproject/iotex-core/action/protocol/abiutil" @@ -126,57 +124,6 @@ type CompositeBucketsStateContext struct { *protocol.BaseStateContext } -func newCompositeBucketsStateContext(data []byte) (*CompositeBucketsStateContext, error) { - paramsMap := map[string]interface{}{} - ok := false - if err := _compositeBucketsMethod.Inputs.UnpackIntoMap(paramsMap, data); err != nil { - return nil, err - } - var offset, limit uint32 - if offset, ok = paramsMap["offset"].(uint32); !ok { - return nil, stakingComm.ErrDecodeFailure - } - if limit, ok = paramsMap["limit"].(uint32); !ok { - return nil, stakingComm.ErrDecodeFailure - } - - method := &iotexapi.ReadStakingDataMethod{ - Method: iotexapi.ReadStakingDataMethod_COMPOSITE_BUCKETS, - } - methodBytes, err := proto.Marshal(method) - if err != nil { - return nil, err - } - arguments := &iotexapi.ReadStakingDataRequest{ - Request: &iotexapi.ReadStakingDataRequest_Buckets{ - Buckets: &iotexapi.ReadStakingDataRequest_VoteBuckets{ - Pagination: &iotexapi.PaginationParam{ - Offset: offset, - Limit: limit, - }, - }, - }, - } - argumentsBytes, err := proto.Marshal(arguments) - if err != nil { - return nil, err - } - return &CompositeBucketsStateContext{ - &protocol.BaseStateContext{ - Parameter: &protocol.Parameters{ - MethodName: methodBytes, - Arguments: [][]byte{argumentsBytes}, - }, - }, - }, nil -} - -// EncodeToEth encode proto to eth -func (r *CompositeBucketsStateContext) EncodeToEth(resp *iotexapi.ReadStateResponse) (string, error) { - var result iotextypes.VoteBucketList - if err := proto.Unmarshal(resp.Data, &result); err != nil { - return "", err - } - - return stakingComm.EncodeVoteBucketListToEth(_compositeBucketsMethod.Outputs, &result) +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) +} From 84d9abb52f9ecc26f7c48dc26ce28f3520a4f89a Mon Sep 17 00:00:00 2001 From: envestcc Date: Thu, 6 Jun 2024 12:38:44 +0800 Subject: [PATCH 3/3] enable v3 --- action/protocol/staking/ethabi/stake_base.go | 5 +++++ action/protocol/staking/ethabi/v3/builder.go | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) 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 index 8637d96a4f..1835e5d9c9 100644 --- a/action/protocol/staking/ethabi/v3/builder.go +++ b/action/protocol/staking/ethabi/v3/builder.go @@ -8,10 +8,6 @@ import ( ) func BuildReadStateRequest(data []byte) (protocol.StateContext, error) { - if len(data) < 4 { - return nil, stakingComm.ErrInvalidCallData - } - switch methodSig := hex.EncodeToString(data[:4]); methodSig { case hex.EncodeToString(_compositeBucketsMethod.ID): return newCompositeBucketsStateContext(data[4:])