Commit 13d9396e authored by vicotor's avatar vicotor

add withdrawal in op-proposer

parent 4af57f5f
......@@ -59,6 +59,10 @@ func (e *ExChainAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*
wblk := wrapper.NewBlkWrapper(block)
var res = &eth.WithdrawalProof{}
tx, _ := e.chain.GetTransaction(txHash)
wtx := tx.GetWithdrawTx()
if wtx == nil {
return nil, errors.New("transaction is not withdrawal tx")
}
receipt := e.chain.GetReceipt(txHash)
if receipt == nil {
return nil, errors.New("not found tx receipt")
......@@ -67,7 +71,7 @@ func (e *ExChainAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*
if err != nil {
return nil, err
}
item := wrapper.NewTxWrapper(tx).WithdrawlHash()
item := wrapper.NewTxWrapper(tx).WithdrawalHash()
proof, err := tree.MerkleProof(item.Bytes())
if err != nil {
return nil, errors.New(fmt.Sprintf("failed to get proof (%s)", err.Error()))
......@@ -76,15 +80,37 @@ func (e *ExChainAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*
for i, p := range proof {
copy(res.Proof[i][:], p[:])
}
res.Value = new(big.Int).SetBytes(wtx.Amount)
res.User = common.BytesToAddress(wtx.User)
res.Coin = []byte(wtx.Coin)
oo, err := e.OutputV0AtBlock(ctx, wblk.Hash())
if err != nil {
log.WithField("error", err).Error("failed to get output for withdrawal proof")
return nil, err
}
res.Output = *oo
return res, nil
}
func (e *ExChainAPI) WithdrawalTxs(ctx context.Context, blockNum uint64) ([]common.Hash, error) {
block := e.chain.GetBlock(uint256.NewInt(blockNum))
if block == nil {
return nil, errors.New("block not found in exchain")
}
wblk := wrapper.NewBlkWrapper(block)
txHashes := make([]common.Hash, 0)
for _, tx := range wblk.Transactions() {
wtx := wrapper.NewTxWrapper(tx)
if tx.TxType == nebulav1.TxType_WithdrawTx {
txHashes = append(txHashes, wtx.Hash())
}
}
return txHashes, nil
}
func (e *ExChainAPI) OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error) {
blk := e.chain.BlockByHash(blockHash)
if blk == nil {
......
......@@ -115,7 +115,7 @@ func (s *server) GetWithdrawalProof(ctx context.Context, request *nodev1.Withdra
if err != nil {
return nil, err
}
item := wrapper.NewTxWrapper(tx).WithdrawlHash()
item := wrapper.NewTxWrapper(tx).WithdrawalHash()
proof, err := tree.MerkleProof(item.Bytes())
if err != nil {
return nil, errors.New(fmt.Sprintf("failed to get proof (%s)", err.Error()))
......
......@@ -3,8 +3,12 @@ package wrapper
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp"
"github.com/exchain/go-exchain/exchain"
nebulav1 "github.com/exchain/go-exchain/exchain/protocol/gen/go/nebula/v1"
"github.com/golang/protobuf/proto"
log "github.com/sirupsen/logrus"
"math/big"
)
type TxWrapper struct {
......@@ -36,6 +40,29 @@ func (t *TxWrapper) calcHash() common.Hash {
}
func (t *TxWrapper) WithdrawalHash() common.Hash {
if t.tx.TxType != nebulav1.TxType_WithdrawTx {
return common.Hash{}
}
wtx := t.tx.GetWithdrawTx()
if wtx == nil {
return common.Hash{}
}
param := exchain.ExChainWithdrawalParam{
Value: new(big.Int).SetBytes(wtx.Amount),
User: common.BytesToAddress(wtx.User),
Coin: wtx.Coin,
}
// todo: vicotor check rlp encode?
data, err := rlp.EncodeToBytes(param)
if err != nil {
log.WithField("err", err).Error("rlp encode withdrawal param failed")
return common.Hash{}
}
hash := crypto.Keccak256Hash(data)
return hash
}
func (t *TxWrapper) Bytes() ([]byte, error) {
return proto.Marshal(t.tx)
}
......
......@@ -10,12 +10,12 @@ require (
github.com/btcsuite/btcd v0.24.2
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
github.com/cockroachdb/pebble v1.1.3
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20250115145553-996c7aba6565
github.com/ethereum/go-ethereum v1.15.0
github.com/ethereum/go-ethereum v1.15.7
github.com/fsnotify/fsnotify v1.8.0
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/golang/snappy v1.0.0
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8
github.com/hashicorp/go-multierror v1.1.1
......@@ -44,15 +44,16 @@ require (
github.com/protolambda/ctxlock v0.1.0
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.5
golang.org/x/crypto v0.32.0
golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/sync v0.10.0
golang.org/x/term v0.28.0
golang.org/x/sync v0.13.0
golang.org/x/term v0.30.0
golang.org/x/time v0.9.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/consensys/gnark-crypto v0.12.1 // indirect
github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
......@@ -89,7 +90,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect
github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
......@@ -106,7 +107,7 @@ require (
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-yaml/yaml v2.1.0+incompatible // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/goccy/go-json v0.10.5 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
......@@ -123,7 +124,7 @@ require (
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
github.com/hashicorp/golang-lru v0.5.0
github.com/hashicorp/golang-lru v1.0.2
github.com/hashicorp/golang-lru/arc/v2 v2.0.7 // indirect
github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e // indirect
github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 // indirect
......@@ -134,7 +135,7 @@ require (
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
......@@ -215,14 +216,14 @@ require (
github.com/stretchr/objx v0.5.2 // indirect
github.com/supranational/blst v0.3.13 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/wlynxg/anet v0.0.4 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.etcd.io/bbolt v1.3.5 // indirect
go.uber.org/dig v1.18.0 // indirect
go.uber.org/fx v1.22.2 // indirect
......@@ -230,15 +231,15 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/tools v0.26.0 // indirect
google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
google.golang.org/grpc v1.57.1
google.golang.org/protobuf v1.34.2
google.golang.org/protobuf v1.36.6
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
......
This diff is collapsed.
......@@ -22,6 +22,7 @@ type l2Client interface {
//GetProof(ctx context.Context, address common.Address, storage []common.Hash, blockTag string) (*eth.AccountResult, error)
OutputV0AtBlock(ctx context.Context, blockHash common.Hash) (*eth.OutputV0, error)
WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error)
WithdrawalTxs(ctx context.Context, blockNumber uint64) ([]common.Hash, error)
}
type driverClient interface {
......@@ -159,6 +160,17 @@ func (n *nodeAPI) WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth
return output, nil
}
func (n *nodeAPI) WithdrawalTxs(ctx context.Context, number hexutil.Uint64) ([]common.Hash, error) {
recordDur := n.m.RecordRPCServerRequest("optimism_withdrawalTxs")
defer recordDur()
output, err := n.client.WithdrawalTxs(ctx, uint64(number))
if err != nil {
return nil, fmt.Errorf("failed to get withdrawal txs at block %s: %w", number, err)
}
return output, nil
}
func (n *nodeAPI) SafeHeadAtL1Block(ctx context.Context, number hexutil.Uint64) (*eth.SafeHeadResponse, error) {
recordDur := n.m.RecordRPCServerRequest("optimism_safeHeadAtL1Block")
defer recordDur()
......
This diff is collapsed.
[{"type":"constructor","inputs":[],"stateMutability":"nonpayable"},{"type":"receive","stateMutability":"payable"},{"type":"function","name":"balance","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"},{"type":"function","name":"batchExChainWithdrawal","inputs":[{"name":"_params","type":"tuple[]","internalType":"struct Types.BatchExChainWithdrawalParam[]","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"user","type":"address","internalType":"address"},{"name":"coin","type":"bytes","internalType":"bytes"},{"name":"txHash","type":"bytes32","internalType":"bytes32"},{"name":"_withdrawalProof","type":"bytes[]","internalType":"bytes[]"}]},{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"},{"name":"_outputRootProof","type":"tuple","internalType":"struct Types.OutputRootProof","components":[{"name":"version","type":"bytes32","internalType":"bytes32"},{"name":"stateRoot","type":"bytes32","internalType":"bytes32"},{"name":"messagePasserStorageRoot","type":"bytes32","internalType":"bytes32"},{"name":"latestBlockhash","type":"bytes32","internalType":"bytes32"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositERC20Transaction","inputs":[{"name":"_to","type":"address","internalType":"address"},{"name":"_mint","type":"uint256","internalType":"uint256"},{"name":"_value","type":"uint256","internalType":"uint256"},{"name":"_gasLimit","type":"uint64","internalType":"uint64"},{"name":"_isCreation","type":"bool","internalType":"bool"},{"name":"_data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"depositTransaction","inputs":[{"name":"_to","type":"address","internalType":"address"},{"name":"_value","type":"uint256","internalType":"uint256"},{"name":"_gasLimit","type":"uint64","internalType":"uint64"},{"name":"_isCreation","type":"bool","internalType":"bool"},{"name":"_data","type":"bytes","internalType":"bytes"}],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"donateETH","inputs":[],"outputs":[],"stateMutability":"payable"},{"type":"function","name":"exChainWithdrawal","inputs":[{"name":"_param","type":"tuple","internalType":"struct Types.ExChainWithdrawalParam","components":[{"name":"value","type":"uint256","internalType":"uint256"},{"name":"user","type":"address","internalType":"address"},{"name":"coin","type":"bytes","internalType":"bytes"},{"name":"txHash","type":"bytes32","internalType":"bytes32"}]},{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"},{"name":"_outputRootProof","type":"tuple","internalType":"struct Types.OutputRootProof","components":[{"name":"version","type":"bytes32","internalType":"bytes32"},{"name":"stateRoot","type":"bytes32","internalType":"bytes32"},{"name":"messagePasserStorageRoot","type":"bytes32","internalType":"bytes32"},{"name":"latestBlockhash","type":"bytes32","internalType":"bytes32"}]},{"name":"_withdrawalProof","type":"bytes[]","internalType":"bytes[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"finalizeWithdrawalTransaction","inputs":[{"name":"_tx","type":"tuple","internalType":"struct Types.WithdrawalTransaction","components":[{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"sender","type":"address","internalType":"address"},{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}]}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"finalizedWithdrawals","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"guardian","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"initialize","inputs":[{"name":"_l2Oracle","type":"address","internalType":"contract L2OutputOracle"},{"name":"_systemConfig","type":"address","internalType":"contract SystemConfig"},{"name":"_superchainConfig","type":"address","internalType":"contract SuperchainConfig"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"isOutputFinalized","inputs":[{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"}],"outputs":[{"name":"","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"l2Oracle","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract L2OutputOracle"}],"stateMutability":"view"},{"type":"function","name":"l2Sender","inputs":[],"outputs":[{"name":"","type":"address","internalType":"address"}],"stateMutability":"view"},{"type":"function","name":"minimumGasLimit","inputs":[{"name":"_byteCount","type":"uint64","internalType":"uint64"}],"outputs":[{"name":"","type":"uint64","internalType":"uint64"}],"stateMutability":"pure"},{"type":"function","name":"params","inputs":[],"outputs":[{"name":"prevBaseFee","type":"uint128","internalType":"uint128"},{"name":"prevBoughtGas","type":"uint64","internalType":"uint64"},{"name":"prevBlockNum","type":"uint64","internalType":"uint64"}],"stateMutability":"view"},{"type":"function","name":"paused","inputs":[],"outputs":[{"name":"paused_","type":"bool","internalType":"bool"}],"stateMutability":"view"},{"type":"function","name":"proveWithdrawalTransaction","inputs":[{"name":"_tx","type":"tuple","internalType":"struct Types.WithdrawalTransaction","components":[{"name":"nonce","type":"uint256","internalType":"uint256"},{"name":"sender","type":"address","internalType":"address"},{"name":"target","type":"address","internalType":"address"},{"name":"value","type":"uint256","internalType":"uint256"},{"name":"gasLimit","type":"uint256","internalType":"uint256"},{"name":"data","type":"bytes","internalType":"bytes"}]},{"name":"_l2OutputIndex","type":"uint256","internalType":"uint256"},{"name":"_outputRootProof","type":"tuple","internalType":"struct Types.OutputRootProof","components":[{"name":"version","type":"bytes32","internalType":"bytes32"},{"name":"stateRoot","type":"bytes32","internalType":"bytes32"},{"name":"messagePasserStorageRoot","type":"bytes32","internalType":"bytes32"},{"name":"latestBlockhash","type":"bytes32","internalType":"bytes32"}]},{"name":"_withdrawalProof","type":"bytes[]","internalType":"bytes[]"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"provenWithdrawals","inputs":[{"name":"","type":"bytes32","internalType":"bytes32"}],"outputs":[{"name":"outputRoot","type":"bytes32","internalType":"bytes32"},{"name":"timestamp","type":"uint128","internalType":"uint128"},{"name":"l2OutputIndex","type":"uint128","internalType":"uint128"}],"stateMutability":"view"},{"type":"function","name":"setGasPayingToken","inputs":[{"name":"_token","type":"address","internalType":"address"},{"name":"_decimals","type":"uint8","internalType":"uint8"},{"name":"_name","type":"bytes32","internalType":"bytes32"},{"name":"_symbol","type":"bytes32","internalType":"bytes32"}],"outputs":[],"stateMutability":"nonpayable"},{"type":"function","name":"superchainConfig","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract SuperchainConfig"}],"stateMutability":"view"},{"type":"function","name":"systemConfig","inputs":[],"outputs":[{"name":"","type":"address","internalType":"contract SystemConfig"}],"stateMutability":"view"},{"type":"function","name":"version","inputs":[],"outputs":[{"name":"","type":"string","internalType":"string"}],"stateMutability":"pure"},{"type":"event","name":"Initialized","inputs":[{"name":"version","type":"uint8","indexed":false,"internalType":"uint8"}],"anonymous":false},{"type":"event","name":"TransactionDeposited","inputs":[{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"},{"name":"version","type":"uint256","indexed":true,"internalType":"uint256"},{"name":"opaqueData","type":"bytes","indexed":false,"internalType":"bytes"}],"anonymous":false},{"type":"event","name":"WithdrawalFinalized","inputs":[{"name":"withdrawalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"success","type":"bool","indexed":false,"internalType":"bool"}],"anonymous":false},{"type":"event","name":"WithdrawalProven","inputs":[{"name":"withdrawalHash","type":"bytes32","indexed":true,"internalType":"bytes32"},{"name":"from","type":"address","indexed":true,"internalType":"address"},{"name":"to","type":"address","indexed":true,"internalType":"address"}],"anonymous":false},{"type":"error","name":"BadTarget","inputs":[]},{"type":"error","name":"CallPaused","inputs":[]},{"type":"error","name":"ContentLengthMismatch","inputs":[]},{"type":"error","name":"EmptyItem","inputs":[]},{"type":"error","name":"InvalidDataRemainder","inputs":[]},{"type":"error","name":"InvalidHeader","inputs":[]},{"type":"error","name":"LargeCalldata","inputs":[]},{"type":"error","name":"NoValue","inputs":[]},{"type":"error","name":"OnlyCustomGasToken","inputs":[]},{"type":"error","name":"OutOfGas","inputs":[]},{"type":"error","name":"SmallGasLimit","inputs":[]},{"type":"error","name":"TransferFailed","inputs":[]},{"type":"error","name":"Unauthorized","inputs":[]},{"type":"error","name":"UnexpectedList","inputs":[]},{"type":"error","name":"UnexpectedString","inputs":[]}]
......@@ -33,12 +33,24 @@ var (
EnvVars: prefixEnvVars("ROLLUP_RPC"),
}
DataDirFlag = &cli.StringFlag{
Name: "data-dir",
Usage: "Data directory for the proposer",
Value: "data",
EnvVars: prefixEnvVars("DATA_DIR"),
}
// Optional flags
L2OOAddressFlag = &cli.StringFlag{
Name: "l2oo-address",
Usage: "Address of the L2OutputOracle contract",
EnvVars: prefixEnvVars("L2OO_ADDRESS"),
}
PortalAddressFlag = &cli.StringFlag{
Name: "portal-address",
Usage: "Address of the Portal contract",
EnvVars: prefixEnvVars("PORTAL_ADDRESS"),
}
PollIntervalFlag = &cli.DurationFlag{
Name: "poll-interval",
Usage: "How frequently to poll L2 for new blocks (legacy L2OO)",
......@@ -91,6 +103,8 @@ var requiredFlags = []cli.Flag{
var optionalFlags = []cli.Flag{
L2OOAddressFlag,
PortalAddressFlag,
DataDirFlag,
PollIntervalFlag,
AllowNonFinalizedFlag,
L2OutputHDPathFlag,
......
......@@ -29,6 +29,12 @@ type CLIConfig struct {
// L2OOAddress is the L2OutputOracle contract address.
L2OOAddress string
// PortalAddress is the Portal contract address.
PortalAddress string
// DataDir is the data directory for the proposer.
DataDir string
// PollInterval is the delay between querying L2 for more transaction
// and creating a new batch.
PollInterval time.Duration
......@@ -100,6 +106,8 @@ func NewConfig(ctx *cli.Context) *CLIConfig {
L1EthRpc: ctx.String(flags.L1EthRpcFlag.Name),
RollupRpc: ctx.String(flags.RollupRpcFlag.Name),
L2OOAddress: ctx.String(flags.L2OOAddressFlag.Name),
PortalAddress: ctx.String(flags.PortalAddressFlag.Name),
DataDir: ctx.String(flags.DataDirFlag.Name),
PollInterval: ctx.Duration(flags.PollIntervalFlag.Name),
TxMgrConfig: txmgr.ReadCLIConfig(ctx),
// Optional Flags
......
......@@ -42,6 +42,9 @@ type L1Client interface {
type L2OOContract interface {
Version(*bind.CallOpts) (string, error)
NextBlockNumber(*bind.CallOpts) (*big.Int, error)
GetL2OutputIndexAfter(opts *bind.CallOpts, _l2BlockNumber *big.Int) (*big.Int, error)
GetL2Output(opts *bind.CallOpts, _l2OutputIndex *big.Int) (bindings.TypesOutputProposal, error)
LatestBlockNumber(opts *bind.CallOpts) (*big.Int, error)
}
type DGFContract interface {
......
This diff is collapsed.
......@@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"github.com/exchain/go-exchain/metadb"
"github.com/exchain/go-exchain/metadb/storagedb"
"io"
"strings"
"sync/atomic"
......@@ -37,6 +39,8 @@ type ProposerConfig struct {
ProposalInterval time.Duration
L2OutputOracleAddr *common.Address
PortalAddr *common.Address
Database metadb.Database
DisputeGameFactoryAddr *common.Address
DisputeGameType uint32
......@@ -95,6 +99,8 @@ func (ps *ProposerService) initFromCLIConfig(ctx context.Context, version string
ps.WaitNodeSync = cfg.WaitNodeSync
ps.initL2ooAddress(cfg)
ps.initPortalAddress(cfg)
ps.initData(cfg)
ps.initDGF(cfg)
if err := ps.initRPCClients(ctx, cfg); err != nil {
......@@ -205,6 +211,20 @@ func (ps *ProposerService) initL2ooAddress(cfg *CLIConfig) {
ps.L2OutputOracleAddr = &l2ooAddress
}
func (ps *ProposerService) initPortalAddress(cfg *CLIConfig) {
portalAddress, err := opservice.ParseAddress(cfg.PortalAddress)
if err != nil {
// Return no error & set no L2OO related configuration fields.
return
}
ps.PortalAddr = &portalAddress
}
func (ps *ProposerService) initData(cfg *CLIConfig) {
db := storagedb.NewStorageDB(cfg.DataDir, "proposer")
ps.Database = db
}
func (ps *ProposerService) initDGF(cfg *CLIConfig) {
dgfAddress, err := opservice.ParseAddress(cfg.DGFAddress)
if err != nil {
......
......@@ -2,7 +2,6 @@ package dial
import (
"context"
"github.com/exchain/go-exchain/exchain"
"github.com/exchain/go-exchain/exchain/wrapper"
"math/big"
)
......@@ -11,6 +10,5 @@ import (
// It does not describe all of the functions an ethclient.Client has, only the ones used by callers of the L2 Providers
type ExchainClientInterface interface {
BlockByNumber(ctx context.Context, number *big.Int) (*wrapper.BlkWrapper, error)
GetWithdrawalProof(ctx context.Context, param exchain.ExChainWithdrawalParam) ([][]byte, error)
Close()
}
......@@ -3,9 +3,9 @@ package dial
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/exchain/go-exchain/op-node/rollup"
"github.com/exchain/go-exchain/op-service/eth"
"github.com/ethereum/go-ethereum/common"
)
// RollupClientInterface is an interface for providing a RollupClient
......@@ -16,6 +16,8 @@ type RollupClientInterface interface {
RollupConfig(ctx context.Context) (*rollup.Config, error)
StartSequencer(ctx context.Context, unsafeHead common.Hash) error
SequencerActive(ctx context.Context) (bool, error)
WithdrawalProof(ctx context.Context, txHash common.Hash) (*eth.WithdrawalProof, error)
WithdrawalTxs(ctx context.Context, blockNum uint64) ([]common.Hash, error)
Close()
}
......
package eth
import (
"github.com/ethereum/go-ethereum/common"
"math/big"
)
type WithdrawalProof struct {
Output OutputV0
Proof []Bytes32
Value *big.Int
User common.Address
Coin []byte
}
......@@ -26,6 +26,12 @@ func (r *RollupClient) WithdrawalProof(ctx context.Context, txHash common.Hash)
return output, err
}
func (r *RollupClient) WithdrawalTxs(ctx context.Context, blockNum uint64) ([]common.Hash, error) {
var output []common.Hash
err := r.rpc.CallContext(ctx, &output, "optimism_withdrawalTxs", hexutil.Uint64(blockNum))
return output, err
}
func (r *RollupClient) OutputAtBlock(ctx context.Context, blockNum uint64) (*eth.OutputResponse, error) {
var output *eth.OutputResponse
err := r.rpc.CallContext(ctx, &output, "optimism_outputAtBlock", hexutil.Uint64(blockNum))
......
......@@ -107,6 +107,13 @@ library Hashing {
return keccak256(abi.encode(_tx.nonce, _tx.sender, _tx.target, _tx.value, _tx.gasLimit, _tx.data));
}
/// @notice Derives the withdrawal hash according to the encoding in the L2.
/// @param _param Withdrawal param to hash.
/// @return Hashed withdrawal param.
function hashExChainWithdrawal(Types.ExChainWithdrawalParam memory _param) internal pure returns (bytes32) {
return keccak256(abi.encode(_param.user, _param.coin, _param.value, _param.txHash));
}
/// @notice Hashes the various elements of an output root proof into an output root hash which
/// can be used to check if the proof is valid.
/// @param _outputRootProof Output root proof which should hash to an output root.
......
......@@ -67,4 +67,19 @@ library Types {
uint256 gasLimit;
bytes data;
}
struct ExChainWithdrawalParam {
uint256 value;
address user;
bytes coin;
bytes32 txHash;
}
struct BatchExChainWithdrawalParam {
uint256 value;
address user;
bytes coin;
bytes32 txHash;
bytes[] _withdrawalProof;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment