Skip to content

Commit

Permalink
Merge tag 'v3.0.1' into release/v3.x-fh
Browse files Browse the repository at this point in the history
Arbitrum Nitro v3.0.1
  • Loading branch information
sduchesneau committed Jun 17, 2024
2 parents 1c9a0db + cf4b74e commit 549ae25
Show file tree
Hide file tree
Showing 52 changed files with 1,280 additions and 1,508 deletions.
7 changes: 3 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# golangci-lint configuration

run:
skip-dirs:
- go-ethereum
- fastcache

timeout: 10m

issues:
exclude-dirs:
- go-ethereum
- fastcache
exclude-rules:
- path: _test\.go
linters:
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ COPY ./scripts/download-machine.sh .
#RUN ./download-machine.sh consensus-v11 0xf4389b835497a910d7ba3ebfb77aa93da985634f3c052de1290360635be40c4a
#RUN ./download-machine.sh consensus-v11.1 0x68e4fe5023f792d4ef584796c84d710303a5e12ea02d6e37e2b5e9c4332507c4
#RUN ./download-machine.sh consensus-v20 0x8b104a2e80ac6165dc58b9048de12f301d70b02a0ab51396c22b4b4b802a16a4
RUN ./download-machine.sh consensus-v30-rc.2 0xb0de9cb89e4d944ae6023a3b62276e54804c242fd8c4c2d8e6cc4450f5fa8b1b
RUN ./download-machine.sh consensus-v30 0xb0de9cb89e4d944ae6023a3b62276e54804c242fd8c4c2d8e6cc4450f5fa8b1b

FROM golang:1.21.10-bookworm as node-builder
WORKDIR /workspace
Expand Down
39 changes: 38 additions & 1 deletion arbnode/batch_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ type BatchPoster struct {

batchReverted atomic.Bool // indicates whether data poster batch was reverted
nextRevertCheckBlock int64 // the last parent block scanned for reverting batches
postedFirstBatch bool // indicates if batch poster has posted the first batch

accessList func(SequencerInboxAccs, AfterDelayedMessagesRead int) types.AccessList
}
Expand All @@ -127,6 +128,10 @@ const (
l1BlockBoundIgnore
)

type BatchPosterDangerousConfig struct {
AllowPostingFirstBatchWhenSequencerMessageCountMismatch bool `koanf:"allow-posting-first-batch-when-sequencer-message-count-mismatch"`
}

type BatchPosterConfig struct {
Enable bool `koanf:"enable"`
DisableDapFallbackStoreDataOnChain bool `koanf:"disable-dap-fallback-store-data-on-chain" reload:"hot"`
Expand Down Expand Up @@ -156,6 +161,7 @@ type BatchPosterConfig struct {
L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"`
UseAccessLists bool `koanf:"use-access-lists" reload:"hot"`
GasEstimateBaseFeeMultipleBips arbmath.Bips `koanf:"gas-estimate-base-fee-multiple-bips"`
Dangerous BatchPosterDangerousConfig `koanf:"dangerous"`

gasRefunder common.Address
l1BlockBound l1BlockBound
Expand Down Expand Up @@ -1265,7 +1271,37 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
}
}

data, kzgBlobs, err := b.encodeAddBatch(new(big.Int).SetUint64(batchPosition.NextSeqNum), batchPosition.MessageCount, b.building.msgCount, sequencerMsg, b.building.segments.delayedMsg, b.building.use4844)
prevMessageCount := batchPosition.MessageCount
if b.config().Dangerous.AllowPostingFirstBatchWhenSequencerMessageCountMismatch && !b.postedFirstBatch {
// AllowPostingFirstBatchWhenSequencerMessageCountMismatch can be used when the
// message count stored in batch poster's database gets out
// of sync with the sequencerReportedSubMessageCount stored in the parent chain.
//
// An example of when this out of sync issue can happen:
// 1. Batch poster is running fine, but then it shutdowns for more than 24h.
// 2. While the batch poster is down, someone sends a transaction to the parent chain
// smart contract to move a message from the delayed inbox to the main inbox.
// This will not update sequencerReportedSubMessageCount in the parent chain.
// 3. When batch poster starts again, the inbox reader will update the
// message count that is maintained in the batch poster's database to be equal to
// (sequencerReportedSubMessageCount that is stored in parent chain) +
// (the amount of delayed messages that were moved from the delayed inbox to the main inbox).
// At this moment the message count stored on batch poster's database gets out of sync with
// the sequencerReportedSubMessageCount stored in the parent chain.

// When the first batch is posted, sequencerReportedSubMessageCount in
// the parent chain will be updated to be equal to the new message count provided
// by the batch poster, which will make this out of sync issue disappear.
// That is why this strategy is only applied for the first batch posted after
// startup.

// If prevMessageCount is set to zero, sequencer inbox's smart contract allows
// to post a batch even if sequencerReportedSubMessageCount is not equal
// to the provided prevMessageCount
prevMessageCount = 0
}

