Skip to content
This repository was archived by the owner on Jul 5, 2024. It is now read-only.

Conform to nitro's DataAvailabilityProvider interface #1

Draft
wants to merge 4 commits into
base: eigenda
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
url = https://github.com/google/brotli.git
[submodule "contracts"]
path = contracts
url = https://github.com/OffchainLabs/nitro-contracts.git
branch = develop
url = https://github.com/Layr-Labs/nitro-contracts.git
branch = afk/eigenDA-compatible-inbox
[submodule "arbitrator/wasm-testsuite/testsuite"]
path = arbitrator/wasm-testsuite/testsuite
url = https://github.com/WebAssembly/testsuite.git
Expand Down
2 changes: 1 addition & 1 deletion arbitrator/wasm-testsuite/testsuite
Submodule testsuite updated 157 files
43 changes: 33 additions & 10 deletions arbnode/batch_poster.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ var (
const (
batchPosterSimpleRedisLockKey = "node.batch-poster.redis-lock.simple-lock-key"

sequencerBatchPostMethodName = "addSequencerL2BatchFromOrigin0"
sequencerBatchPostWithBlobsMethodName = "addSequencerL2BatchFromBlobs"
sequencerBatchPostMethodName = "addSequencerL2BatchFromOrigin0"
sequencerBatchPostWithBlobsMethodName = "addSequencerL2BatchFromBlobs"
sequencerBatchPostWithEigendaMethodName = "addSequencerL2BatchFromEigenDA"
)

type batchPosterPosition struct {
Expand Down Expand Up @@ -847,19 +848,38 @@ func (b *BatchPoster) encodeAddBatch(
l2MessageData []byte,
delayedMsg uint64,
use4844 bool,
useEigenDA bool,
Comment on lines 850 to +851

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: feel like an enum (e.g, DataSource) would be the best representation for this

eigenDaBlobInfo *eigenda.EigenDABlobInfo,
) ([]byte, []kzg4844.Blob, error) {
methodName := sequencerBatchPostMethodName
if use4844 {
methodName = sequencerBatchPostWithBlobsMethodName
}

if useEigenDA {
methodName = sequencerBatchPostWithEigendaMethodName
}

method, ok := b.seqInboxABI.Methods[methodName]
if !ok {
return nil, nil, errors.New("failed to find add batch method")
}
var calldata []byte
var kzgBlobs []kzg4844.Blob
var err error
if use4844 {

if useEigenDA {
calldata, err = method.Inputs.Pack(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should prolly be checking this error

seqNum,
eigenDaBlobInfo.BlobVerificationProof,
eigenDaBlobInfo.BlobHeader,
new(big.Int).SetUint64(delayedMsg),
b.config().gasRefunder,
new(big.Int).SetUint64(uint64(prevMsgNum)),
new(big.Int).SetUint64(uint64(newMsgNum)),
)
kzgBlobs, err = blobs.EncodeBlobs(l2MessageData)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where do we override this? If not mistaken this is using the same encoding for 4844 blobs

} else if use4844 {
kzgBlobs, err = blobs.EncodeBlobs(l2MessageData)
if err != nil {
return nil, nil, fmt.Errorf("failed to encode blobs: %w", err)
Expand Down Expand Up @@ -907,7 +927,7 @@ func estimateGas(client rpc.ClientInterface, ctx context.Context, params estimat
return uint64(gas), err
}

func (b *BatchPoster) estimateGas(ctx context.Context, sequencerMessage []byte, delayedMessages uint64, realData []byte, realBlobs []kzg4844.Blob, realNonce uint64, realAccessList types.AccessList) (uint64, error) {
func (b *BatchPoster) estimateGas(ctx context.Context, sequencerMessage []byte, delayedMessages uint64, realData []byte, realBlobs []kzg4844.Blob, realNonce uint64, realAccessList types.AccessList, eigenDaBlobInfo *eigenda.EigenDABlobInfo) (uint64, error) {
config := b.config()
rpcClient := b.l1Reader.Client()
rawRpcClient := rpcClient.Client()
Expand Down Expand Up @@ -949,7 +969,7 @@ func (b *BatchPoster) estimateGas(ctx context.Context, sequencerMessage []byte,
// However, we set nextMsgNum to 1 because it is necessary for a correct estimation for the final to be non-zero.
// Because we're likely estimating against older state, this might not be the actual next message,
// but the gas used should be the same.
data, kzgBlobs, err := b.encodeAddBatch(abi.MaxUint256, 0, 1, sequencerMessage, delayedMessages, len(realBlobs) > 0)
data, kzgBlobs, err := b.encodeAddBatch(abi.MaxUint256, 0, 1, sequencerMessage, delayedMessages, len(realBlobs) > 0, true, eigenDaBlobInfo)
if err != nil {
return 0, err
}
Expand Down Expand Up @@ -1224,26 +1244,29 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
}
}

var blobInfo *eigenda.EigenDABlobInfo
var blobID *eigenda.EigenDABlobID

if b.daWriter == nil && b.eigenDAWriter != nil {
log.Info("Start to write data to eigenda: ", "data", hex.EncodeToString(sequencerMsg))
daRef, err := b.eigenDAWriter.Store(ctx, sequencerMsg)
blobID, blobInfo, err = b.eigenDAWriter.Store(ctx, sequencerMsg)
if err != nil {
if config.DisableEigenDAFallbackStoreDataOnChain {
log.Warn("Falling back to storing data on chain", "err", err)
return false, errors.New("unable to post batch to EigenDA and fallback storing data on chain is disabled")
}
}

pointer, err := b.eigenDAWriter.Serialize(daRef)
pointer, err := b.eigenDAWriter.Serialize(blobID)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not?

Suggested change
pointer, err := b.eigenDAWriter.Serialize(blobID)
sequencerMsg, err = b.eigenDAWriter.Serialize(blobID)

if err != nil {
log.Warn("DaRef serialization failed", "err", err)
return false, errors.New("DaRef serialization failed")
}
log.Info("EigenDA transaction receipt(data pointer): ", "hash", hex.EncodeToString(daRef.BatchHeaderHash), "index", daRef.BlobIndex)
log.Info("EigenDA transaction receipt(data pointer): ", "hash", hex.EncodeToString(blobID.BatchHeaderHash), "index", blobID.BlobIndex)
sequencerMsg = pointer
}

data, kzgBlobs, err := b.encodeAddBatch(new(big.Int).SetUint64(batchPosition.NextSeqNum), batchPosition.MessageCount, b.building.msgCount, sequencerMsg, b.building.segments.delayedMsg, b.building.use4844)
data, kzgBlobs, err := b.encodeAddBatch(new(big.Int).SetUint64(batchPosition.NextSeqNum), batchPosition.MessageCount, b.building.msgCount, sequencerMsg, b.building.segments.delayedMsg, b.building.use4844, true, blobInfo)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we be binding this boolean as a config value to the building type?

if err != nil {
return false, err
}
Expand All @@ -1258,7 +1281,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error)
// In theory, this might reduce gas usage, but only by a factor that's already
// accounted for in `config.ExtraBatchGas`, as that same factor can appear if a user
// posts a new delayed message that we didn't see while gas estimating.
gasLimit, err := b.estimateGas(ctx, sequencerMsg, lastPotentialMsg.DelayedMessagesRead, data, kzgBlobs, nonce, accessList)
gasLimit, err := b.estimateGas(ctx, sequencerMsg, lastPotentialMsg.DelayedMessagesRead, data, kzgBlobs, nonce, accessList, blobInfo)
if err != nil {
return false, err
}
Expand Down
2 changes: 1 addition & 1 deletion arbnode/inbox_tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ func (t *InboxTracker) AddSequencerBatches(ctx context.Context, client arbutil.L
if t.blobReader != nil {
daProviders = append(daProviders, arbstate.NewDAProviderBlobReader(t.blobReader))
}
multiplexer := arbstate.NewInboxMultiplexer(backend, prevbatchmeta.DelayedMessageCount, daProviders, t.eigenDA, arbstate.KeysetValidate)
multiplexer := arbstate.NewInboxMultiplexer(backend, prevbatchmeta.DelayedMessageCount, daProviders, arbstate.KeysetValidate)
batchMessageCounts := make(map[uint64]arbutil.MessageIndex)
currentpos := prevbatchmeta.MessageCount + 1
for {
Expand Down
25 changes: 25 additions & 0 deletions arbnode/sequencer_inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/offchainlabs/nitro/arbstate"
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/das/eigenda"

"github.com/offchainlabs/nitro/solgen/go/bridgegen"
)
Expand All @@ -35,6 +36,7 @@ const (
batchDataSeparateEvent
batchDataNone
batchDataBlobHashes
batchDataEigenDA
)

func init() {
Expand Down Expand Up @@ -164,6 +166,24 @@ func (m *SequencerInboxBatch) getSequencerData(ctx context.Context, client arbut
data = append(data, h[:]...)
}
return data, nil
case batchDataEigenDA:
// get the transaction data from the log
tx, err := arbutil.GetLogTransaction(ctx, client, m.rawLog)
if err != nil {
return nil, err
}
// get the input data from the transaction
// TODO: decide on if you want to parse it here or parse it upstream, I've decided to parse it upstream and include all of the calldata in the batch
calldata := tx.Data()

// append the eigenDA header flag to the front
data := []byte{eigenda.EigenDAMessageHeaderFlag}
data = append(data, calldata[:]...)

// format of eigenDA data is
// [0 - 1] header flag
// [1 - len(data)] calldata
return data, nil
default:
return nil, fmt.Errorf("batch has invalid data location %v", m.dataLocation)
}
Expand Down Expand Up @@ -199,6 +219,11 @@ func (m *SequencerInboxBatch) Serialize(ctx context.Context, client arbutil.L1In

m.serialized = fullData
return fullData, nil

// in the case of eigenDA the serialized data looks like this
// [0-40] Header Vals
// [40-41]eigenDA header flag

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
// [40-41]eigenDA header flag
// [40-41] eigenDA header flag

// [41 - len(fullData)] transaction calldata
}

func (i *SequencerInbox) LookupBatchesInRange(ctx context.Context, from, to *big.Int) ([]*SequencerInboxBatch, error) {
Expand Down
55 changes: 33 additions & 22 deletions arbstate/inbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ var (
ErrInvalidBlobDataFormat = errors.New("blob batch data is not a list of hashes as expected")
)

func parseSequencerMessage(ctx context.Context, batchNum uint64, batchBlockHash common.Hash, data []byte, daProviders []DataAvailabilityProvider, eigenDAReader eigenda.EigenDAReader, keysetValidationMode KeysetValidationMode) (*sequencerMessage, error) {
func parseSequencerMessage(ctx context.Context, batchNum uint64, batchBlockHash common.Hash, data []byte, daProviders []DataAvailabilityProvider, keysetValidationMode KeysetValidationMode) (*sequencerMessage, error) {
if len(data) < 40 {
return nil, errors.New("sequencer message missing L1 header")
}
Expand All @@ -82,6 +82,8 @@ func parseSequencerMessage(ctx context.Context, batchNum uint64, batchBlockHash
afterDelayedMessages: binary.BigEndian.Uint64(data[32:40]),
segments: [][]byte{},
}

// payload is the rest of the data after the header
payload := data[40:]
log.Info("Inbox parse sequencer message: ", "payload", hex.EncodeToString(payload))

Expand All @@ -101,23 +103,6 @@ func parseSequencerMessage(ctx context.Context, batchNum uint64, batchBlockHash
foundDA := false
var err error

// detect eigenda message from byte
if eigenda.IsEigenDAMessageHeaderByte(payload[0]) {
if eigenDAReader == nil {
log.Error("No EigenDA Reader configured, but sequencer message found with EigenDA header")
} else {
var err error
payload, err = eigenda.RecoverPayloadFromEigenDABatch(ctx, payload[1:], eigenDAReader, nil)
if err != nil {
return nil, err
}
if payload == nil {
return parsedMsg, nil
}
foundDA = true
}
}

for _, provider := range daProviders {
if provider != nil && provider.IsValidHeaderByte(payload[0]) {
payload, err = provider.RecoverPayloadFromBatch(ctx, batchNum, batchBlockHash, data, nil, keysetValidationMode)
Expand Down Expand Up @@ -385,6 +370,34 @@ func (b *dAProviderForBlobReader) RecoverPayloadFromBatch(
return payload, nil
}

// NewDAProviderEigenDA is generally meant to be only used by nitro.
// DA Providers should implement methods in the DataAvailabilityProvider interface independently
func NewDAProviderEigenDA(eigenDAReader eigenda.EigenDAReader) *daProviderForEigenDA {
return &daProviderForEigenDA{
eigenDAReader: eigenDAReader,
}
}

type daProviderForEigenDA struct {
eigenDAReader eigenda.EigenDAReader
}

func (e *daProviderForEigenDA) IsValidHeaderByte(headerByte byte) bool {
return eigenda.IsEigenDAMessageHeaderByte(headerByte)
}

func (e *daProviderForEigenDA) RecoverPayloadFromBatch(
ctx context.Context,
batchNum uint64,
batchBlockHash common.Hash,
sequencerMsg []byte,
preimages map[arbutil.PreimageType]map[common.Hash][]byte,
keysetValidationMode KeysetValidationMode,
) ([]byte, error) {
// we start from the 41st byte of sequencerMsg because bytes 0 - 40 are the header, and 40 - 41 is the eigenDA header flag
return eigenda.RecoverPayloadFromEigenDABatch(ctx, sequencerMsg[41:], e.eigenDAReader, preimages)
}

type KeysetValidationMode uint8

const KeysetValidate KeysetValidationMode = 0
Expand All @@ -395,7 +408,6 @@ type inboxMultiplexer struct {
backend InboxBackend
delayedMessagesRead uint64
daProviders []DataAvailabilityProvider
eigenDAReader eigenda.EigenDAReader
cachedSequencerMessage *sequencerMessage
cachedSequencerMessageNum uint64
cachedSegmentNum uint64
Expand All @@ -405,12 +417,11 @@ type inboxMultiplexer struct {
keysetValidationMode KeysetValidationMode
}

func NewInboxMultiplexer(backend InboxBackend, delayedMessagesRead uint64, daProviders []DataAvailabilityProvider, eigenDAReader eigenda.EigenDAReader, keysetValidationMode KeysetValidationMode) arbostypes.InboxMultiplexer {
func NewInboxMultiplexer(backend InboxBackend, delayedMessagesRead uint64, daProviders []DataAvailabilityProvider, keysetValidationMode KeysetValidationMode) arbostypes.InboxMultiplexer {
return &inboxMultiplexer{
backend: backend,
delayedMessagesRead: delayedMessagesRead,
daProviders: daProviders,
eigenDAReader: eigenDAReader,
keysetValidationMode: keysetValidationMode,
}
}
Expand All @@ -432,7 +443,7 @@ func (r *inboxMultiplexer) Pop(ctx context.Context) (*arbostypes.MessageWithMeta
}
r.cachedSequencerMessageNum = r.backend.GetSequencerInboxPosition()
var err error
r.cachedSequencerMessage, err = parseSequencerMessage(ctx, r.cachedSequencerMessageNum, batchBlockHash, bytes, r.daProviders, r.eigenDAReader, r.keysetValidationMode)
r.cachedSequencerMessage, err = parseSequencerMessage(ctx, r.cachedSequencerMessageNum, batchBlockHash, bytes, r.daProviders, r.keysetValidationMode)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion arbstate/inbox_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func FuzzInboxMultiplexer(f *testing.F) {
delayedMessage: delayedMsg,
positionWithinMessage: 0,
}
multiplexer := NewInboxMultiplexer(backend, 0, nil, nil, KeysetValidate)
multiplexer := NewInboxMultiplexer(backend, 0, nil, KeysetValidate)
_, err := multiplexer.Pop(context.TODO())
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion brotli
Submodule brotli updated 188 files
16 changes: 9 additions & 7 deletions cmd/replay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ func (r *BlobPreimageReader) Initialize(ctx context.Context) error {

// struct for recovering data from preimage, impl interface EigenDAReader

func (dasReader *PreimageEigenDAReader) QueryBlob(ctx context.Context, ref *eigenda.EigenDARef) ([]byte, error) {
dataPointer, err := ref.Serialize()
func (dasReader *PreimageEigenDAReader) QueryBlob(ctx context.Context, id *eigenda.EigenDABlobID) ([]byte, error) {
dataPointer, err := id.Serialize()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -232,12 +232,14 @@ func main() {
keysetValidationMode = arbstate.KeysetDontValidate
}
var daProviders []arbstate.DataAvailabilityProvider
// TODO: add dasReader of type eigenda.EigenDAReader when it conforms to interface
// if dasReader != nil {
// daProviders = append(daProviders, arbstate.NewDAProviderDAS(dasReader))
// }

if dasReader != nil {
daProviders = append(daProviders, arbstate.NewDAProviderEigenDA(dasReader))
}
daProviders = append(daProviders, arbstate.NewDAProviderBlobReader(&BlobPreimageReader{}))
inboxMultiplexer := arbstate.NewInboxMultiplexer(backend, delayedMessagesRead, daProviders, dasReader, keysetValidationMode)

daProviders = append(daProviders, arbstate.NewDAProviderDAS(&PreimageDASReader{}))
inboxMultiplexer := arbstate.NewInboxMultiplexer(backend, delayedMessagesRead, daProviders, keysetValidationMode)
ctx := context.Background()
message, err := inboxMultiplexer.Pop(ctx)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion contracts
Loading