Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add eth_syncing RPC method #10719

Merged
merged 1 commit into from
May 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,7 @@ type FullNode interface {
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) //perm:read
NetVersion(ctx context.Context) (string, error) //perm:read
NetListening(ctx context.Context) (bool, error) //perm:read
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
Expand Down
1 change: 1 addition & 0 deletions api/api_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type Gateway interface {
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
Expand Down
1 change: 1 addition & 0 deletions api/eth_aliases.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func CreateEthRPCAliases(as apitypes.Aliaser) {
as.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt")
as.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance")
as.AliasMethod("eth_chainId", "Filecoin.EthChainId")
as.AliasMethod("eth_syncing", "Filecoin.EthSyncing")
as.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory")
as.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion")
as.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
Expand Down
15 changes: 15 additions & 0 deletions api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified build/openrpc/full.json.gz
Binary file not shown.
Binary file modified build/openrpc/gateway.json.gz
Binary file not shown.
Binary file modified build/openrpc/miner.json.gz
Binary file not shown.
Binary file modified build/openrpc/worker.json.gz
Binary file not shown.
24 changes: 24 additions & 0 deletions chain/types/ethtypes/eth_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,30 @@ func (c *EthCall) UnmarshalJSON(b []byte) error {
return nil
}

type EthSyncingResult struct {
DoneSync bool
StartingBlock EthUint64
CurrentBlock EthUint64
HighestBlock EthUint64
}

func (sr EthSyncingResult) MarshalJSON() ([]byte, error) {
if sr.DoneSync {
// when done syncing, the json response should be '"result": false'
return []byte("false"), nil
}

// need to do an anonymous struct to avoid infinite recursion
return json.Marshal(&struct {
StartingBlock EthUint64 `json:"startingblock"`
CurrentBlock EthUint64 `json:"currentblock"`
HighestBlock EthUint64 `json:"highestblock"`
}{
StartingBlock: sr.StartingBlock,
CurrentBlock: sr.CurrentBlock,
HighestBlock: sr.HighestBlock})
}

const (
EthAddressLength = 20
EthHashLength = 32
Expand Down
10 changes: 10 additions & 0 deletions documentation/en/api-v1-unstable-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
* [EthProtocolVersion](#EthProtocolVersion)
* [EthSendRawTransaction](#EthSendRawTransaction)
* [EthSubscribe](#EthSubscribe)
* [EthSyncing](#EthSyncing)
* [EthUninstallFilter](#EthUninstallFilter)
* [EthUnsubscribe](#EthUnsubscribe)
* [Filecoin](#Filecoin)
Expand Down Expand Up @@ -3071,6 +3072,15 @@ Inputs:

Response: `"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"`

### EthSyncing


Perms: read

Inputs: `null`

Response: `false`

### EthUninstallFilter
Uninstalls a filter with given id.

Expand Down
1 change: 1 addition & 0 deletions gateway/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ type TargetAPI interface {
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
Expand Down
8 changes: 8 additions & 0 deletions gateway/proxy_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,14 @@ func (gw *Node) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) {
return gw.target.EthChainId(ctx)
}

func (gw *Node) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) {
if err := gw.limit(ctx, basicRateLimitTokens); err != nil {
return ethtypes.EthSyncingResult{}, err
}

return gw.target.EthSyncing(ctx)
}

func (gw *Node) NetVersion(ctx context.Context) (string, error) {
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
return "", err
Expand Down
4 changes: 4 additions & 0 deletions node/impl/full/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ func (e *EthModuleDummy) EthChainId(ctx context.Context) (ethtypes.EthUint64, er
return 0, ErrModuleDisabled
}

func (e *EthModuleDummy) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) {
return ethtypes.EthSyncingResult{}, ErrModuleDisabled
}

func (e *EthModuleDummy) NetVersion(ctx context.Context) (string, error) {
return "", ErrModuleDisabled
}
Expand Down
38 changes: 38 additions & 0 deletions node/impl/full/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type EthModuleAPI interface {
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error)
EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error)
NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
Expand Down Expand Up @@ -133,6 +134,7 @@ type EthModule struct {
ChainAPI
MpoolAPI
StateAPI
SyncAPI
}

var _ EthModuleAPI = (*EthModule)(nil)
Expand Down Expand Up @@ -673,6 +675,42 @@ func (a *EthModule) EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
return ethtypes.EthUint64(build.Eip155ChainId), nil
}

func (a *EthModule) EthSyncing(ctx context.Context) (ethtypes.EthSyncingResult, error) {
state, err := a.SyncAPI.SyncState(ctx)
if err != nil {
return ethtypes.EthSyncingResult{}, fmt.Errorf("failed calling SyncState: %w", err)
}

if len(state.ActiveSyncs) == 0 {
return ethtypes.EthSyncingResult{}, errors.New("no active syncs, try again")
}

working := -1
for i, ss := range state.ActiveSyncs {
if ss.Stage == api.StageIdle {
continue
}
working = i
Copy link
Contributor

@maciejwitowski maciejwitowski Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this? Why are looking for the index of the last non-idle one from ActiveSyncs and eg not the 1st one? (I'm not sure what ActiveSyncs represent tbh)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to have the same logic as when calling lotus sync wait which is done like this (see https://github.com/filecoin-project/lotus/blob/master/cli/sync.go#L286)

There is also this commit which picks the last worker in case all are idle, but it does not go in details as to why

}
if working == -1 {
working = len(state.ActiveSyncs) - 1
}

ss := state.ActiveSyncs[working]
if ss.Base == nil || ss.Target == nil {
return ethtypes.EthSyncingResult{}, errors.New("missing syncing information, try again")
}

res := ethtypes.EthSyncingResult{
DoneSync: ss.Stage == api.StageSyncComplete,
CurrentBlock: ethtypes.EthUint64(ss.Height),
StartingBlock: ethtypes.EthUint64(ss.Base.Height()),
HighestBlock: ethtypes.EthUint64(ss.Target.Height()),
}

return res, nil
}

func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) {
params, err := jsonrpc.DecodeParams[ethtypes.EthFeeHistoryParams](p)
if err != nil {
Expand Down
5 changes: 3 additions & 2 deletions node/modules/ethmodule.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import (
"github.com/filecoin-project/lotus/node/repo"
)

func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *store.ChainStore, *stmgr.StateManager, EventAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI, full.MpoolAPI) (*full.EthModule, error) {
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI, mpoolapi full.MpoolAPI) (*full.EthModule, error) {
func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo, fx.Lifecycle, *store.ChainStore, *stmgr.StateManager, EventAPI, *messagepool.MessagePool, full.StateAPI, full.ChainAPI, full.MpoolAPI, full.SyncAPI) (*full.EthModule, error) {
return func(mctx helpers.MetricsCtx, r repo.LockedRepo, lc fx.Lifecycle, cs *store.ChainStore, sm *stmgr.StateManager, evapi EventAPI, mp *messagepool.MessagePool, stateapi full.StateAPI, chainapi full.ChainAPI, mpoolapi full.MpoolAPI, syncapi full.SyncAPI) (*full.EthModule, error) {
sqlitePath, err := r.SqlitePath()
if err != nil {
return nil, err
Expand Down Expand Up @@ -84,6 +84,7 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep
ChainAPI: chainapi,
MpoolAPI: mpoolapi,
StateAPI: stateapi,
SyncAPI: syncapi,

EthTxHashManager: &ethTxHashManager,
}, nil
Expand Down