api.go 3.61 KB
Newer Older
1 2 3 4 5 6
package node

import (
	"context"
	"fmt"

7
	"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
8
	"github.com/ethereum-optimism/optimism/op-node/eth"
9
	"github.com/ethereum-optimism/optimism/op-node/metrics"
10
	"github.com/ethereum-optimism/optimism/op-node/rollup"
11
	"github.com/ethereum-optimism/optimism/op-node/version"
12 13 14 15 16 17 18
	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/log"
	"github.com/ethereum/go-ethereum/rpc"
)

type l2EthClient interface {
19
	InfoByRpcNumber(ctx context.Context, num rpc.BlockNumber) (eth.BlockInfo, error)
20
	// GetProof returns a proof of the account, it may return a nil result without error if the address was not found.
21
	GetProof(ctx context.Context, address common.Address, blockTag string) (*eth.AccountResult, error)
22 23
}

24
type driverClient interface {
25
	SyncStatus(ctx context.Context) (*eth.SyncStatus, error)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
	ResetDerivationPipeline(context.Context) error
}

type adminAPI struct {
	dr driverClient
	m  *metrics.Metrics
}

func newAdminAPI(dr driverClient, m *metrics.Metrics) *adminAPI {
	return &adminAPI{
		dr: dr,
		m:  m,
	}
}

func (n *adminAPI) ResetDerivationPipeline(ctx context.Context) error {
	recordDur := n.m.RecordRPCServerRequest("admin_resetDerivationPipeline")
	defer recordDur()
	return n.dr.ResetDerivationPipeline(ctx)
45 46
}

47 48 49
type nodeAPI struct {
	config *rollup.Config
	client l2EthClient
50
	dr     driverClient
51
	log    log.Logger
52
	m      *metrics.Metrics
53 54
}

55
func newNodeAPI(config *rollup.Config, l2Client l2EthClient, dr driverClient, log log.Logger, m *metrics.Metrics) *nodeAPI {
56 57 58
	return &nodeAPI{
		config: config,
		client: l2Client,
59
		dr:     dr,
60
		log:    log,
61
		m:      m,
62 63 64
	}
}

65
func (n *nodeAPI) OutputAtBlock(ctx context.Context, number rpc.BlockNumber) ([]eth.Bytes32, error) {
66 67
	recordDur := n.m.RecordRPCServerRequest("optimism_outputAtBlock")
	defer recordDur()
68 69
	// TODO: rpc.BlockNumber doesn't support the "safe" tag. Need a new type

70
	head, err := n.client.InfoByRpcNumber(ctx, number)
71 72 73 74 75 76 77 78
	if err != nil {
		n.log.Error("failed to get block", "err", err)
		return nil, err
	}
	if head == nil {
		return nil, ethereum.NotFound
	}

79
	proof, err := n.client.GetProof(ctx, predeploys.L2ToL1MessagePasserAddr, toBlockNumArg(number))
80 81 82 83 84 85 86 87
	if err != nil {
		n.log.Error("failed to get contract proof", "err", err)
		return nil, err
	}
	if proof == nil {
		return nil, ethereum.NotFound
	}
	// make sure that the proof (including storage hash) that we retrieved is correct by verifying it against the state-root
88 89
	if err := proof.Verify(head.Root()); err != nil {
		n.log.Error("invalid withdrawal root detected in block", "stateRoot", head.Root(), "blocknum", number, "msg", err)
90 91 92
		return nil, fmt.Errorf("invalid withdrawal root hash")
	}

93
	var l2OutputRootVersion eth.Bytes32 // it's zero for now
94
	l2OutputRoot := rollup.ComputeL2OutputRoot(l2OutputRootVersion, head.Hash(), head.Root(), proof.StorageHash)
95

96
	return []eth.Bytes32{l2OutputRootVersion, l2OutputRoot}, nil
97 98
}

99
func (n *nodeAPI) SyncStatus(ctx context.Context) (*eth.SyncStatus, error) {
100 101
	recordDur := n.m.RecordRPCServerRequest("optimism_syncStatus")
	defer recordDur()
102 103 104
	return n.dr.SyncStatus(ctx)
}

105 106 107 108 109 110
func (n *nodeAPI) RollupConfig(_ context.Context) (*rollup.Config, error) {
	recordDur := n.m.RecordRPCServerRequest("optimism_rollupConfig")
	defer recordDur()
	return n.config, nil
}

111
func (n *nodeAPI) Version(ctx context.Context) (string, error) {
112 113
	recordDur := n.m.RecordRPCServerRequest("optimism_version")
	defer recordDur()
114 115 116 117
	return version.Version + "-" + version.Meta, nil
}

func toBlockNumArg(number rpc.BlockNumber) string {
118 119 120
	// never returns an error
	out, _ := number.MarshalText()
	return string(out)
121
}