eth: rpc: fix sendRawTransaction, transactionIndex, feeHistory (#9736)

* Eth JSON-RPC API: add transactionIndex

* Eth JSON-RPC API: fix EthFeeHistory and EthSendRawTransaction

* Eth JSON-RPC API: fix parsing block parameter for getBlockByNumber

* fix itest
This commit is contained in:
ychiao 2022-11-27 21:44:43 -05:00 committed by GitHub
parent 176275267b
commit f1493fbee7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 72 additions and 20 deletions

View File

@ -779,15 +779,15 @@ type FullNode interface {
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash EthHash, txIndex EthUint64) (EthTx, error) //perm:read EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash EthHash, txIndex EthUint64) (EthTx, error) //perm:read
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum EthUint64, txIndex EthUint64) (EthTx, error) //perm:read EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum EthUint64, txIndex EthUint64) (EthTx, error) //perm:read
EthGetCode(ctx context.Context, address EthAddress, blkOpt string) (EthBytes, error) //perm:read EthGetCode(ctx context.Context, address EthAddress, blkOpt string) (EthBytes, error) //perm:read
EthGetStorageAt(ctx context.Context, address EthAddress, position EthBytes, blkParam string) (EthBytes, error) //perm:read EthGetStorageAt(ctx context.Context, address EthAddress, position EthBytes, blkParam string) (EthBytes, error) //perm:read
EthGetBalance(ctx context.Context, address EthAddress, blkParam string) (EthBigInt, error) //perm:read EthGetBalance(ctx context.Context, address EthAddress, blkParam string) (EthBigInt, error) //perm:read
EthChainId(ctx context.Context) (EthUint64, error) //perm:read EthChainId(ctx context.Context) (EthUint64, error) //perm:read
NetVersion(ctx context.Context) (string, error) //perm:read NetVersion(ctx context.Context) (string, error) //perm:read
NetListening(ctx context.Context) (bool, error) //perm:read NetListening(ctx context.Context) (bool, error) //perm:read
EthProtocolVersion(ctx context.Context) (EthUint64, error) //perm:read EthProtocolVersion(ctx context.Context) (EthUint64, error) //perm:read
EthGasPrice(ctx context.Context) (EthBigInt, error) //perm:read EthGasPrice(ctx context.Context) (EthBigInt, error) //perm:read
EthFeeHistory(ctx context.Context, blkCount EthUint64, newestBlk string, rewardPercentiles []int64) (EthFeeHistory, error) //perm:read EthFeeHistory(ctx context.Context, blkCount EthUint64, newestBlk string, rewardPercentiles []float64) (EthFeeHistory, error) //perm:read
EthMaxPriorityFeePerGas(ctx context.Context) (EthBigInt, error) //perm:read EthMaxPriorityFeePerGas(ctx context.Context) (EthBigInt, error) //perm:read
EthEstimateGas(ctx context.Context, tx EthCall) (EthUint64, error) //perm:read EthEstimateGas(ctx context.Context, tx EthCall) (EthUint64, error) //perm:read

View File

@ -444,3 +444,27 @@ type EthFeeHistory struct {
GasUsedRatio []float64 `json:"gasUsedRatio"` GasUsedRatio []float64 `json:"gasUsedRatio"`
Reward *[][]EthBigInt `json:"reward,omitempty"` Reward *[][]EthBigInt `json:"reward,omitempty"`
} }
type BlkNumType int64
const (
BlkNumLatest BlkNumType = iota
BlkNumPending
BlkNumVal
)
func ParseBlkNumOption(str string) (typ BlkNumType, blkNum EthUint64, err error) {
switch str {
case "pending":
return BlkNumPending, 0, nil
case "latest":
return BlkNumLatest, 0, nil
default:
var num EthUint64
err := num.UnmarshalJSON([]byte(`"` + str + `"`))
if err != nil {
return BlkNumVal, 0, err
}
return BlkNumVal, num, nil
}
}

View File

