feat: ethrpc: implement EthBlock and EthTx structs (#9287)
Co-authored-by: Raúl Kripalani <raul@protocol.ai>
This commit is contained in:
parent
4652d8559f
commit
e5bb5b7430
@ -785,9 +785,10 @@ 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
|
||||||
EthMaxPriorityFeePerGas(ctx context.Context) (EthInt, error) //perm:read
|
|
||||||
EthGasPrice(ctx context.Context) (EthInt, error) //perm:read
|
EthGasPrice(ctx context.Context) (EthInt, error) //perm:read
|
||||||
// EthSendRawTransaction(ctx context.Context, tx api.EthTx) (EthHash, error) //perm:write
|
EthMaxPriorityFeePerGas(ctx context.Context) (EthInt, error) //perm:read
|
||||||
|
EthEstimateGas(ctx context.Context, tx EthCall, blkParam string) (EthInt, error) //perm:read
|
||||||
|
EthCall(ctx context.Context, tx EthCall, blkParam string) (string, 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
|
||||||
|
102
api/eth_types.go
102
api/eth_types.go
@ -5,15 +5,18 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
mathbig "math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/multiformats/go-multihash"
|
"github.com/multiformats/go-multihash"
|
||||||
xerrors "golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"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"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
)
|
)
|
||||||
|
|
||||||
type EthInt int64
|
type EthInt int64
|
||||||
@ -32,12 +35,16 @@ func (e *EthInt) UnmarshalJSON(b []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
eint := EthInt(parsedInt)
|
eint := EthInt(parsedInt)
|
||||||
e = &eint
|
*e = eint
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type EthBigInt big.Int
|
type EthBigInt big.Int
|
||||||
|
|
||||||
|
var (
|
||||||
|
EthBigIntZero = EthBigInt{Int: big.Zero().Int}
|
||||||
|
)
|
||||||
|
|
||||||
func (e EthBigInt) MarshalJSON() ([]byte, error) {
|
func (e EthBigInt) MarshalJSON() ([]byte, error) {
|
||||||
if e.Int == nil {
|
if e.Int == nil {
|
||||||
return json.Marshal("0x0")
|
return json.Marshal("0x0")
|
||||||
@ -45,6 +52,24 @@ func (e EthBigInt) MarshalJSON() ([]byte, error) {
|
|||||||
return json.Marshal(fmt.Sprintf("0x%x", e.Int))
|
return json.Marshal(fmt.Sprintf("0x%x", e.Int))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *EthBigInt) UnmarshalJSON(b []byte) error {
|
||||||
|
var s string
|
||||||
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
replaced := strings.Replace(s, "0x", "", -1)
|
||||||
|
if len(replaced)%2 == 1 {
|
||||||
|
replaced = "0" + replaced
|
||||||
|
}
|
||||||
|
|
||||||
|
i := new(mathbig.Int)
|
||||||
|
i.SetString(replaced, 16)
|
||||||
|
|
||||||
|
*e = EthBigInt(big.NewFromGo(i))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type EthBlock struct {
|
type EthBlock struct {
|
||||||
ParentHash EthHash `json:"parentHash"`
|
ParentHash EthHash `json:"parentHash"`
|
||||||
Sha3Uncles EthHash `json:"sha3Uncles"`
|
Sha3Uncles EthHash `json:"sha3Uncles"`
|
||||||
@ -53,24 +78,49 @@ type EthBlock struct {
|
|||||||
TransactionsRoot EthHash `json:"transactionsRoot"`
|
TransactionsRoot EthHash `json:"transactionsRoot"`
|
||||||
ReceiptsRoot EthHash `json:"receiptsRoot"`
|
ReceiptsRoot EthHash `json:"receiptsRoot"`
|
||||||
// TODO: include LogsBloom
|
// TODO: include LogsBloom
|
||||||
Difficulty EthInt `json:"difficulty"`
|
Difficulty EthInt `json:"difficulty"`
|
||||||
Number EthInt `json:"number"`
|
Number EthInt `json:"number"`
|
||||||
GasLimit EthInt `json:"gasLimit"`
|
GasLimit EthInt `json:"gasLimit"`
|
||||||
GasUsed EthInt `json:"gasUsed"`
|
GasUsed EthInt `json:"gasUsed"`
|
||||||
Timestamp EthInt `json:"timestamp"`
|
Timestamp EthInt `json:"timestamp"`
|
||||||
Extradata []byte `json:"extraData"`
|
Extradata []byte `json:"extraData"`
|
||||||
MixHash EthHash `json:"mixHash"`
|
MixHash EthHash `json:"mixHash"`
|
||||||
Nonce EthNonce `json:"nonce"`
|
Nonce EthNonce `json:"nonce"`
|
||||||
BaseFeePerGas EthInt `json:"baseFeePerGas"`
|
BaseFeePerGas EthBigInt `json:"baseFeePerGas"`
|
||||||
Transactions EthTx `json:"transactions"`
|
Size EthInt `json:"size"`
|
||||||
|
// can be []EthTx or []string depending on query params
|
||||||
|
Transactions []interface{} `json:"transactions"`
|
||||||
|
Uncles []EthHash `json:"uncles"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
EmptyEthHash = EthHash{}
|
||||||
|
EmptyEthInt = EthInt(0)
|
||||||
|
EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewEthBlock() EthBlock {
|
||||||
|
return EthBlock{
|
||||||
|
Sha3Uncles: EmptyEthHash,
|
||||||
|
StateRoot: EmptyEthHash,
|
||||||
|
TransactionsRoot: EmptyEthHash,
|
||||||
|
ReceiptsRoot: EmptyEthHash,
|
||||||
|
Difficulty: EmptyEthInt,
|
||||||
|
Extradata: []byte{},
|
||||||
|
MixHash: EmptyEthHash,
|
||||||
|
Nonce: EmptyEthNonce,
|
||||||
|
GasLimit: EthInt(build.BlockGasLimit), // TODO we map Ethereum blocks to Filecoin tipsets; this is inconsistent.
|
||||||
|
Uncles: []EthHash{},
|
||||||
|
Transactions: []interface{}{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 EthHash `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"`
|
||||||
@ -85,6 +135,26 @@ type EthTx struct {
|
|||||||
S EthBigInt `json:"s"`
|
S EthBigInt `json:"s"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EthCall struct {
|
||||||
|
From EthAddress `json:"from"`
|
||||||
|
To EthAddress `json:"to"`
|
||||||
|
Gas EthInt `json:"gas"`
|
||||||
|
GasPrice EthBigInt `json:"gasPrice"`
|
||||||
|
Value EthBigInt `json:"value"`
|
||||||
|
Data []byte `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *EthCall) UnmarshalJSON(b []byte) error {
|
||||||
|
type TempEthCall EthCall
|
||||||
|
var params TempEthCall
|
||||||
|
|
||||||
|
if err := json.Unmarshal(b, ¶ms); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*c = EthCall(params)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type EthTxReceipt struct {
|
type EthTxReceipt struct {
|
||||||
TransactionHash EthHash `json:"transactionHash"`
|
TransactionHash EthHash `json:"transactionHash"`
|
||||||
TransactionIndex EthInt `json:"transacionIndex"`
|
TransactionIndex EthInt `json:"transacionIndex"`
|
||||||
@ -136,7 +206,7 @@ func (a *EthAddress) UnmarshalJSON(b []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
a = &addr
|
copy(a[:], addr[:])
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +255,7 @@ func (h *EthHash) UnmarshalJSON(b []byte) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
h = &hash
|
copy(h[:], hash[:])
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,20 @@ func TestEthIntMarshalJSON(t *testing.T) {
|
|||||||
require.Equal(t, j, tc.Output)
|
require.Equal(t, j, tc.Output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func TestEthIntUnmarshalJSON(t *testing.T) {
|
||||||
|
testcases := []TestCase{
|
||||||
|
{[]byte("\"0x0\""), EthInt(0)},
|
||||||
|
{[]byte("\"0x41\""), EthInt(65)},
|
||||||
|
{[]byte("\"0x400\""), EthInt(1024)},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
var i EthInt
|
||||||
|
err := i.UnmarshalJSON(tc.Input.([]byte))
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, i, tc.Output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEthBigIntMarshalJSON(t *testing.T) {
|
func TestEthBigIntMarshalJSON(t *testing.T) {
|
||||||
testcases := []TestCase{
|
testcases := []TestCase{
|
||||||
@ -45,16 +59,34 @@ func TestEthBigIntMarshalJSON(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEthBigIntUnmarshalJSON(t *testing.T) {
|
||||||
|
testcases := []TestCase{
|
||||||
|
{[]byte("\"0x0\""), EthBigInt(big.MustFromString("0"))},
|
||||||
|
{[]byte("\"0x41\""), EthBigInt(big.MustFromString("65"))},
|
||||||
|
{[]byte("\"0x400\""), EthBigInt(big.MustFromString("1024"))},
|
||||||
|
{[]byte("\"0xff1000000000000000000000000\""), EthBigInt(big.MustFromString("323330131220712761719252861321216"))},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testcases {
|
||||||
|
var i EthBigInt
|
||||||
|
err := i.UnmarshalJSON(tc.Input.([]byte))
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, i, tc.Output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEthHash(t *testing.T) {
|
func TestEthHash(t *testing.T) {
|
||||||
testcases := []string{
|
testcases := []string{
|
||||||
"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184",
|
`"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`,
|
||||||
"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738",
|
`"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, hash := range testcases {
|
for _, hash := range testcases {
|
||||||
h, err := EthHashFromHex(hash)
|
var h EthHash
|
||||||
|
err := h.UnmarshalJSON([]byte(hash))
|
||||||
|
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, h.String(), hash)
|
require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1))
|
||||||
|
|
||||||
c := h.ToCid()
|
c := h.ToCid()
|
||||||
h1, err := EthHashFromCid(c)
|
h1, err := EthHashFromCid(c)
|
||||||
@ -65,15 +97,17 @@ func TestEthHash(t *testing.T) {
|
|||||||
|
|
||||||
func TestEthAddr(t *testing.T) {
|
func TestEthAddr(t *testing.T) {
|
||||||
testcases := []string{
|
testcases := []string{
|
||||||
strings.ToLower("0xd4c5fb16488Aa48081296299d54b0c648C9333dA"),
|
strings.ToLower(`"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"`),
|
||||||
strings.ToLower("0x2C2EC67e3e1FeA8e4A39601cB3A3Cd44f5fa830d"),
|
strings.ToLower(`"0x2C2EC67e3e1FeA8e4A39601cB3A3Cd44f5fa830d"`),
|
||||||
strings.ToLower("0x01184F793982104363F9a8a5845743f452dE0586"),
|
strings.ToLower(`"0x01184F793982104363F9a8a5845743f452dE0586"`),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, addr := range testcases {
|
for _, addr := range testcases {
|
||||||
a, err := EthAddressFromHex(addr)
|
var a EthAddress
|
||||||
|
err := a.UnmarshalJSON([]byte(addr))
|
||||||
|
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Equal(t, a.String(), addr)
|
require.Equal(t, a.String(), strings.Replace(addr, `"`, "", -1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,3 +128,11 @@ func TestParseEthAddr(t *testing.T) {
|
|||||||
require.Equal(t, addr, faddr)
|
require.Equal(t, addr, faddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalEthCall(t *testing.T) {
|
||||||
|
data := `{"from":"0x4D6D86b31a112a05A473c4aE84afaF873f632325","to":"0xFe01CC39f5Ae8553D6914DBb9dC27D219fa22D7f","gas":"0x5","gasPrice":"0x6","value":"0x123","data":""}`
|
||||||
|
|
||||||
|
var c EthCall
|
||||||
|
err := c.UnmarshalJSON([]byte(data))
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
||||||
|
@ -951,6 +951,21 @@ func (mr *MockFullNodeMockRecorder) EthBlockNumber(arg0 interface{}) *gomock.Cal
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthBlockNumber", reflect.TypeOf((*MockFullNode)(nil).EthBlockNumber), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthBlockNumber", reflect.TypeOf((*MockFullNode)(nil).EthBlockNumber), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthCall mocks base method.
|
||||||
|
func (m *MockFullNode) EthCall(arg0 context.Context, arg1 api.EthCall, arg2 string) (string, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(string)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthCall indicates an expected call of EthCall.
|
||||||
|
func (mr *MockFullNodeMockRecorder) EthCall(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthCall", reflect.TypeOf((*MockFullNode)(nil).EthCall), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
// EthChainId mocks base method.
|
// EthChainId mocks base method.
|
||||||
func (m *MockFullNode) EthChainId(arg0 context.Context) (api.EthInt, error) {
|
func (m *MockFullNode) EthChainId(arg0 context.Context) (api.EthInt, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@ -966,6 +981,21 @@ func (mr *MockFullNodeMockRecorder) EthChainId(arg0 interface{}) *gomock.Call {
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthChainId", reflect.TypeOf((*MockFullNode)(nil).EthChainId), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthChainId", reflect.TypeOf((*MockFullNode)(nil).EthChainId), arg0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EthEstimateGas mocks base method.
|
||||||
|
func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 api.EthCall, arg2 string) (api.EthInt, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1, arg2)
|
||||||
|
ret0, _ := ret[0].(api.EthInt)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// EthEstimateGas indicates an expected call of EthEstimateGas.
|
||||||
|
func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1, arg2)
|
||||||
|
}
|
||||||
|
|
||||||
// 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.EthInt, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -222,9 +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"`
|
||||||
|
|
||||||
EthChainId func(p0 context.Context) (EthInt, error) `perm:"read"`
|
EthChainId func(p0 context.Context) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
EthGasPrice func(p0 context.Context) (EthInt, error) ``
|
EthEstimateGas func(p0 context.Context, p1 EthCall, p2 string) (EthInt, error) `perm:"read"`
|
||||||
|
|
||||||
|
EthGasPrice func(p0 context.Context) (EthInt, 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"`
|
||||||
|
|
||||||
@ -1853,6 +1857,17 @@ 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) {
|
||||||
|
if s.Internal.EthCall == nil {
|
||||||
|
return "", ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.EthCall(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) EthCall(p0 context.Context, p1 EthCall, p2 string) (string, error) {
|
||||||
|
return "", ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthChainId(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthChainId(p0 context.Context) (EthInt, error) {
|
||||||
if s.Internal.EthChainId == nil {
|
if s.Internal.EthChainId == nil {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
@ -1864,6 +1879,17 @@ func (s *FullNodeStub) EthChainId(p0 context.Context) (EthInt, error) {
|
|||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 EthCall, p2 string) (EthInt, error) {
|
||||||
|
if s.Internal.EthEstimateGas == nil {
|
||||||
|
return *new(EthInt), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.EthEstimateGas(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 EthCall, p2 string) (EthInt, error) {
|
||||||
|
return *new(EthInt), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) EthGasPrice(p0 context.Context) (EthInt, error) {
|
func (s *FullNodeStruct) EthGasPrice(p0 context.Context) (EthInt, error) {
|
||||||
if s.Internal.EthGasPrice == nil {
|
if s.Internal.EthGasPrice == nil {
|
||||||
return *new(EthInt), ErrNotSupported
|
return *new(EthInt), ErrNotSupported
|
||||||
|
@ -131,4 +131,8 @@ const InteractivePoRepConfidence = 6
|
|||||||
|
|
||||||
const BootstrapPeerThreshold = 1
|
const BootstrapPeerThreshold = 1
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 31415926
|
||||||
|
|
||||||
var WhitelistedBlock = cid.Undef
|
var WhitelistedBlock = cid.Undef
|
||||||
|
@ -81,4 +81,8 @@ const PropagationDelaySecs = uint64(6)
|
|||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 2
|
const BootstrapPeerThreshold = 2
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 3141592
|
||||||
|
|
||||||
var WhitelistedBlock = cid.Undef
|
var WhitelistedBlock = cid.Undef
|
||||||
|
@ -114,4 +114,8 @@ var PropagationDelaySecs = uint64(10)
|
|||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 4
|
const BootstrapPeerThreshold = 4
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 314159
|
||||||
|
|
||||||
var WhitelistedBlock = cid.Undef
|
var WhitelistedBlock = cid.Undef
|
||||||
|
@ -119,4 +119,9 @@ const PropagationDelaySecs = uint64(6)
|
|||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 2
|
const BootstrapPeerThreshold = 2
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
// TODO same as butterfly for now, as we didn't submit an assignment for interopnet.
|
||||||
|
const Eip155ChainId = 3141592
|
||||||
|
|
||||||
var WhitelistedBlock = cid.Undef
|
var WhitelistedBlock = cid.Undef
|
||||||
|
@ -127,5 +127,9 @@ const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
|
|||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 4
|
const BootstrapPeerThreshold = 4
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 314
|
||||||
|
|
||||||
// we skip checks on message validity in this block to sidestep the zero-bls signature
|
// we skip checks on message validity in this block to sidestep the zero-bls signature
|
||||||
var WhitelistedBlock = MustParseCid("bafy2bzaceapyg2uyzk7vueh3xccxkuwbz3nxewjyguoxvhx77malc2lzn2ybi")
|
var WhitelistedBlock = MustParseCid("bafy2bzaceapyg2uyzk7vueh3xccxkuwbz3nxewjyguoxvhx77malc2lzn2ybi")
|
||||||
|
@ -130,3 +130,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const BootstrapPeerThreshold = 1
|
const BootstrapPeerThreshold = 1
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 31415926
|
||||||
|
@ -85,4 +85,8 @@ const PropagationDelaySecs = uint64(6)
|
|||||||
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
|
||||||
const BootstrapPeerThreshold = 2
|
const BootstrapPeerThreshold = 2
|
||||||
|
|
||||||
|
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
|
||||||
|
// As per https://github.com/ethereum-lists/chains
|
||||||
|
const Eip155ChainId = 31415
|
||||||
|
|
||||||
var WhitelistedBlock = cid.Undef
|
var WhitelistedBlock = cid.Undef
|
||||||
|
@ -99,6 +99,14 @@ func (k *TipSetKey) UnmarshalJSON(b []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k TipSetKey) Cid() (cid.Cid, error) {
|
||||||
|
blk, err := k.ToStorageBlock()
|
||||||
|
if err != nil {
|
||||||
|
return cid.Cid{}, err
|
||||||
|
}
|
||||||
|
return blk.Cid(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (k TipSetKey) ToStorageBlock() (block.Block, error) {
|
func (k TipSetKey) ToStorageBlock() (block.Block, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
if err := k.MarshalCBOR(buf); err != nil {
|
if err := k.MarshalCBOR(buf); err != nil {
|
||||||
|
@ -68,7 +68,9 @@
|
|||||||
* [Eth](#Eth)
|
* [Eth](#Eth)
|
||||||
* [EthAccounts](#EthAccounts)
|
* [EthAccounts](#EthAccounts)
|
||||||
* [EthBlockNumber](#EthBlockNumber)
|
* [EthBlockNumber](#EthBlockNumber)
|
||||||
|
* [EthCall](#EthCall)
|
||||||
* [EthChainId](#EthChainId)
|
* [EthChainId](#EthChainId)
|
||||||
|
* [EthEstimateGas](#EthEstimateGas)
|
||||||
* [EthGasPrice](#EthGasPrice)
|
* [EthGasPrice](#EthGasPrice)
|
||||||
* [EthGetBalance](#EthGetBalance)
|
* [EthGetBalance](#EthGetBalance)
|
||||||
* [EthGetBlockByHash](#EthGetBlockByHash)
|
* [EthGetBlockByHash](#EthGetBlockByHash)
|
||||||
@ -2173,6 +2175,28 @@ Inputs: `null`
|
|||||||
|
|
||||||
Response: `"0x5"`
|
Response: `"0x5"`
|
||||||
|
|
||||||
|
### EthCall
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
|
"to": "0x0707070707070707070707070707070707070707",
|
||||||
|
"gas": "0x5",
|
||||||
|
"gasPrice": "0x0",
|
||||||
|
"value": "0x0",
|
||||||
|
"data": "Ynl0ZSBhcnJheQ=="
|
||||||
|
},
|
||||||
|
"string value"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response: `"string value"`
|
||||||
|
|
||||||
### EthChainId
|
### EthChainId
|
||||||
|
|
||||||
|
|
||||||
@ -2182,10 +2206,32 @@ Inputs: `null`
|
|||||||
|
|
||||||
Response: `"0x5"`
|
Response: `"0x5"`
|
||||||
|
|
||||||
|
### EthEstimateGas
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
|
"to": "0x0707070707070707070707070707070707070707",
|
||||||
|
"gas": "0x5",
|
||||||
|
"gasPrice": "0x0",
|
||||||
|
"value": "0x0",
|
||||||
|
"data": "Ynl0ZSBhcnJheQ=="
|
||||||
|
},
|
||||||
|
"string value"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response: `"0x5"`
|
||||||
|
|
||||||
### EthGasPrice
|
### EthGasPrice
|
||||||
|
|
||||||
|
|
||||||
Perms:
|
Perms: read
|
||||||
|
|
||||||
Inputs: `null`
|
Inputs: `null`
|
||||||
|
|
||||||
@ -2236,26 +2282,14 @@ Response:
|
|||||||
"extraData": "Ynl0ZSBhcnJheQ==",
|
"extraData": "Ynl0ZSBhcnJheQ==",
|
||||||
"mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"nonce": "0x0707070707070707",
|
"nonce": "0x0707070707070707",
|
||||||
"baseFeePerGas": "0x5",
|
"baseFeePerGas": "0x0",
|
||||||
"transactions": {
|
"size": "0x5",
|
||||||
"chainId": "0x5",
|
"transactions": [
|
||||||
"nonce": 42,
|
{}
|
||||||
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
],
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"uncles": [
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"0x0707070707070707070707070707070707070707070707070707070707070707"
|
||||||
"transacionIndex": "0x5",
|
]
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
|
||||||
"value": "0x0",
|
|
||||||
"type": "0x5",
|
|
||||||
"input": "Ynl0ZSBhcnJheQ==",
|
|
||||||
"gas": "0x5",
|
|
||||||
"maxFeePerGas": "0x0",
|
|
||||||
"maxPriorityFeePerGas": "0x0",
|
|
||||||
"v": "0x0",
|
|
||||||
"r": "0x0",
|
|
||||||
"s": "0x0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2289,26 +2323,14 @@ Response:
|
|||||||
"extraData": "Ynl0ZSBhcnJheQ==",
|
"extraData": "Ynl0ZSBhcnJheQ==",
|
||||||
"mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"mixHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"nonce": "0x0707070707070707",
|
"nonce": "0x0707070707070707",
|
||||||
"baseFeePerGas": "0x5",
|
"baseFeePerGas": "0x0",
|
||||||
"transactions": {
|
"size": "0x5",
|
||||||
"chainId": "0x5",
|
"transactions": [
|
||||||
"nonce": 42,
|
{}
|
||||||
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
],
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"uncles": [
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"0x0707070707070707070707070707070707070707070707070707070707070707"
|
||||||
"transacionIndex": "0x5",
|
]
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
|
||||||
"value": "0x0",
|
|
||||||
"type": "0x5",
|
|
||||||
"input": "Ynl0ZSBhcnJheQ==",
|
|
||||||
"gas": "0x5",
|
|
||||||
"maxFeePerGas": "0x0",
|
|
||||||
"maxPriorityFeePerGas": "0x0",
|
|
||||||
"v": "0x0",
|
|
||||||
"r": "0x0",
|
|
||||||
"s": "0x0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -2392,7 +2414,7 @@ Response:
|
|||||||
"nonce": 42,
|
"nonce": 42,
|
||||||
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x0707070707070707070707070707070707070707",
|
||||||
@ -2428,7 +2450,7 @@ Response:
|
|||||||
"nonce": 42,
|
"nonce": 42,
|
||||||
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x0707070707070707070707070707070707070707",
|
||||||
@ -2463,7 +2485,7 @@ Response:
|
|||||||
"nonce": 42,
|
"nonce": 42,
|
||||||
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"hash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockHash": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
||||||
"blockNumber": "0x0707070707070707070707070707070707070707070707070707070707070707",
|
"blockNumber": "0x5",
|
||||||
"transacionIndex": "0x5",
|
"transacionIndex": "0x5",
|
||||||
"from": "0x0707070707070707070707070707070707070707",
|
"from": "0x0707070707070707070707070707070707070707",
|
||||||
"to": "0x0707070707070707070707070707070707070707",
|
"to": "0x0707070707070707070707070707070707070707",
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
@ -33,8 +34,10 @@ 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)
|
||||||
EthMaxPriorityFeePerGas(ctx context.Context) (api.EthInt, error)
|
|
||||||
EthGasPrice(ctx context.Context) (api.EthInt, error)
|
EthGasPrice(ctx context.Context) (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)
|
||||||
|
EthMaxPriorityFeePerGas(ctx context.Context) (api.EthInt, error)
|
||||||
// EthSendRawTransaction(ctx context.Context, tx api.EthTx) (api.EthHash, error)
|
// EthSendRawTransaction(ctx context.Context, tx api.EthTx) (api.EthHash, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +50,8 @@ type EthModule struct {
|
|||||||
fx.In
|
fx.In
|
||||||
|
|
||||||
Chain *store.ChainStore
|
Chain *store.ChainStore
|
||||||
|
|
||||||
|
ChainAPI
|
||||||
StateAPI
|
StateAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,15 +109,34 @@ func (a *EthModule) EthGetBlockTransactionCountByHash(ctx context.Context, blkHa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash api.EthHash, fullTxInfo bool) (api.EthBlock, error) {
|
func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash api.EthHash, fullTxInfo bool) (api.EthBlock, error) {
|
||||||
return api.EthBlock{}, nil
|
ts, err := a.Chain.GetTipSetByCid(ctx, blkHash.ToCid())
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, xerrors.Errorf("error loading tipset %s: %w", ts, err)
|
||||||
|
}
|
||||||
|
return a.ethBlockFromFilecoinTipSet(ctx, ts, fullTxInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkNum api.EthInt, fullTxInfo bool) (api.EthBlock, error) {
|
func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkNum api.EthInt, fullTxInfo bool) (api.EthBlock, error) {
|
||||||
return api.EthBlock{}, nil
|
ts, err := a.Chain.GetTipsetByHeight(ctx, abi.ChainEpoch(blkNum), nil, false)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, xerrors.Errorf("error loading tipset %s: %w", ts, err)
|
||||||
|
}
|
||||||
|
return a.ethBlockFromFilecoinTipSet(ctx, ts, fullTxInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash api.EthHash) (api.EthTx, error) {
|
func (a *EthModule) EthGetTransactionByHash(ctx context.Context, txHash api.EthHash) (api.EthTx, error) {
|
||||||
return api.EthTx{}, nil
|
cid := txHash.ToCid()
|
||||||
|
|
||||||
|
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, cid, api.LookbackNoLimit, true)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := a.ethTxFromFilecoinMessageLookup(ctx, msgLookup)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
return tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@ -155,7 +179,7 @@ func (a *EthModule) EthGetBalance(ctx context.Context, address api.EthAddress, b
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthChainId(ctx context.Context) (api.EthInt, error) {
|
func (a *EthModule) EthChainId(ctx context.Context) (api.EthInt, error) {
|
||||||
return api.EthInt(0), nil
|
return api.EthInt(build.Eip155ChainId), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) NetVersion(ctx context.Context) (string, error) {
|
func (a *EthModule) NetVersion(ctx context.Context) (string, error) {
|
||||||
@ -187,11 +211,127 @@ func (a *EthModule) EthGasPrice(ctx context.Context) (api.EthInt, error) {
|
|||||||
// return api.EthHash{}, nil
|
// return api.EthHash{}, nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// func (a *EthModule) EthEstimateGas(ctx context.Context, tx api.EthTx, 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
|
return api.EthInt(0), nil
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// func (a *EthModule) EthCall(ctx context.Context, tx api.EthTx, blkParam string) (string, error) {
|
func (a *EthModule) EthCall(ctx context.Context, tx api.EthCall, blkParam string) (string, error) {
|
||||||
// return "", nil
|
return "", nil
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
|
func (a *EthModule) ethBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTxInfo bool) (api.EthBlock, error) {
|
||||||
|
parent, err := a.Chain.LoadTipSet(ctx, ts.Parents())
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, err
|
||||||
|
}
|
||||||
|
parentKeyCid, err := parent.Key().Cid()
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, err
|
||||||
|
}
|
||||||
|
parentBlkHash, err := api.EthHashFromCid(parentKeyCid)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
blkMsgs, err := a.Chain.BlockMsgsForTipset(ctx, ts)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
block := api.NewEthBlock()
|
||||||
|
|
||||||
|
// this seems to be a very expensive way to get gasUsed of the block. may need to find an efficient way to do it
|
||||||
|
gasUsed := int64(0)
|
||||||
|
for _, blkMsg := range blkMsgs {
|
||||||
|
for _, msg := range append(blkMsg.BlsMessages, blkMsg.SecpkMessages...) {
|
||||||
|
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), api.LookbackNoLimit, true)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, nil
|
||||||
|
}
|
||||||
|
gasUsed += msgLookup.Receipt.GasUsed
|
||||||
|
|
||||||
|
if fullTxInfo {
|
||||||
|
tx, err := a.ethTxFromFilecoinMessageLookup(ctx, msgLookup)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, nil
|
||||||
|
}
|
||||||
|
block.Transactions = append(block.Transactions, tx)
|
||||||
|
} else {
|
||||||
|
hash, err := api.EthHashFromCid(msg.Cid())
|
||||||
|
if err != nil {
|
||||||
|
return api.EthBlock{}, err
|
||||||
|
}
|
||||||
|
block.Transactions = append(block.Transactions, hash.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block.Number = api.EthInt(ts.Height())
|
||||||
|
block.ParentHash = parentBlkHash
|
||||||
|
block.Timestamp = api.EthInt(ts.Blocks()[0].Timestamp)
|
||||||
|
block.BaseFeePerGas = api.EthBigInt{Int: ts.Blocks()[0].ParentBaseFee.Int}
|
||||||
|
block.GasUsed = api.EthInt(gasUsed)
|
||||||
|
return block, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *EthModule) ethTxFromFilecoinMessageLookup(ctx context.Context, msgLookup *api.MsgLookup) (api.EthTx, error) {
|
||||||
|
cid := msgLookup.Message
|
||||||
|
txHash, err := api.EthHashFromCid(cid)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tsCid, err := msgLookup.TipSet.Cid()
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
blkHash, err := api.EthHashFromCid(tsCid)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := a.ChainAPI.ChainGetMessage(ctx, msgLookup.Message)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fromFilIdAddr, err := a.StateAPI.StateLookupID(ctx, msg.From, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fromEthAddr, err := api.EthAddressFromFilecoinIDAddress(fromFilIdAddr)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
toFilAddr, err := a.StateAPI.StateLookupID(ctx, msg.From, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
toEthAddr, err := api.EthAddressFromFilecoinIDAddress(toFilAddr)
|
||||||
|
if err != nil {
|
||||||
|
return api.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tx := api.EthTx{
|
||||||
|
ChainID: api.EthInt(build.Eip155ChainId),
|
||||||
|
Hash: txHash,
|
||||||
|
BlockHash: blkHash,
|
||||||
|
BlockNumber: api.EthInt(msgLookup.Height),
|
||||||
|
From: fromEthAddr,
|
||||||
|
To: toEthAddr,
|
||||||
|
Value: api.EthBigInt(msg.Value),
|
||||||
|
Type: api.EthInt(2),
|
||||||
|
Gas: api.EthInt(msg.GasLimit),
|
||||||
|
MaxFeePerGas: api.EthBigInt(msg.GasFeeCap),
|
||||||
|
MaxPriorityFeePerGas: api.EthBigInt(msg.GasPremium),
|
||||||
|
V: api.EthBigIntZero,
|
||||||
|
R: api.EthBigIntZero,
|
||||||
|
S: api.EthBigIntZero,
|
||||||
|
// TODO: Input:
|
||||||
|
}
|
||||||
|
return tx, nil
|
||||||
|
}
|
||||||
|
@ -95,8 +95,8 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
|
|||||||
rpcServer.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
|
rpcServer.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
|
||||||
rpcServer.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice")
|
rpcServer.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice")
|
||||||
rpcServer.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction")
|
rpcServer.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction")
|
||||||
// rpcServer.AliasMethod("eth_estimateGas", "Filecoin.EthEstimateGas")
|
rpcServer.AliasMethod("eth_estimateGas", "Filecoin.EthEstimateGas")
|
||||||
// rpcServer.AliasMethod("eth_call", "Filecoin.EthCall")
|
rpcServer.AliasMethod("eth_call", "Filecoin.EthCall")
|
||||||
|
|
||||||
rpcServer.AliasMethod("net_version", "Filecoin.NetVersion")
|
rpcServer.AliasMethod("net_version", "Filecoin.NetVersion")
|
||||||
rpcServer.AliasMethod("net_listening", "Filecoin.NetListening")
|
rpcServer.AliasMethod("net_listening", "Filecoin.NetListening")
|
||||||
|
Loading…
Reference in New Issue
Block a user