data, kzgBlobs, err := b.encodeAddBatch(new(big.Int).SetUint64(batchPosition.NextSeqNum), prevMessageCount, b.building.msgCount, sequencerMsg, b.building.segments.delayedMsg, b.building.use4844)
if err != nil {
return false, err
}
Expand Down Expand Up @@ -1306,6 +1342,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
if err != nil {
return false, err
}
b.postedFirstBatch = true
log.Info(
"BatchPoster: batch sent",
"sequenceNumber", batchPosition.NextSeqNum,
Expand Down
54 changes: 51 additions & 3 deletions arbnode/dataposter/data_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ 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/holiman/uint256"
"github.com/offchainlabs/nitro/arbnode/dataposter/dbstorage"
"github.com/offchainlabs/nitro/arbnode/dataposter/externalsigner"
"github.com/offchainlabs/nitro/arbnode/dataposter/noop"
"github.com/offchainlabs/nitro/arbnode/dataposter/slice"
"github.com/offchainlabs/nitro/arbnode/dataposter/storage"
Expand Down Expand Up @@ -255,6 +255,50 @@ func rpcClient(ctx context.Context, opts *ExternalSignerCfg) (*rpc.Client, error
)
}

// TxToSignTxArgs converts transaction to SendTxArgs. This is needed for
// external signer to specify From field.
func TxToSignTxArgs(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()
var (
blobs []kzg4844.Blob
commitments []kzg4844.Commitment
proofs []kzg4844.Proof
)
if tx.BlobTxSidecar() != nil {
blobs = tx.BlobTxSidecar().Blobs
commitments = tx.BlobTxSidecar().Commitments
proofs = tx.BlobTxSidecar().Proofs
}
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()),
BlobFeeCap: (*hexutil.Big)(tx.BlobGasFeeCap()),
BlobHashes: tx.BlobHashes(),
Blobs: blobs,
Commitments: commitments,
Proofs: proofs,
}, 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 @@ -273,7 +317,7 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com
// RLP encoded transaction object.
// https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_signtransaction
var data hexutil.Bytes
args, err := externalsigner.TxToSignTxArgs(addr, tx)
args, err := TxToSignTxArgs(addr, tx)
if err != nil {
return nil, fmt.Errorf("error converting transaction to sendTxArgs: %w", err)
}
Expand All @@ -285,7 +329,11 @@ func externalSigner(ctx context.Context, opts *ExternalSignerCfg) (signerFn, com
return nil, fmt.Errorf("unmarshaling signed transaction: %w", err)
}
hasher := types.LatestSignerForChainID(tx.ChainId())
if h := hasher.Hash(args.ToTransaction()); h != hasher.Hash(signedTx) {
gotTx, err := args.ToTransaction()
if err != nil {
return nil, fmt.Errorf("converting transaction arguments into transaction: %w", err)
}
if h := hasher.Hash(gotTx); h != hasher.Hash(signedTx) {
return nil, fmt.Errorf("transaction: %x from external signer differs from request: %x", hasher.Hash(signedTx), h)
}
return signedTx, nil
Expand Down
22 changes: 8 additions & 14 deletions arbnode/dataposter/dataposter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"math/big"
"net/http"
"testing"
"time"

Expand All @@ -14,11 +13,11 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rpc"
"github.com/google/go-cmp/cmp"
"github.com/holiman/uint256"
"github.com/offchainlabs/nitro/arbnode/dataposter/externalsigner"
"github.com/offchainlabs/nitro/arbnode/dataposter/externalsignertest"
"github.com/offchainlabs/nitro/util/arbmath"
)
Expand Down Expand Up @@ -58,14 +57,14 @@ func TestParseReplacementTimes(t *testing.T) {
}
}

func signerTestCfg(addr common.Address) (*ExternalSignerCfg, error) {
func signerTestCfg(addr common.Address, url string) (*ExternalSignerCfg, error) {
cp, err := externalsignertest.CertPaths()
if err != nil {
return nil, fmt.Errorf("getting certificates path: %w", err)
}
return &ExternalSignerCfg{
Address: common.Bytes2Hex(addr.Bytes()),
URL: externalsignertest.SignerURL,
URL: url,
Method: externalsignertest.SignerMethod,
RootCA: cp.ServerCert,
ClientCert: cp.ClientCert,
Expand Down Expand Up @@ -106,15 +105,14 @@ var (
)

func TestExternalSigner(t *testing.T) {
httpSrv, srv := externalsignertest.NewServer(t)
cert, key := "./testdata/localhost.crt", "./testdata/localhost.key"
srv := externalsignertest.NewServer(t)
go func() {
if err := httpSrv.ListenAndServeTLS(cert, key); err != nil && err != http.ErrServerClosed {
t.Errorf("ListenAndServeTLS() unexpected error: %v", err)
if err := srv.Start(); err != nil {
log.Error("Failed to start external signer server:", err)
return
}
}()
signerCfg, err := signerTestCfg(srv.Address)
signerCfg, err := signerTestCfg(srv.Address, srv.URL())
if err != nil {
t.Fatalf("Error getting signer test config: %v", err)
}
Expand Down Expand Up @@ -143,11 +141,7 @@ func TestExternalSigner(t *testing.T) {
if err != nil {
t.Fatalf("Error signing transaction with external signer: %v", err)
}
args, err := externalsigner.TxToSignTxArgs(addr, tc.tx)
if err != nil {
t.Fatalf("Error converting transaction to sendTxArgs: %v", err)
}
want, err := srv.SignerFn(addr, args.ToTransaction())
want, err := srv.SignerFn(addr, tc.tx)
if err != nil {
t.Fatalf("Error signing transaction: %v", err)
}
Expand Down
115 changes: 0 additions & 115 deletions arbnode/dataposter/externalsigner/externalsigner.go

This file was deleted.

Loading

0 comments on commit 549ae25

Please sign in to comment.