feat: ethrpc: implement call, estimateGas, getTransactionCount (#9306)
This commit is contained in:
parent
e5bb5b7430
commit
b53d5924a1
@ -774,7 +774,7 @@ type FullNode interface {
|
|||||||
EthGetBlockByNumber(ctx context.Context, blkNum EthInt, fullTxInfo bool) (EthBlock, error) //perm:read
|
EthGetBlockByNumber(ctx context.Context, blkNum EthInt, fullTxInfo bool) (EthBlock, error) //perm:read
|
||||||
EthGetTransactionByHash(ctx context.Context, txHash EthHash) (EthTx, error) //perm:read
|
EthGetTransactionByHash(ctx context.Context, txHash EthHash) (EthTx, error) //perm:read
|
||||||
EthGetTransactionCount(ctx context.Context, sender EthAddress, blkOpt string) (EthInt, error) //perm:read
|
EthGetTransactionCount(ctx context.Context, sender EthAddress, blkOpt string) (EthInt, error) //perm:read
|
||||||
EthGetTransactionReceipt(ctx context.Context, blkHash EthHash) (EthTxReceipt, error) //perm:read
|
EthGetTransactionReceipt(ctx context.Context, txHash EthHash) (EthTxReceipt, error) //perm:read
|
||||||
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash EthHash, txIndex EthInt) (EthTx, error) //perm:read
|
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash EthHash, txIndex EthInt) (EthTx, error) //perm:read
|
||||||
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum EthInt, txIndex EthInt) (EthTx, error) //perm:read
|
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum EthInt, txIndex EthInt) (EthTx, error) //perm:read
|
||||||
|
|
||||||
@ -785,10 +785,13 @@ type FullNode interface {
|
|||||||
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) (EthInt, error) //perm:read
|
EthProtocolVersion(ctx context.Context) (EthInt, error) //perm:read
|
||||||
EthGasPrice(ctx context.Context) (EthInt, error) //perm:read
|
EthGasPrice(ctx context.Context) (EthBigInt, error) //perm:read
|
||||||
EthMaxPriorityFeePerGas(ctx context.Context) (EthInt, error) //perm:read
|
|
||||||
EthEstimateGas(ctx context.Context, tx EthCall, blkParam string) (EthInt, error) //perm:read
|
EthMaxPriorityFeePerGas(ctx context.Context) (EthBigInt, error) //perm:read
|
||||||
EthCall(ctx context.Context, tx EthCall, blkParam string) (string, error) //perm:read
|
EthEstimateGas(ctx context.Context, tx EthCall, blkParam string) (EthInt, error) //perm:read
|
||||||
|
EthCall(ctx context.Context, tx EthCall, blkParam string) (EthBytes, error) //perm:read
|
||||||
|
|
||||||
|
EthSendRawTransaction(ctx context.Context, rawTx EthBytes) (EthHash, error) //perm:read
|
||||||
|
|
||||||
// CreateBackup creates node backup onder the specified file name. The
|
// CreateBackup creates node backup onder the specified file name. The
|
||||||
// method requires that the lotus daemon is running with the
|
// method requires that the lotus daemon is running with the
|
||||||
|
130
api/eth_types.go
130
api/eth_types.go
@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
init8 "github.com/filecoin-project/go-state-types/builtin/v8/init"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
)
|
)
|
||||||
@ -70,6 +72,33 @@ func (e *EthBigInt) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EthBytes []byte
|
||||||
|
|
||||||
|
func (e EthBytes) MarshalJSON() ([]byte, error) {
|
||||||
|
encoded := "0x" + hex.EncodeToString(e)
|
||||||
|
return json.Marshal(encoded)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EthBytes) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s = strings.Replace(s, "0x", "", -1)
|
||||||
|
if len(s)%2 == 1 {
|
||||||
|
s = "0" + s
|
||||||
|
}
|
||||||
|
|
||||||
|
decoded, err := hex.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*e = decoded
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type EthBlock struct {
|
type EthBlock struct {
|
||||||
ParentHash EthHash `json:"parentHash"`
|
ParentHash EthHash `json:"parentHash"`
|
||||||
Sha3Uncles EthHash `json:"sha3Uncles"`
|
Sha3Uncles EthHash `json:"sha3Uncles"`
|
||||||
@ -116,23 +145,23 @@ func NewEthBlock() EthBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EthTx struct {
|
type EthTx struct {
|
||||||
ChainID EthInt `json:"chainId"`
|
ChainID EthInt `json:"chainId"`
|
||||||
Nonce uint64 `json:"nonce"`
|
Nonce uint64 `json:"nonce"`
|
||||||
Hash EthHash `json:"hash"`
|
Hash EthHash `json:"hash"`
|
||||||
BlockHash EthHash `json:"blockHash"`
|
BlockHash EthHash `json:"blockHash"`
|
||||||
BlockNumber EthInt `json:"blockNumber"`
|
BlockNumber EthInt `json:"blockNumber"`
|
||||||
TransactionIndex EthInt `json:"transacionIndex"`
|
TransactionIndex EthInt `json:"transacionIndex"`
|
||||||
From EthAddress `json:"from"`
|
From EthAddress `json:"from"`
|
||||||
To EthAddress `json:"to"`
|
To *EthAddress `json:"to"`
|
||||||
Value EthBigInt `json:"value"`
|
Value EthBigInt `json:"value"`
|
||||||
Type EthInt `json:"type"`
|
Type EthInt `json:"type"`
|
||||||
Input []byte `json:"input"`
|
Input EthBytes `json:"input"`
|
||||||
Gas EthInt `json:"gas"`
|
Gas EthInt `json:"gas"`
|
||||||
MaxFeePerGas EthBigInt `json:"maxFeePerGas"`
|
MaxFeePerGas EthBigInt `json:"maxFeePerGas"`
|
||||||
MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"`
|
MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"`
|
||||||
V EthBigInt `json:"v"`
|
V EthBigInt `json:"v"`
|
||||||
R EthBigInt `json:"r"`
|
R EthBigInt `json:"r"`
|
||||||
S EthBigInt `json:"s"`
|
S EthBigInt `json:"s"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type EthCall struct {
|
type EthCall struct {
|
||||||
@ -141,7 +170,7 @@ type EthCall struct {
|
|||||||
Gas EthInt `json:"gas"`
|
Gas EthInt `json:"gas"`
|
||||||
GasPrice EthBigInt `json:"gasPrice"`
|
GasPrice EthBigInt `json:"gasPrice"`
|
||||||
Value EthBigInt `json:"value"`
|
Value EthBigInt `json:"value"`
|
||||||
Data []byte `json:"data"`
|
Data EthBytes `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *EthCall) UnmarshalJSON(b []byte) error {
|
func (c *EthCall) UnmarshalJSON(b []byte) error {
|
||||||
@ -156,22 +185,71 @@ func (c *EthCall) UnmarshalJSON(b []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EthTxReceipt struct {
|
type EthTxReceipt struct {
|
||||||
TransactionHash EthHash `json:"transactionHash"`
|
TransactionHash EthHash `json:"transactionHash"`
|
||||||
TransactionIndex EthInt `json:"transacionIndex"`
|
TransactionIndex EthInt `json:"transacionIndex"`
|
||||||
BlockHash EthHash `json:"blockHash"`
|
BlockHash EthHash `json:"blockHash"`
|
||||||
BlockNumber EthHash `json:"blockNumber"`
|
BlockNumber EthInt `json:"blockNumber"`
|
||||||
From EthAddress `json:"from"`
|
From EthAddress `json:"from"`
|
||||||
To EthAddress `json:"to"`
|
To *EthAddress `json:"to"`
|
||||||
// Logs
|
// Logs
|
||||||
// LogsBloom
|
// LogsBloom
|
||||||
StateRoot EthHash `json:"root"`
|
StateRoot EthHash `json:"root"`
|
||||||
Status EthInt `json:"status"`
|
Status EthInt `json:"status"`
|
||||||
ContractAddress *EthAddress `json:"contractAddress"`
|
ContractAddress *EthAddress `json:"contractAddress"`
|
||||||
CumulativeGasUsed EthBigInt `json:"cumulativeGasUsed"`
|
CumulativeGasUsed EthInt `json:"cumulativeGasUsed"`
|
||||||
GasUsed EthBigInt `json:"gasUsed"`
|
GasUsed EthInt `json:"gasUsed"`
|
||||||
EffectiveGasPrice EthBigInt `json:"effectiveGasPrice"`
|
EffectiveGasPrice EthBigInt `json:"effectiveGasPrice"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewEthTxReceipt(tx EthTx, lookup *MsgLookup, replay *InvocResult) (EthTxReceipt, error) {
|
||||||
|
receipt := EthTxReceipt{
|
||||||
|
TransactionHash: tx.Hash,
|
||||||
|
TransactionIndex: tx.TransactionIndex,
|
||||||
|
BlockHash: tx.BlockHash,
|
||||||
|
BlockNumber: tx.BlockNumber,
|
||||||
|
From: tx.From,
|
||||||
|
To: tx.To,
|
||||||
|
StateRoot: EmptyEthHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
contractAddr, err := CheckContractCreation(lookup)
|
||||||
|
if err == nil {
|
||||||
|
receipt.To = nil
|
||||||
|
receipt.ContractAddress = contractAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
if lookup.Receipt.ExitCode.IsSuccess() {
|
||||||
|
receipt.Status = 1
|
||||||
|
}
|
||||||
|
if lookup.Receipt.ExitCode.IsError() {
|
||||||
|
receipt.Status = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
receipt.GasUsed = EthInt(lookup.Receipt.GasUsed)
|
||||||
|
|
||||||
|
// TODO: handle CumulativeGasUsed
|
||||||
|
receipt.CumulativeGasUsed = EmptyEthInt
|
||||||
|
|
||||||
|
effectiveGasPrice := big.Div(replay.GasCost.TotalCost, big.NewInt(lookup.Receipt.GasUsed))
|
||||||
|
receipt.EffectiveGasPrice = EthBigInt(effectiveGasPrice)
|
||||||
|
return receipt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckContractCreation(lookup *MsgLookup) (*EthAddress, error) {
|
||||||
|
if lookup.Receipt.ExitCode.IsError() {
|
||||||
|
return nil, xerrors.Errorf("message execution was not successful")
|
||||||
|
}
|
||||||
|
var result init8.ExecReturn
|
||||||
|
ret := bytes.NewReader(lookup.Receipt.Return)
|
||||||
|
if err := result.UnmarshalCBOR(ret); err == nil {
|
||||||
|
contractAddr, err := EthAddressFromFilecoinIDAddress(result.IDAddress)
|
||||||
|
if err == nil {
|
||||||
|
return &contractAddr, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, xerrors.Errorf("not a contract creation tx")
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ETH_ADDRESS_LENGTH = 20
|
ETH_ADDRESS_LENGTH = 20
|
||||||
ETH_HASH_LENGTH = 32
|
ETH_HASH_LENGTH = 32
|
||||||
|
@ -136,3 +136,22 @@ func TestUnmarshalEthCall(t *testing.T) {
|
|||||||
err := c.UnmarshalJSON([]byte(data))
|
err := c.UnmarshalJSON([]byte(data))
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalEthBytes(t *testing.T) {
|
||||||
|
testcases := []string{
|
||||||
|
`"0x00"`,
|
||||||
|
strings.ToLower(`"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"`),
|
||||||
|
strings.ToLower(`"0x2C2EC67e3e1FeA8e4A39601cB3A3Cd44f5fa830d"`),
|
||||||
|
strings.ToLower(`"0x01184F793982104363F9a8a5845743f452dE0586"`),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
var s EthBytes
|
||||||
|
err := s.UnmarshalJSON([]byte(tc))
|
||||||
|
require.Nil(t, err)
|
||||||
|
|
||||||
|
data, err := s.MarshalJSON()
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, string(data), tc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -952,10 +952,10 @@ func (mr *MockFullNodeMockRecorder) EthBlockNumber(arg0 interface{}) *gomock.Cal
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EthCall mocks base method.
|
// EthCall mocks base method.
|
||||||
func (m *MockFullNode) EthCall(arg0 context.Context, arg1 api.EthCall, arg2 string) (string, error) {
|
func (m *MockFullNode) EthCall(arg0 context.Context, arg1 api.EthCall, arg2 string) (api.EthBytes, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2)
|
||||||
ret0, _ := ret[0].(string)
|
ret0, _ := ret[0].(api.EthBytes)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -997,10 +997,10 @@ func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1, arg2 interface{})
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EthGasPrice mocks base method.
|
// EthGasPrice mocks base method.
|
||||||
func (m *MockFullNode) EthGasPrice(arg0 context.Context) (api.EthInt, error) {
|
func (m *MockFullNode) EthGasPrice(arg0 context.Context) (api.EthBigInt, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "EthGasPrice", arg0)
|
ret := m.ctrl.Call(m, "EthGasPrice", arg0)
|
||||||
ret0, _ := ret[0].(api.EthInt)
|
ret0, _ := ret[0].(api.EthBigInt)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -1192,10 +1192,10 @@ func (mr *MockFullNodeMockRecorder) EthGetTransactionReceipt(arg0, arg1 interfac
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EthMaxPriorityFeePerGas mocks base method.
|
// EthMaxPriorityFeePerGas mocks base method.
|
||||||
func (m *MockFullNode) EthMaxPriorityFeePerGas(arg0 context.Context) (api.EthInt, error) {
|
func (m *MockFullNode) EthMaxPriorityFeePerGas(arg0 context.Context) (api.EthBigInt, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "EthMaxPriorityFeePerGas", arg0)
|
ret := m.ctrl.Call(m, "EthMaxPriorityFeePerGas", arg0)
|
||||||
ret0, _ := ret[0].(api.EthInt)
|
ret0, _ := ret[0].(api.EthBigInt)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -1221,6 +1221,21 @@ func (mr *MockFullNodeMockRecorder) EthProtocolVersion(arg0 interface{}) *gomock
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthProtocolVersion", reflect.TypeOf((*MockFullNode)(nil).EthProtocolVersion), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthProtocolVersion", reflect.TypeOf((*MockFullNode)(nil).EthProtocolVersion), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthSendRawTransaction mocks base method.
|
||||||
|
func (m *MockFullNode) EthSendRawTransaction(arg0 context.Context, arg1 api.EthBytes) (api.EthHash, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "EthSendRawTransaction", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(api.EthHash)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthSendRawTransaction indicates an expected call of EthSendRawTransaction.
|
||||||
|
func (mr *MockFullNodeMockRecorder) EthSendRawTransaction(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSendRawTransaction", reflect.TypeOf((*MockFullNode)(nil).EthSendRawTransaction), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// GasEstimateFeeCap mocks base method.
|
// GasEstimateFeeCap mocks base method.
|
||||||
func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) {
|
func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -222,13 +222,13 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
EthBlockNumber func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthBlockNumber func(p0 context.Context) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthCall func(p0 context.Context, p1 EthCall, p2 string) (string, error) `perm:"read"`
|
EthCall func(p0 context.Context, p1 EthCall, p2 string) (EthBytes, error) `perm:"read"`
|
||||||
|
|
||||||
EthChainId func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthChainId func(p0 context.Context) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthEstimateGas func(p0 context.Context, p1 EthCall, p2 string) (EthInt, error) `perm:"read"`
|
EthEstimateGas func(p0 context.Context, p1 EthCall, p2 string) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthGasPrice func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthGasPrice func(p0 context.Context) (EthBigInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthGetBalance func(p0 context.Context, p1 EthAddress, p2 string) (EthBigInt, error) `perm:"read"`
|
EthGetBalance func(p0 context.Context, p1 EthAddress, p2 string) (EthBigInt, error) `perm:"read"`
|
||||||
|
|
||||||
@ -254,10 +254,12 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
EthGetTransactionReceipt func(p0 context.Context, p1 EthHash) (EthTxReceipt, error) `perm:"read"`
|
EthGetTransactionReceipt func(p0 context.Context, p1 EthHash) (EthTxReceipt, error) `perm:"read"`
|
||||||
|
|
||||||
EthMaxPriorityFeePerGas func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthMaxPriorityFeePerGas func(p0 context.Context) (EthBigInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthProtocolVersion func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthProtocolVersion func(p0 context.Context) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
|
EthSendRawTransaction func(p0 context.Context, p1 EthBytes) (EthHash, error) `perm:"read"`
|
||||||
|
|
||||||
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||||
|
|
||||||
GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"`
|
GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"`
|
||||||
@ -1857,15 +1859,15 @@ func (s *FullNodeStub) EthBlockNumber(p0 context.Context) (EthInt, error) {
|
|||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthCall(p0 context.Context, p1 EthCall, p2 string) (string, error) {
|
func (s *FullNodeStruct) EthCall(p0 context.Context, p1 EthCall, p2 string) (EthBytes, error) {
|
||||||
if s.Internal.EthCall == nil {
|
if s.Internal.EthCall == nil {
|
||||||
return "", ErrNotSupported
|
return *new(EthBytes), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.EthCall(p0, p1, p2)
|
return s.Internal.EthCall(p0, p1, p2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStub) EthCall(p0 context.Context, p1 EthCall, p2 string) (string, error) {
|
func (s *FullNodeStub) EthCall(p0 context.Context, p1 EthCall, p2 string) (EthBytes, error) {
|
||||||
return "", ErrNotSupported
|
return *new(EthBytes), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthChainId(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthChainId(p0 context.Context) (EthInt, error) {
|
||||||
@ -1890,15 +1892,15 @@ func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 EthCall, p2 string)
|
|||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthGasPrice(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthGasPrice(p0 context.Context) (EthBigInt, error) {
|
||||||
if s.Internal.EthGasPrice == nil {
|
if s.Internal.EthGasPrice == nil {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthBigInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.EthGasPrice(p0)
|
return s.Internal.EthGasPrice(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStub) EthGasPrice(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStub) EthGasPrice(p0 context.Context) (EthBigInt, error) {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthBigInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthGetBalance(p0 context.Context, p1 EthAddress, p2 string) (EthBigInt, error) {
|
func (s *FullNodeStruct) EthGetBalance(p0 context.Context, p1 EthAddress, p2 string) (EthBigInt, error) {
|
||||||
@ -2033,15 +2035,15 @@ func (s *FullNodeStub) EthGetTransactionReceipt(p0 context.Context, p1 EthHash)
|
|||||||
return *new(EthTxReceipt), ErrNotSupported
|
return *new(EthTxReceipt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthMaxPriorityFeePerGas(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthMaxPriorityFeePerGas(p0 context.Context) (EthBigInt, error) {
|
||||||
if s.Internal.EthMaxPriorityFeePerGas == nil {
|
if s.Internal.EthMaxPriorityFeePerGas == nil {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthBigInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
return s.Internal.EthMaxPriorityFeePerGas(p0)
|
return s.Internal.EthMaxPriorityFeePerGas(p0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStub) EthMaxPriorityFeePerGas(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStub) EthMaxPriorityFeePerGas(p0 context.Context) (EthBigInt, error) {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthBigInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthProtocolVersion(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthProtocolVersion(p0 context.Context) (EthInt, error) {
|
||||||
@ -2055,6 +2057,17 @@ func (s *FullNodeStub) EthProtocolVersion(p0 context.Context) (EthInt, error) {
|
|||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStruct) EthSendRawTransaction(p0 context.Context, p1 EthBytes) (EthHash, error) {
|
||||||
|
if s.Internal.EthSendRawTransaction == nil {
|
||||||
|
return *new(EthHash), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.EthSendRawTransaction(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) EthSendRawTransaction(p0 context.Context, p1 EthBytes) (EthHash, error) {
|
||||||
|
return *new(EthHash), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) {
|
func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) {
|
||||||
if s.Internal.GasEstimateFeeCap == nil {
|
if s.Internal.GasEstimateFeeCap == nil {
|
||||||
return *new(types.BigInt), ErrNotSupported
|
return *new(types.BigInt), ErrNotSupported
|
||||||
|
@ -86,6 +86,7 @@
|
|||||||
* [EthGetTransactionReceipt](#EthGetTransactionReceipt)
|
* [EthGetTransactionReceipt](#EthGetTransactionReceipt)
|
||||||
* [EthMaxPriorityFeePerGas](#EthMaxPriorityFeePerGas)
|
* [EthMaxPriorityFeePerGas](#EthMaxPriorityFeePerGas)
|
||||||
* [EthProtocolVersion](#EthProtocolVersion)
|
* [EthProtocolVersion](#EthProtocolVersion)
|
||||||
|
* [EthSendRawTransaction](#EthSendRawTransaction)
|
||||||
* [Gas](#Gas)
|
* [Gas](#Gas)
|
||||||
* [GasEstimateFeeCap](#GasEstimateFeeCap)
|
* [GasEstimateFeeCap](#GasEstimateFeeCap)
|
||||||
* [GasEstimateGasLimit](#GasEstimateGasLimit)
|
* [GasEstimateGasLimit](#GasEstimateGasLimit)
|
||||||
@ -2189,13 +2190,13 @@ Inputs:
|
|||||||
"gas": "0x5",
|
"gas": "0x5",
|
||||||
"gasPrice": "0x0",
|
"gasPrice": "0x0",
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"data": "Ynl0ZSBhcnJheQ=="
|
"data": "0x07"
|
||||||
},
|
},
|
||||||
"string value"
|
"string value"
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
Response: `"string value"`
|
Response: `"0x07"`
|
||||||
|
|
||||||
### EthChainId
|
### EthChainId
|
||||||
|
|
||||||
@ -2220,7 +2221,7 @@ Inputs:
|
|||||||
"gas": "0x5",
|
"gas": "0x5",
|
||||||
"gasPrice": "0x0",
|
"gasPrice": "0x0",
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"data": "Ynl0ZSBhcnJheQ=="
|
"data": "0x07"
|
||||||
},
|
},
|
||||||
"string value"
|
"string value"
|
||||||
]
|
]
|
||||||
@ -2235,7 +2236,7 @@ Perms: read
|
|||||||
|
|
||||||
Inputs: `null`
|
Inputs: `null`
|
||||||
|
|
||||||
Response: `"0x5"`
|
Response: `"0x0"`
|
||||||
|
|
||||||
### EthGetBalance
|
### EthGetBalance
|
||||||
|
|
||||||
@ -2417,10 +2418,10 @@ Response:
|
|||||||
"blockNumber": "0x5",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"type": "0x5",
|
"type": "0x5",
|
||||||
"input": "Ynl0ZSBhcnJheQ==",
|
"input": "0x07",
|
||||||
"gas": "0x5",
|
"gas": "0x5",
|
||||||
"maxFeePerGas": "0x0",
|
"maxFeePerGas": "0x0",
|
||||||
"maxPriorityFeePerGas": "0x0",
|
"maxPriorityFeePerGas": "0x0",
|
||||||
@ -2453,10 +2454,10 @@ Response:
|
|||||||
"blockNumber": "0x5",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"type": "0x5",
|
"type": "0x5",
|
||||||
"input": "Ynl0ZSBhcnJheQ==",
|
"input": "0x07",
|
||||||
"gas": "0x5",
|
"gas": "0x5",
|
||||||
"maxFeePerGas": "0x0",
|
"maxFeePerGas": "0x0",
|
||||||
"maxPriorityFeePerGas": "0x0",
|
"maxPriorityFeePerGas": "0x0",
|
||||||
@ -2488,10 +2489,10 @@ Response:
|
|||||||
"blockNumber": "0x5",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
||||||
"value": "0x0",
|
"value": "0x0",
|
||||||
"type": "0x5",
|
"type": "0x5",
|
||||||
"input": "Ynl0ZSBhcnJheQ==",
|
"input": "0x07",
|
||||||
"gas": "0x5",
|
"gas": "0x5",
|
||||||
"maxFeePerGas": "0x0",
|
"maxFeePerGas": "0x0",
|
||||||
"maxPriorityFeePerGas": "0x0",
|
"maxPriorityFeePerGas": "0x0",
|
||||||
@ -2534,14 +2535,14 @@ Response:
|
|||||||
"transactionHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"transactionHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockNumber": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
||||||
"root": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"root": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"status": "0x5",
|
"status": "0x5",
|
||||||
"contractAddress": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
"contractAddress": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
|
||||||
"cumulativeGasUsed": "0x0",
|
"cumulativeGasUsed": "0x5",
|
||||||
"gasUsed": "0x0",
|
"gasUsed": "0x5",
|
||||||
"effectiveGasPrice": "0x0"
|
"effectiveGasPrice": "0x0"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -2553,7 +2554,7 @@ Perms: read
|
|||||||
|
|
||||||
Inputs: `null`
|
Inputs: `null`
|
||||||
|
|
||||||
Response: `"0x5"`
|
Response: `"0x0"`
|
||||||
|
|
||||||
### EthProtocolVersion
|
### EthProtocolVersion
|
||||||
|
|
||||||
@ -2564,6 +2565,20 @@ Inputs: `null`
|
|||||||
|
|
||||||
Response: `"0x5"`
|
Response: `"0x5"`
|
||||||
|
|
||||||
|
### EthSendRawTransaction
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"0x07"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response: `"0x0707070707070707070707070707070707070707070707070707070707070707"`
|
||||||
|
|
||||||
## Gas
|
## Gas
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,11 +8,17 @@ import (
|
|||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
"github.com/filecoin-project/go-state-types/exitcode"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EthModuleAPI interface {
|
type EthModuleAPI interface {
|
||||||
@ -24,7 +30,7 @@ type EthModuleAPI interface {
|
|||||||
EthGetBlockByNumber(ctx context.Context, blkNum api.EthInt, fullTxInfo bool) (api.EthBlock, error)
|
EthGetBlockByNumber(ctx context.Context, blkNum api.EthInt, fullTxInfo bool) (api.EthBlock, error)
|
||||||
EthGetTransactionByHash(ctx context.Context, txHash api.EthHash) (api.EthTx, error)
|
EthGetTransactionByHash(ctx context.Context, txHash api.EthHash) (api.EthTx, error)
|
||||||
EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkOpt string) (api.EthInt, error)
|
EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkOpt string) (api.EthInt, error)
|
||||||
EthGetTransactionReceipt(ctx context.Context, blkHash api.EthHash) (api.EthTxReceipt, error)
|
EthGetTransactionReceipt(ctx context.Context, txHash api.EthHash) (api.EthTxReceipt, error)
|
||||||
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthInt) (api.EthTx, error)
|
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthInt) (api.EthTx, error)
|
||||||
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum api.EthInt, txIndex api.EthInt) (api.EthTx, error)
|
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum api.EthInt, txIndex api.EthInt) (api.EthTx, error)
|
||||||
EthGetCode(ctx context.Context, address api.EthAddress) (string, error)
|
EthGetCode(ctx context.Context, address api.EthAddress) (string, error)
|
||||||
@ -34,11 +40,11 @@ type EthModuleAPI interface {
|
|||||||
NetVersion(ctx context.Context) (string, error)
|
NetVersion(ctx context.Context) (string, error)
|
||||||
NetListening(ctx context.Context) (bool, error)
|
NetListening(ctx context.Context) (bool, error)
|
||||||
EthProtocolVersion(ctx context.Context) (api.EthInt, error)
|
EthProtocolVersion(ctx context.Context) (api.EthInt, error)
|
||||||
EthGasPrice(ctx context.Context) (api.EthInt, error)
|
EthGasPrice(ctx context.Context) (api.EthBigInt, error)
|
||||||
EthEstimateGas(ctx context.Context, tx api.EthCall, blkParam string) (api.EthInt, error)
|
EthEstimateGas(ctx context.Context, tx api.EthCall, blkParam string) (api.EthInt, error)
|
||||||
EthCall(ctx context.Context, tx api.EthCall, blkParam string) (string, error)
|
EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error)
|
||||||
EthMaxPriorityFeePerGas(ctx context.Context) (api.EthInt, error)
|
EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error)
|
||||||
// EthSendRawTransaction(ctx context.Context, tx api.EthTx) (api.EthHash, error)
|
EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ EthModuleAPI = *new(api.FullNode)
|
var _ EthModuleAPI = *new(api.FullNode)
|
||||||
@ -49,9 +55,12 @@ var _ EthModuleAPI = *new(api.FullNode)
|
|||||||
type EthModule struct {
|
type EthModule struct {
|
||||||
fx.In
|
fx.In
|
||||||
|
|
||||||
Chain *store.ChainStore
|
Chain *store.ChainStore
|
||||||
|
Mpool *messagepool.MessagePool
|
||||||
|
StateManager *stmgr.StateManager
|
||||||
|
|
||||||
ChainAPI
|
ChainAPI
|
||||||
|
MpoolAPI
|
||||||
StateAPI
|
StateAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +74,10 @@ type EthAPI struct {
|
|||||||
EthModuleAPI
|
EthModuleAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *EthModule) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
||||||
|
return stmgr.GetNetworkName(ctx, a.StateManager, a.Chain.GetHeaviestTipSet().ParentState())
|
||||||
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthBlockNumber(context.Context) (api.EthInt, error) {
|
func (a *EthModule) EthBlockNumber(context.Context) (api.EthInt, error) {
|
||||||
height := a.Chain.GetHeaviestTipSet().Height()
|
height := a.Chain.GetHeaviestTipSet().Height()
|
||||||
return api.EthInt(height), nil
|
return api.EthInt(height), nil
|
||||||
@ -140,11 +153,40 @@ func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash api.EthH
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkParam string) (api.EthInt, error) {
|
func (a *EthModule) EthGetTransactionCount(ctx context.Context, sender api.EthAddress, blkParam string) (api.EthInt, error) {
|
||||||
return api.EthInt(0), nil
|
addr, err := sender.ToFilecoinAddress()
|
||||||
|
if err != nil {
|
||||||
|
return api.EthInt(0), err
|
||||||
|
}
|
||||||
|
nonce, err := a.Mpool.GetNonce(ctx, addr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthInt(0), err
|
||||||
|
}
|
||||||
|
return api.EthInt(nonce), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetTransactionReceipt(ctx context.Context, blkHash api.EthHash) (api.EthTxReceipt, error) {
|
func (a *EthModule) EthGetTransactionReceipt(ctx context.Context, txHash api.EthHash) (api.EthTxReceipt, error) {
|
||||||
return api.EthTxReceipt{}, nil
|
cid := txHash.ToCid()
|
||||||
|
|
||||||
|
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, cid, api.LookbackNoLimit, true)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := a.ethTxFromFilecoinMessageLookup(ctx, msgLookup)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
replay, err := a.StateAPI.StateReplay(ctx, types.EmptyTSK, cid)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
receipt, err := api.NewEthTxReceipt(tx, msgLookup, replay)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTxReceipt{}, err
|
||||||
|
}
|
||||||
|
return receipt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthInt) (api.EthTx, error) {
|
func (a *EthModule) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash api.EthHash, txIndex api.EthInt) (api.EthTx, error) {
|
||||||
@ -196,27 +238,98 @@ func (a *EthModule) NetListening(ctx context.Context) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthProtocolVersion(ctx context.Context) (api.EthInt, error) {
|
func (a *EthModule) EthProtocolVersion(ctx context.Context) (api.EthInt, error) {
|
||||||
return api.EthInt(0), nil
|
height := a.Chain.GetHeaviestTipSet().Height()
|
||||||
|
return api.EthInt(a.StateManager.GetNetworkVersion(ctx, height)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthMaxPriorityFeePerGas(ctx context.Context) (api.EthInt, error) {
|
func (a *EthModule) EthMaxPriorityFeePerGas(ctx context.Context) (api.EthBigInt, error) {
|
||||||
return api.EthInt(0), nil
|
gasPremium, err := a.GasAPI.GasEstimateGasPremium(ctx, 0, builtin.SystemActorAddr, 10000, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBigInt(big.Zero()), err
|
||||||
|
}
|
||||||
|
return api.EthBigInt(gasPremium), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGasPrice(ctx context.Context) (api.EthInt, error) {
|
func (a *EthModule) EthGasPrice(ctx context.Context) (api.EthBigInt, error) {
|
||||||
return api.EthInt(0), nil
|
// According to Geth's implementation, eth_gasPrice should return base + tip
|
||||||
|
// Ref: https://github.com/ethereum/pm/issues/328#issuecomment-853234014
|
||||||
|
|
||||||
|
ts := a.Chain.GetHeaviestTipSet()
|
||||||
|
baseFee := ts.Blocks()[0].ParentBaseFee
|
||||||
|
|
||||||
|
premium, err := a.EthMaxPriorityFeePerGas(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBigInt(big.Zero()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gasPrice := big.Add(baseFee, big.Int(premium))
|
||||||
|
return api.EthBigInt(gasPrice), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (a *EthModule) EthSendRawTransaction(ctx context.Context tx api.EthTx) (api.EthHash, error) {
|
func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx api.EthBytes) (api.EthHash, error) {
|
||||||
// return api.EthHash{}, nil
|
return api.EthHash{}, nil
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
func (a *EthModule) applyEvmMsg(ctx context.Context, tx api.EthCall) (*api.InvocResult, error) {
|
||||||
|
from, err := tx.From.ToFilecoinAddress()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
to, err := tx.To.ToFilecoinAddress()
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
|
||||||
|
}
|
||||||
|
msg := &types.Message{
|
||||||
|
From: from,
|
||||||
|
To: to,
|
||||||
|
Value: big.Int(tx.Value),
|
||||||
|
Method: abi.MethodNum(2),
|
||||||
|
Params: tx.Data,
|
||||||
|
GasLimit: build.BlockGasLimit,
|
||||||
|
GasFeeCap: big.Zero(),
|
||||||
|
GasPremium: big.Zero(),
|
||||||
|
}
|
||||||
|
ts := a.Chain.GetHeaviestTipSet()
|
||||||
|
|
||||||
|
// Try calling until we find a height with no migration.
|
||||||
|
var res *api.InvocResult
|
||||||
|
for {
|
||||||
|
res, err = a.StateManager.CallWithGas(ctx, msg, []types.ChainMsg{}, ts)
|
||||||
|
if err != stmgr.ErrExpensiveFork {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
ts, err = a.Chain.GetTipSetFromKey(ctx, ts.Parents())
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("getting parent tipset: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("CallWithGas failed: %w", err)
|
||||||
|
}
|
||||||
|
if res.MsgRct.ExitCode != exitcode.Ok {
|
||||||
|
return nil, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error)
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthEstimateGas(ctx context.Context, tx api.EthCall, blkParam string) (api.EthInt, error) {
|
func (a *EthModule) EthEstimateGas(ctx context.Context, tx api.EthCall, blkParam string) (api.EthInt, error) {
|
||||||
return api.EthInt(0), nil
|
invokeResult, err := a.applyEvmMsg(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthInt(0), err
|
||||||
|
}
|
||||||
|
ret := invokeResult.MsgRct.GasUsed
|
||||||
|
return api.EthInt(ret), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthCall(ctx context.Context, tx api.EthCall, blkParam string) (string, error) {
|
func (a *EthModule) EthCall(ctx context.Context, tx api.EthCall, blkParam string) (api.EthBytes, error) {
|
||||||
return "", nil
|
invokeResult, err := a.applyEvmMsg(ctx, tx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(invokeResult.MsgRct.Return) > 0 {
|
||||||
|
return api.EthBytes(invokeResult.MsgRct.Return), nil
|
||||||
|
}
|
||||||
|
return api.EthBytes{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) ethBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool) (api.EthBlock, error) {
|
func (a *EthModule) ethBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool) (api.EthBlock, error) {
|
||||||
@ -306,7 +419,7 @@ func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLooku
|
|||||||
return api.EthTx{}, err
|
return api.EthTx{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
toFilAddr, err := a.StateAPI.StateLookupID(ctx, msg.From, types.EmptyTSK)
|
toFilAddr, err := a.StateAPI.StateLookupID(ctx, msg.To, types.EmptyTSK)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return api.EthTx{}, err
|
return api.EthTx{}, err
|
||||||
}
|
}
|
||||||
@ -316,13 +429,19 @@ func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLooku
|
|||||||
return api.EthTx{}, err
|
return api.EthTx{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toAddr := &toEthAddr
|
||||||
|
_, err = api.CheckContractCreation(msgLookup)
|
||||||
|
if err == nil {
|
||||||
|
toAddr = nil
|
||||||
|
}
|
||||||
|
|
||||||
tx := api.EthTx{
|
tx := api.EthTx{
|
||||||
ChainID: api.EthInt(build.Eip155ChainId),
|
ChainID: api.EthInt(build.Eip155ChainId),
|
||||||
Hash: txHash,
|
Hash: txHash,
|
||||||
BlockHash: blkHash,
|
BlockHash: blkHash,
|
||||||
BlockNumber: api.EthInt(msgLookup.Height),
|
BlockNumber: api.EthInt(msgLookup.Height),
|
||||||
From: fromEthAddr,
|
From: fromEthAddr,
|
||||||
To: toEthAddr,
|
To: toAddr,
|
||||||
Value: api.EthBigInt(msg.Value),
|
Value: api.EthBigInt(msg.Value),
|
||||||
Type: api.EthInt(2),
|
Type: api.EthInt(2),
|
||||||
Gas: api.EthInt(msg.GasLimit),
|
Gas: api.EthInt(msg.GasLimit),
|
||||||
@ -331,7 +450,7 @@ func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLooku
|
|||||||
V: api.EthBigIntZero,
|
V: api.EthBigIntZero,
|
||||||
R: api.EthBigIntZero,
|
R: api.EthBigIntZero,
|
||||||
S: api.EthBigIntZero,
|
S: api.EthBigIntZero,
|
||||||
// TODO: Input:
|
Input: msg.Params,
|
||||||
}
|
}
|
||||||
return tx, nil
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user