rpc.go 3.52 KB
Newer Older
1
package syncnode
2 3 4 5

import (
	"context"
	"errors"
6 7 8
	"io"

	"github.com/ethereum-optimism/optimism/op-service/rpc"
9 10 11 12

	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	gethtypes "github.com/ethereum/go-ethereum/core/types"
13
	gethrpc "github.com/ethereum/go-ethereum/rpc"
14 15 16 17 18 19

	"github.com/ethereum-optimism/optimism/op-service/client"
	"github.com/ethereum-optimism/optimism/op-service/eth"
	"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
)

20
type RPCSyncNode struct {
21 22 23 24
	name string
	cl   client.RPC
}

25 26
func NewRPCSyncNode(name string, cl client.RPC) *RPCSyncNode {
	return &RPCSyncNode{
27 28 29 30 31
		name: name,
		cl:   cl,
	}
}

32 33 34
var _ SyncSource = (*RPCSyncNode)(nil)
var _ SyncControl = (*RPCSyncNode)(nil)
var _ SyncNode = (*RPCSyncNode)(nil)
35

36
func (rs *RPCSyncNode) BlockRefByNumber(ctx context.Context, number uint64) (eth.BlockRef, error) {
37 38 39
	var out *eth.BlockRef
	err := rs.cl.CallContext(ctx, &out, "interop_blockRefByNumber", number)
	if err != nil {
40
		var jsonErr gethrpc.Error
41 42 43 44 45 46 47 48 49 50
		if errors.As(err, &jsonErr) {
			if jsonErr.ErrorCode() == 0 { // TODO
				return eth.BlockRef{}, ethereum.NotFound
			}
		}
		return eth.BlockRef{}, err
	}
	return *out, nil
}

51
func (rs *RPCSyncNode) FetchReceipts(ctx context.Context, blockHash common.Hash) (gethtypes.Receipts, error) {
52 53 54
	var out gethtypes.Receipts
	err := rs.cl.CallContext(ctx, &out, "interop_fetchReceipts", blockHash)
	if err != nil {
55
		var jsonErr gethrpc.Error
56 57 58 59 60 61 62 63 64 65
		if errors.As(err, &jsonErr) {
			if jsonErr.ErrorCode() == 0 { // TODO
				return nil, ethereum.NotFound
			}
		}
		return nil, err
	}
	return out, nil
}

66
func (rs *RPCSyncNode) ChainID(ctx context.Context) (types.ChainID, error) {
67 68 69 70 71
	var chainID types.ChainID
	err := rs.cl.CallContext(ctx, &chainID, "interop_chainID")
	return chainID, err
}

72
func (rs *RPCSyncNode) String() string {
73 74
	return rs.name
}
75

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
func (rs *RPCSyncNode) SubscribeEvents(ctx context.Context, dest chan *types.ManagedEvent) (ethereum.Subscription, error) {
	return rpc.SubscribeStream(ctx, "interop", rs.cl, dest, "events")
}

// PullEvent pulls an event, as alternative to an event-subscription with SubscribeEvents.
// This returns an io.EOF error if no new events are available.
func (rs *RPCSyncNode) PullEvent(ctx context.Context) (*types.ManagedEvent, error) {
	var out *types.ManagedEvent
	err := rs.cl.CallContext(ctx, &out, "interop_pullEvent")
	var x gethrpc.Error
	if err != nil {
		if errors.As(err, &x) && x.ErrorCode() == rpc.OutOfEventsErrCode {
			return nil, io.EOF
		}
		return nil, err
	}
	return out, nil
}

func (rs *RPCSyncNode) UpdateCrossUnsafe(ctx context.Context, id eth.BlockID) error {
	return rs.cl.CallContext(ctx, nil, "interop_updateCrossUnsafe", id)
}

func (rs *RPCSyncNode) UpdateCrossSafe(ctx context.Context, derived eth.BlockID, derivedFrom eth.BlockID) error {
	return rs.cl.CallContext(ctx, nil, "interop_updateCrossSafe", derived, derivedFrom)
}

func (rs *RPCSyncNode) UpdateFinalized(ctx context.Context, id eth.BlockID) error {
	return rs.cl.CallContext(ctx, nil, "interop_updateFinalized", id)
}

func (rs *RPCSyncNode) Reset(ctx context.Context, unsafe, safe, finalized eth.BlockID) error {
	return rs.cl.CallContext(ctx, nil, "interop_reset", unsafe, safe, finalized)
}

func (rs *RPCSyncNode) ProvideL1(ctx context.Context, nextL1 eth.BlockRef) error {
	return rs.cl.CallContext(ctx, nil, "interop_provideL1", nextL1)
}

func (rs *RPCSyncNode) AnchorPoint(ctx context.Context) (types.DerivedBlockRefPair, error) {
	var out types.DerivedBlockRefPair
	err := rs.cl.CallContext(ctx, &out, "interop_anchorPoint")
	return out, err
119
}