@ -997,7 +997,7 @@ func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1 interface{}) *gomo
} }
// EthFeeHistory mocks base method. // EthFeeHistory mocks base method.
func (m *MockFullNode) EthFeeHistory(arg0 context.Context, arg1 api.EthUint64, arg2 string, arg3 []int64) (api.EthFeeHistory, error) { func (m *MockFullNode) EthFeeHistory(arg0 context.Context, arg1 api.EthUint64, arg2 string, arg3 []float64) (api.EthFeeHistory, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthFeeHistory", arg0, arg1, arg2, arg3) ret := m.ctrl.Call(m, "EthFeeHistory", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(api.EthFeeHistory) ret0, _ := ret[0].(api.EthFeeHistory)

View File

@ -229,7 +229,7 @@ type FullNodeStruct struct {
EthEstimateGas func(p0 context.Context, p1 EthCall) (EthUint64, error) `perm:"read"` EthEstimateGas func(p0 context.Context, p1 EthCall) (EthUint64, error) `perm:"read"`
EthFeeHistory func(p0 context.Context, p1 EthUint64, p2 string, p3 []int64) (EthFeeHistory, error) `perm:"read"` EthFeeHistory func(p0 context.Context, p1 EthUint64, p2 string, p3 []float64) (EthFeeHistory, error) `perm:"read"`
EthGasPrice func(p0 context.Context) (EthBigInt, error) `perm:"read"` EthGasPrice func(p0 context.Context) (EthBigInt, error) `perm:"read"`
@ -1899,14 +1899,14 @@ func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 EthCall) (EthUint64
return *new(EthUint64), ErrNotSupported return *new(EthUint64), ErrNotSupported
} }
func (s *FullNodeStruct) EthFeeHistory(p0 context.Context, p1 EthUint64, p2 string, p3 []int64) (EthFeeHistory, error) { func (s *FullNodeStruct) EthFeeHistory(p0 context.Context, p1 EthUint64, p2 string, p3 []float64) (EthFeeHistory, error) {
if s.Internal.EthFeeHistory == nil { if s.Internal.EthFeeHistory == nil {
return *new(EthFeeHistory), ErrNotSupported return *new(EthFeeHistory), ErrNotSupported
} }
return s.Internal.EthFeeHistory(p0, p1, p2, p3) return s.Internal.EthFeeHistory(p0, p1, p2, p3)
} }
func (s *FullNodeStub) EthFeeHistory(p0 context.Context, p1 EthUint64, p2 string, p3 []int64) (EthFeeHistory, error) { func (s *FullNodeStub) EthFeeHistory(p0 context.Context, p1 EthUint64, p2 string, p3 []float64) (EthFeeHistory, error) {
return *new(EthFeeHistory), ErrNotSupported return *new(EthFeeHistory), ErrNotSupported
} }

Binary file not shown.

View File

@ -2244,7 +2244,7 @@ Inputs:
"0x5", "0x5",
"string value", "string value",
[ [
9 12.3
] ]
] ]
``` ```

View File

@ -67,7 +67,7 @@ func (e *EthModuleDummy) EthGetBalance(ctx context.Context, address api.EthAddre
return api.EthBigIntZero, ErrImplementMe return api.EthBigIntZero, ErrImplementMe
} }
func (e *EthModuleDummy) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []int64) (api.EthFeeHistory, error) { func (e *EthModuleDummy) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []float64) (api.EthFeeHistory, error) {
return api.EthFeeHistory{}, ErrImplementMe return api.EthFeeHistory{}, ErrImplementMe
} }

View File

