Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

txDAG transfer by gasless transaction (#28) #150

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ var (
utils.RollupHaltOnIncompatibleProtocolVersionFlag,
utils.RollupSuperchainUpgradesFlag,
utils.ParallelTxDAGFlag,
utils.ParallelTxDAGSenderPrivFlag,
configFileFlag,
utils.LogDebugFlag,
utils.LogBacktraceAtFlag,
Expand Down
17 changes: 16 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/core/txpool/bundlepool"
"math"
"math/big"
"net"
Expand All @@ -35,6 +34,8 @@ import (
"strings"
"time"

"github.com/ethereum/go-ethereum/core/txpool/bundlepool"

pcsclite "github.com/gballet/go-libpcsclite"
gopsutil "github.com/shirou/gopsutil/mem"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -1093,6 +1094,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 @@ -1981,6 +1989,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
8 changes: 6 additions & 2 deletions miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ package miner

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
"math/big"
"sync"
"time"

"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/consensus"
Expand Down Expand Up @@ -107,6 +109,8 @@ type Config struct {
RollupComputePendingBlock bool // Compute the pending block from tx-pool, instead of copying the latest-block

Mev MevConfig // Mev configuration

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

// DefaultConfig contains default settings for miner.
Expand Down
84 changes: 83 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@ package miner

import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
mapset "github.com/deckarep/golang-set/v2"
"math/big"
"sync"
"sync/atomic"
"time"

mapset "github.com/deckarep/golang-set/v2"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/misc"
Expand All @@ -36,6 +38,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 @@ -98,6 +101,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 @@ -893,10 +900,32 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
}
var coalescedLogs []*types.Log

//append the tx DAG transaction to the block
appendTxDAG := func() {
andyzhang2023 marked this conversation as resolved.
Show resolved Hide resolved
// 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 @@ -970,6 +999,7 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
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 @@ -988,6 +1018,58 @@ func (w *worker) commitTransactions(env *environment, txs *transactionsByPriceAn
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 timstamp for sealing task
Expand Down
Loading