Skip to content

Commit

Permalink
Merge pull request #2037 from OffchainLabs/dataposter_from_field
Browse files Browse the repository at this point in the history
Pass From field from dataposter to external signer
  • Loading branch information
anodar authored Jan 11, 2024
2 parents 4bafeaf + 5795e8a commit 80f2ac8
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 423 deletions.
20 changes: 11 additions & 9 deletions arbnode/batch_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,15 +219,16 @@ var TestBatchPosterConfig = BatchPosterConfig{
}

type BatchPosterOpts struct {
DataPosterDB ethdb.Database
L1Reader *headerreader.HeaderReader
Inbox *InboxTracker
Streamer *TransactionStreamer
SyncMonitor *SyncMonitor
Config BatchPosterConfigFetcher
DeployInfo *chaininfo.RollupAddresses
TransactOpts *bind.TransactOpts
DAWriter das.DataAvailabilityServiceWriter
DataPosterDB ethdb.Database
L1Reader *headerreader.HeaderReader
Inbox *InboxTracker
Streamer *TransactionStreamer
SyncMonitor *SyncMonitor
Config BatchPosterConfigFetcher
DeployInfo *chaininfo.RollupAddresses
TransactOpts *bind.TransactOpts
DAWriter das.DataAvailabilityServiceWriter
ParentChainID *big.Int
}

func NewBatchPoster(ctx context.Context, opts *BatchPosterOpts) (*BatchPoster, error) {
Expand Down Expand Up @@ -291,6 +292,7 @@ func NewBatchPoster(ctx context.Context, opts *BatchPosterOpts) (*BatchPoster, e
MetadataRetriever: b.getBatchPosterPosition,
ExtraBacklog: b.GetBacklogEstimate,
RedisKey: "data-poster.queue",
ParentChainID: opts.ParentChainID,
})
if err != nil {
return nil, err
Expand Down
59 changes: 47 additions & 12 deletions arbnode/dataposter/data_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/go-redis/redis/v8"
"github.com/offchainlabs/nitro/arbnode/dataposter/dbstorage"
"github.com/offchainlabs/nitro/arbnode/dataposter/noop"
Expand Down Expand Up @@ -62,6 +63,7 @@ type DataPoster struct {
replacementTimes []time.Duration
metadataRetriever func(ctx context.Context, blockNum *big.Int) ([]byte, error)
extraBacklog func() uint64
parentChainID *big.Int

// These fields are protected by the mutex.
// TODO: factor out these fields into separate structure, since now one
Expand Down Expand Up @@ -113,6 +115,7 @@ type DataPosterOpts struct {
MetadataRetriever func(ctx context.Context, blockNum *big.Int) ([]byte, error)
ExtraBacklog func() uint64
RedisKey string // Redis storage key
ParentChainID *big.Int
}

func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, error) {
Expand Down Expand Up @@ -172,6 +175,7 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro
errorCount: make(map[uint64]int),
maxFeeCapExpression: expression,
extraBacklog: opts.ExtraBacklog,
parentChainID: opts.ParentChainID,
}
if dp.extraBacklog == nil {
dp.extraBacklog = func() uint64 { return 0 }
Expand All @@ -189,6 +193,7 @@ func NewDataPoster(ctx context.Context, opts *DataPosterOpts) (*DataPoster, erro
},
}
}

return dp, nil
}

Expand Down Expand Up @@ -229,6 +234,35 @@ func rpcClient(ctx context.Context, opts *ExternalSignerCfg) (*rpc.Client, error
)
}

// txToSendTxArgs converts transaction to SendTxArgs. This is needed for
// external signer to specify From field.
func txToSendTxArgs(addr common.Address, tx *types.Transaction) (*apitypes.SendTxArgs, error) {
var to *common.MixedcaseAddress
if tx.To() != nil {
to = new(common.MixedcaseAddress)
*to = common.NewMixedcaseAddress(*tx.To())
}
data := (hexutil.Bytes)(tx.Data())
val := (*hexutil.Big)(tx.Value())
if val == nil {
val = (*hexutil.Big)(big.NewInt(0))
}
al := tx.AccessList()
return &apitypes.SendTxArgs{
From: common.NewMixedcaseAddress(addr),
To: to,
Gas: hexutil.Uint64(tx.Gas()),
GasPrice: (*hexutil.Big)(tx.GasPrice()),
MaxFeePerGas: (*hexutil.Big)(tx.GasFeeCap()),
MaxPriorityFeePerGas: (*hexutil.Big)(tx.GasTipCap()),
Value: *val,
Nonce: hexutil.Uint64(tx.Nonce()),
Data: &data,
AccessList: &al,
ChainID: (*hexutil.Big)(tx.ChainId()),
}, nil
}

// externalSigner returns signer function and ethereum address of the signer.
// Returns an error if address isn't specified or if it can't connect to the
// signer RPC server.
Expand All @@ -242,27 +276,27 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com
return nil, common.Address{}, fmt.Errorf("error connecting external signer: %w", err)
}
sender := common.HexToAddress(opts.Address)

var hasher types.Signer
return func(ctx context.Context, addr common.Address, tx *types.Transaction) (*types.Transaction, error) {
// According to the "eth_signTransaction" API definition, this should be
// RLP encoded transaction object.
// https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction
var data hexutil.Bytes
if err := client.CallContext(ctx, &data, opts.Method, tx); err != nil {
return nil, fmt.Errorf("signing transaction: %w", err)
args, err := txToSendTxArgs(addr, tx)
if err != nil {
return nil, fmt.Errorf("error converting transaction to sendTxArgs: %w", err)
}
var signedTx types.Transaction
if err := rlp.DecodeBytes(data, &signedTx); err != nil {
return nil, fmt.Errorf("error decoding signed transaction: %w", err)
if err := client.CallContext(ctx, &data, opts.Method, args); err != nil {
return nil, fmt.Errorf("making signing request to external signer: %w", err)
}
if hasher == nil {
hasher = types.LatestSignerForChainID(tx.ChainId())
signedTx := &types.Transaction{}
if err := signedTx.UnmarshalBinary(data); err != nil {
return nil, fmt.Errorf("unmarshaling signed transaction: %w", err)
}
if hasher.Hash(tx) != hasher.Hash(&signedTx) {
return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(&signedTx), hasher.Hash(tx))
hasher := types.LatestSignerForChainID(tx.ChainId())
if h := hasher.Hash(args.ToTransaction()); h != hasher.Hash(signedTx) {
return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(signedTx), h)
}
return &signedTx, nil
return signedTx, nil
}, sender, nil
}

Expand Down Expand Up @@ -549,6 +583,7 @@ func (p *DataPoster) PostTransaction(ctx context.Context, dataCreatedAt time.Tim
Value: value,
Data: calldata,
AccessList: accessList,
ChainID: p.parentChainID,
}
fullTx, err := p.signer(ctx, p.Sender(), types.NewTx(&inner))
if err != nil {
Expand Down
Loading

0 comments on commit 80f2ac8

Please sign in to comment.