@ -44,7 +44,7 @@ type EthModuleAPI interface {
EthGetCode(ctx context.Context, address api.EthAddress, blkOpt string) (api.EthBytes, error) EthGetCode(ctx context.Context, address api.EthAddress, blkOpt string) (api.EthBytes, error)
EthGetStorageAt(ctx context.Context, address api.EthAddress, position api.EthBytes, blkParam string) (api.EthBytes, error) EthGetStorageAt(ctx context.Context, address api.EthAddress, position api.EthBytes, blkParam string) (api.EthBytes, error)
EthGetBalance(ctx context.Context, address api.EthAddress, blkParam string) (api.EthBigInt, error) EthGetBalance(ctx context.Context, address api.EthAddress, blkParam string) (api.EthBigInt, error)
EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []int64) (api.EthFeeHistory, error) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlk string, rewardPercentiles []float64) (api.EthFeeHistory, error)
EthChainId(ctx context.Context) (api.EthUint64, error) EthChainId(ctx context.Context) (api.EthUint64, error)
NetVersion(ctx context.Context) (string, error) NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error) NetListening(ctx context.Context) (bool, error)
@ -54,7 +54,6 @@ type EthModuleAPI interface {
EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error) EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error)
EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error) EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error)
EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error) EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error)
// EthFeeHistory(ctx context.Context, blkCount string)
} }
var _ EthModuleAPI = *new(api.FullNode) var _ EthModuleAPI = *new(api.FullNode)
@ -140,9 +139,15 @@ func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash api.EthHash,
} }
func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (api.EthBlock, error) { func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (api.EthBlock, error) {
var num api.EthUint64 typ, num, err := api.ParseBlkNumOption(blkNum)
err := num.UnmarshalJSON([]byte(`"` + blkNum + `"`))
if err != nil { if err != nil {
return api.EthBlock{}, fmt.Errorf("cannot parse block number: %v", err)
}
switch typ {
case api.BlkNumLatest:
num = api.EthUint64(a.Chain.GetHeaviestTipSet().Height()) - 1
case api.BlkNumPending:
num = api.EthUint64(a.Chain.GetHeaviestTipSet().Height()) num = api.EthUint64(a.Chain.GetHeaviestTipSet().Height())
} }
@ -377,7 +382,7 @@ func (a *EthModule) EthChainId(ctx context.Context) (api.EthUint64, error) {
return api.EthUint64(build.Eip155ChainId), nil return api.EthUint64(build.Eip155ChainId), nil
} }
func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlkNum string, rewardPercentiles []int64) (api.EthFeeHistory, error) { func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount api.EthUint64, newestBlkNum string, rewardPercentiles []float64) (api.EthFeeHistory, error) {
if blkCount > 1024 { if blkCount > 1024 {
return api.EthFeeHistory{}, fmt.Errorf("block count should be smaller than 1024") return api.EthFeeHistory{}, fmt.Errorf("block count should be smaller than 1024")
} }
@ -497,6 +502,13 @@ func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx api.EthByte
return api.EmptyEthHash, err return api.EmptyEthHash, err
} }
_, err = a.StateAPI.StateGetActor(ctx, smsg.Message.To, types.EmptyTSK)
if err != nil {
// if actor does not exist on chain yet, set the method to 0 because
// embryos only implement method 0
smsg.Message.Method = builtin.MethodSend
}
cid, err := a.MpoolAPI.MpoolPush(ctx, smsg) cid, err := a.MpoolAPI.MpoolPush(ctx, smsg)
if err != nil { if err != nil {
return api.EmptyEthHash, err return api.EmptyEthHash, err
@ -768,6 +780,21 @@ func (a *EthModule) newEthTxFromFilecoinMessageLookup(ctx context.Context, msgLo
return api.EthTx{}, err return api.EthTx{}, err
} }
// lookup the transactionIndex
txIdx := -1
msgs, err := a.Chain.MessagesForTipset(ctx, parentTs)
if err != nil {
return api.EthTx{}, err
}
for i, msg := range msgs {
if msg.Cid() == msgLookup.Message {
txIdx = i
}
}
if txIdx == -1 {
return api.EthTx{}, fmt.Errorf("cannot find the msg in the tipset")
}
blkHash, err := api.NewEthHashFromCid(parentTsCid) blkHash, err := api.NewEthHashFromCid(parentTsCid)
if err != nil { if err != nil {
return api.EthTx{}, err return api.EthTx{}, err
@ -826,6 +853,7 @@ func (a *EthModule) newEthTxFromFilecoinMessageLookup(ctx context.Context, msgLo
To: toAddr, To: toAddr,
Value: api.EthBigInt(msg.Value), Value: api.EthBigInt(msg.Value),
Type: api.EthUint64(2), Type: api.EthUint64(2),
TransactionIndex: api.EthUint64(txIdx),
Gas: api.EthUint64(msg.GasLimit), Gas: api.EthUint64(msg.GasLimit),
MaxFeePerGas: api.EthBigInt(msg.GasFeeCap), MaxFeePerGas: api.EthBigInt(msg.GasFeeCap),
MaxPriorityFeePerGas: api.EthBigInt(msg.GasPremium), MaxPriorityFeePerGas: api.EthBigInt(msg.GasPremium),