Skip to content

Commit

Permalink
txDAG transfer (#28)
Browse files Browse the repository at this point in the history
* txDAG transfer

* encode/decode txDAG data with ABI

* set txDAG receiver to a special address

---------

Co-authored-by: andyzhang2023 <[email protected]>

merge conflict

fix conflict
  • Loading branch information
andyzhang2023 authored and welkin22 committed Nov 19, 2024
1 parent 71f4525 commit a70fe85
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ var (
utils.RollupHaltOnIncompatibleProtocolVersionFlag,
utils.RollupSuperchainUpgradesFlag,
utils.ParallelTxDAGFlag,
utils.ParallelTxDAGSenderPrivFlag,
configFileFlag,
utils.LogDebugFlag,
utils.LogBacktraceAtFlag,
Expand Down
14 changes: 14 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,13 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server.
Usage: "enable opcode optimization",
Category: flags.VMCategory,
}

ParallelTxDAGSenderPrivFlag = &cli.StringFlag{
Name: "parallel.txdagsenderpriv",
Usage: "private key of the sender who sends the TxDAG transactions",
Value: "",
Category: flags.VMCategory,
}
)

var (
Expand Down Expand Up @@ -1999,6 +2006,13 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
cfg.EnableParallelTxDAG = ctx.Bool(ParallelTxDAGFlag.Name)
}

if ctx.IsSet(ParallelTxDAGSenderPrivFlag.Name) {
priHex := ctx.String(ParallelTxDAGSenderPrivFlag.Name)
if cfg.Miner.ParallelTxDAGSenderPriv, err = crypto.HexToECDSA(priHex); err != nil {
Fatalf("Failed to parse txdag private key of %s, err: %v", ParallelTxDAGSenderPrivFlag.Name, err)
}
}

if ctx.IsSet(VMOpcodeOptimizeFlag.Name) {
cfg.EnableOpcodeOptimizing = ctx.Bool(VMOpcodeOptimizeFlag.Name)
if cfg.EnableOpcodeOptimizing {
Expand Down
3 changes: 3 additions & 0 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package miner

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
Expand Down Expand Up @@ -109,6 +110,8 @@ type Config struct {
EffectiveGasCeil uint64 // if non-zero, a gas ceiling to apply independent of the header's gaslimit value

Mev MevConfig // Mev configuration

ParallelTxDAGSenderPriv *ecdsa.PrivateKey // The private key for the parallel tx DAG sender
}

// DefaultConfig contains default settings for miner.
Expand Down
81 changes: 81 additions & 0 deletions miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package miner

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
Expand All @@ -40,6 +41,7 @@ import (
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth/tracers"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/log"
Expand Down Expand Up @@ -102,6 +104,10 @@ var (
txErrReplayMeter = metrics.NewRegisteredMeter("miner/tx/replay", nil)
)

var (
DefaultTxDAGAddress = common.HexToAddress("0xda90000000000000000000000000000000000000")
)

// environment is the worker's current environment and holds all
// information of the sealing block generation.
type environment struct {
Expand Down Expand Up @@ -916,10 +922,32 @@ func (w *worker) commitTransactions(env *environment, plainTxs, blobTxs *transac
}
var coalescedLogs []*types.Log

//append the tx DAG transaction to the block
appendTxDAG := func() {
// whether enable TxDAG
if !w.chain.TxDAGEnabledWhenMine() {
return
}
// TODO this is a placeholder for the tx DAG data that will be generated by the stateDB
txForDAG, err := w.generateDAGTx(env.state, env.signer, env.tcount, env.coinbase)
if err != nil {
log.Warn("failed to generate DAG tx", "err", err)
return
}
logs, err := w.commitTransaction(env, txForDAG)
if err != nil {
log.Warn("failed to commit DAG tx", "err", err)
return
}
coalescedLogs = append(coalescedLogs, logs...)
env.tcount++
}

for {
// Check interruption signal and abort building if it's fired.
if interrupt != nil {
if signal := interrupt.Load(); signal != commitInterruptNone {
appendTxDAG()
return signalToErr(signal)
}
}
Expand Down Expand Up @@ -1018,6 +1046,7 @@ func (w *worker) commitTransactions(env *environment, plainTxs, blobTxs *transac
txErrUnknownMeter.Mark(1)
}
}
appendTxDAG()
if !w.isRunning() && len(coalescedLogs) > 0 {
// We don't push the pendingLogsEvent while we are sealing. The reason is that
// when we are sealing, the worker will regenerate a sealing block every 3 seconds.
Expand All @@ -1036,6 +1065,58 @@ func (w *worker) commitTransactions(env *environment, plainTxs, blobTxs *transac
return nil
}

// generateDAGTx generates a DAG transaction for the block
func (w *worker) generateDAGTx(statedb *state.StateDB, signer types.Signer, txIndex int, coinbase common.Address) (*types.Transaction, error) {
if statedb == nil {
return nil, fmt.Errorf("failed to get state db, env.state=nil")
}

if signer == nil {
return nil, fmt.Errorf("current signer is nil")
}

//privateKey, err := crypto.HexToECDSA(privateKeyHex)
sender := w.config.ParallelTxDAGSenderPriv
receiver := DefaultTxDAGAddress
if sender == nil {
return nil, fmt.Errorf("missing sender private key")
}

// get txDAG data from the stateDB
txDAG, err := statedb.ResolveTxDAG(txIndex, []common.Address{coinbase, params.OptimismBaseFeeRecipient, params.OptimismL1FeeRecipient})
if txDAG == nil {
return nil, err
}
// txIndex is the index of this txDAG transaction
txDAG.SetTxDep(txIndex, types.TxDep{Flags: &types.NonDependentRelFlag})

publicKey := sender.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return nil, fmt.Errorf("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)

// get nonce from the
nonce := statedb.GetNonce(fromAddress)

data, err := types.EncodeTxDAGCalldata(txDAG)
if err != nil {
return nil, fmt.Errorf("failed to encode txDAG, err: %v", err)
}

// Create the transaction
tx := types.NewTransaction(nonce, receiver, big.NewInt(0), 21100, big.NewInt(0), data)

// Sign the transaction with the private key
signedTx, err := types.SignTx(tx, signer, sender)
if err != nil {
return nil, fmt.Errorf("failed to sign transaction, err: %v", err)
}

return signedTx, nil
}

// generateParams wraps various of settings for generating sealing task.
type generateParams struct {
timestamp uint64 // The timestamp for sealing task
Expand Down

0 comments on commit a70fe85

Please sign in to comment.