Skip to content
This repository has been archived by the owner on May 11, 2024. It is now read-only.

Commit

Permalink
feat(repo): implement EIP-4844 in client (#526)
Browse files Browse the repository at this point in the history
Co-authored-by: maskpp <[email protected]>
  • Loading branch information
davidtaikocha and mask-pp authored Feb 17, 2024
1 parent 6fefa6e commit 103cad2
Show file tree
Hide file tree
Showing 29 changed files with 1,846 additions and 125 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.dll
*.so
*.dylib
.env
bin
coverage.out
prover/dbPath
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
FROM golang:1.21-alpine as builder

RUN apk add --no-cache gcc musl-dev linux-headers git make
RUN apk update && apk add --no-cache --update gcc musl-dev linux-headers git make build-base

WORKDIR /taiko-client
COPY . .
RUN make build

FROM alpine:latest

RUN apk add --no-cache ca-certificates
RUN apk add --no-cache ca-certificates libstdc++

COPY --from=builder /taiko-client/bin/taiko-client /usr/local/bin/

Expand Down
7 changes: 7 additions & 0 deletions cmd/flags/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ var (
Required: true,
Category: driverCategory,
}
L1BeaconEndpoint = &cli.StringFlag{
Name: "l1.beacon",
Usage: "HTTP RPC endpoint of a L1 consensus client",
Required: true,
Category: driverCategory,
}
JWTSecret = &cli.StringFlag{
Name: "jwtSecret",
Usage: "Path to a JWT secret to use for authenticated RPC endpoints",
Expand Down Expand Up @@ -47,6 +53,7 @@ var (

// DriverFlags All driver flags.
var DriverFlags = MergeFlags(CommonFlags, []cli.Flag{
L1BeaconEndpoint,
L2WSEndpoint,
L2AuthEndpoint,
JWTSecret,
Expand Down
6 changes: 6 additions & 0 deletions cmd/flags/proposer.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ var (
Value: false,
Category: proposerCategory,
}
BlobAllowed = &cli.BoolFlag{
Name: "blobAllowed",
Usage: "Send EIP-4844 blob transactions when proposing blocks",
Value: false,
}
L1BlockBuilderTip = &cli.Uint64Flag{
Name: "l1BlockBuilderTip",
Usage: "Amount you wish to tip the L1 block builder",
Expand Down Expand Up @@ -160,5 +165,6 @@ var ProposerFlags = MergeFlags(CommonFlags, []cli.Flag{
MaxTierFeePriceBumps,
ProposeBlockIncludeParentMetaHash,
ProposerAssignmentHookAddress,
BlobAllowed,
L1BlockBuilderTip,
})
17 changes: 15 additions & 2 deletions driver/chain_syncer/calldata/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
anchorTxConstructor "github.com/taikoxyz/taiko-client/driver/anchor_tx_constructor"
"github.com/taikoxyz/taiko-client/driver/chain_syncer/beaconsync"
"github.com/taikoxyz/taiko-client/driver/state"
txlistfetcher "github.com/taikoxyz/taiko-client/driver/txlist_fetcher"
"github.com/taikoxyz/taiko-client/internal/metrics"
eventIterator "github.com/taikoxyz/taiko-client/pkg/chain_iterator/event_iterator"
"github.com/taikoxyz/taiko-client/pkg/rpc"
Expand Down Expand Up @@ -235,11 +236,22 @@ func (s *Syncer) onBlockProposed(
event.Raw.TxIndex,
)
if err != nil {
return fmt.Errorf("failed to fetch original TaikoL1.proposeBlock transaction: %w", err)
return fmt.Errorf("failed to fetch original TaikoL1.ProposeBlock transaction: %w", err)
}

var txListDecoder txlistfetcher.TxListFetcher
if event.Meta.BlobUsed {
txListDecoder = txlistfetcher.NewBlobTxListFetcher(s.rpc)
} else {
txListDecoder = &txlistfetcher.CalldataFetcher{}
}
txListBytes, err := txListDecoder.Fetch(ctx, tx, &event.Meta)
if err != nil {
return fmt.Errorf("failed to decode tx list: %w", err)
}

// Check whether the transactions list is valid.
txListBytes, hint, invalidTxIndex, err := s.txListValidator.ValidateTxList(event.BlockId, tx.Data())
hint, invalidTxIndex, err := s.txListValidator.ValidateTxList(event.BlockId, txListBytes, event.Meta.BlobUsed)
if err != nil {
return fmt.Errorf("failed to validate transactions list: %w", err)
}
Expand All @@ -249,6 +261,7 @@ func (s *Syncer) onBlockProposed(
"blockID", event.BlockId,
"hint", hint,
"invalidTxIndex", invalidTxIndex,
"bytes", len(txListBytes),
)

l1Origin := &rawdb.L1Origin{
Expand Down
1 change: 1 addition & 0 deletions driver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func NewConfigFromCliContext(c *cli.Context) (*Config, error) {
return &Config{
ClientConfig: &rpc.ClientConfig{
L1Endpoint: c.String(flags.L1WSEndpoint.Name),
L1BeaconEndpoint: c.String(flags.L1BeaconEndpoint.Name),
L2Endpoint: c.String(flags.L2WSEndpoint.Name),
L2CheckPoint: l2CheckPoint,
TaikoL1Address: common.HexToAddress(c.String(flags.TaikoL1Address.Name)),
Expand Down
2 changes: 1 addition & 1 deletion driver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type Driver struct {
wg sync.WaitGroup
}

// InitFromCli New initializes the given driver instance based on the command line flags.
// InitFromCli initializes the given driver instance based on the command line flags.
func (d *Driver) InitFromCli(ctx context.Context, c *cli.Context) error {
cfg, err := NewConfigFromCliContext(c)
if err != nil {
Expand Down
59 changes: 59 additions & 0 deletions driver/txlist_fetcher/blob.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package txlistdecoder

import (
"context"
"crypto/sha256"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log"

"github.com/taikoxyz/taiko-client/bindings"
"github.com/taikoxyz/taiko-client/pkg/rpc"
)

type BlobFetcher struct {
rpc *rpc.Client
}

func NewBlobTxListFetcher(rpc *rpc.Client) *BlobFetcher {
return &BlobFetcher{rpc}
}

func (d *BlobFetcher) Fetch(
ctx context.Context,
tx *types.Transaction,
meta *bindings.TaikoDataBlockMetadata,
) ([]byte, error) {
if !meta.BlobUsed {
return nil, errBlobUnused
}

sidecars, err := d.rpc.GetBlobs(ctx, new(big.Int).SetUint64(meta.L1Height+1))
if err != nil {
return nil, err
}

log.Info("Fetch sidecars", "slot", meta.L1Height+1, "sidecars", len(sidecars))

for i, sidecar := range sidecars {
log.Info(
"Block sidecar",
"index", i,
"KzgCommitment", sidecar.KzgCommitment,
"blobHash", common.Bytes2Hex(meta.BlobHash[:]),
)

commitment := kzg4844.Commitment(common.FromHex(sidecar.KzgCommitment))
if kzg4844.CalcBlobHashV1(
sha256.New(),
&commitment,
) == common.BytesToHash(meta.BlobHash[:]) {
return rpc.DecodeBlob(common.FromHex(sidecar.Blob))
}
}

return nil, errSidecarNotFound
}
23 changes: 23 additions & 0 deletions driver/txlist_fetcher/calldata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package txlistdecoder

import (
"context"

"github.com/ethereum/go-ethereum/core/types"
"github.com/taikoxyz/taiko-client/bindings"
"github.com/taikoxyz/taiko-client/bindings/encoding"
)

type CalldataFetcher struct{}

func (d *CalldataFetcher) Fetch(
ctx context.Context,
tx *types.Transaction,
meta *bindings.TaikoDataBlockMetadata,
) ([]byte, error) {
if meta.BlobUsed {
return nil, errBlobUsed
}

return encoding.UnpackTxListBytes(tx.Data())
}
19 changes: 19 additions & 0 deletions driver/txlist_fetcher/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package txlistdecoder

import (
"context"
"errors"

"github.com/ethereum/go-ethereum/core/types"
"github.com/taikoxyz/taiko-client/bindings"
)

var (
errBlobUsed = errors.New("blob is used")
errBlobUnused = errors.New("blob is not used")
errSidecarNotFound = errors.New("sidecar not found")
)

type TxListFetcher interface {
Fetch(ctx context.Context, tx *types.Transaction, meta *bindings.TaikoDataBlockMetadata) ([]byte, error)
}
Loading

0 comments on commit 103cad2

Please sign in to comment.