Skip to content

eth2: catalyst RPC calls and command line options #22320

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

1 change: 1 addition & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ var (
utils.EWASMInterpreterFlag,
utils.EVMInterpreterFlag,
configFileFlag,
utils.CatalystFlag,
}

rpcFlags = []cli.Flag{
Expand Down
1 change: 1 addition & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.SnapshotFlag,
utils.BloomFilterSizeFlag,
cli.HelpFlag,
utils.CatalystFlag,
},
},
}
Expand Down
8 changes: 8 additions & 0 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,11 @@ var (
Usage: "External EVM configuration (default = built-in interpreter)",
Value: "",
}
// Catalyst
CatalystFlag = cli.BoolFlag{
Name: "catalyst",
Usage: "Set geth into catalyst mode",
}
)

// MakeDataDir retrieves the currently requested data directory, terminating
Expand Down Expand Up @@ -1711,6 +1716,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash)
}
}
if ctx.GlobalIsSet(CatalystFlag.Name) {
cfg.Catalyst = true
}
}

// SetDNSDiscoveryDefaults configures DNS discovery with the given URL if
Expand Down
44 changes: 41 additions & 3 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1482,7 +1482,7 @@ func (bc *BlockChain) writeKnownBlock(block *types.Block) error {

current := bc.CurrentBlock()
if block.ParentHash() != current.Hash() {
if err := bc.reorg(current, block); err != nil {
if err := bc.Reorg(current, block); err != nil {
return err
}
}
Expand Down Expand Up @@ -1606,7 +1606,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
if reorg {
// Reorganise the chain if the parent is not the head block
if block.ParentHash() != currentBlock.Hash() {
if err := bc.reorg(currentBlock, block); err != nil {
if err := bc.Reorg(currentBlock, block); err != nil {
return NonStatTy, err
}
}
Expand Down Expand Up @@ -1693,6 +1693,44 @@ func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
return n, err
}

// InsertChainWithoutSealVerification works exactly the same
// except for seal verification, seal verification is omitted
func (bc *BlockChain) InsertChainWithoutSealVerification(chain types.Blocks) (int, error) {
// Sanity check that we have something meaningful to import
if len(chain) == 0 {
return 0, nil
}

bc.blockProcFeed.Send(true)
defer bc.blockProcFeed.Send(false)

// Remove already known canon-blocks
var (
block, prev *types.Block
)
// Do a sanity check that the provided chain is actually ordered and linked
for i := 1; i < len(chain); i++ {
block = chain[i]
prev = chain[i-1]
if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() {
// Chain broke ancestry, log a message (programming error) and skip insertion
log.Error("Non contiguous block insert", "number", block.Number(), "hash", block.Hash(),
"parent", block.ParentHash(), "prevnumber", prev.Number(), "prevhash", prev.Hash())

return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x…], item %d is #%d [%x…] (parent [%x…])", i-1, prev.NumberU64(),
prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4])
}
}
// Pre-checks passed, start the full block imports
bc.wg.Add(1)
bc.chainmu.Lock()
n, err := bc.insertChain(chain, false)
bc.chainmu.Unlock()
bc.wg.Done()

return n, err
}

// insertChain is the internal implementation of InsertChain, which assumes that
// 1) chains are contiguous, and 2) The chain mutex is held.
//
Expand Down Expand Up @@ -2114,7 +2152,7 @@ func (bc *BlockChain) insertSideChain(block *types.Block, it *insertIterator) (i
// reorg takes two blocks, an old chain and a new chain and will reconstruct the
// blocks and inserts them to be part of the new canonical chain and accumulates
// potential missing transactions and post an event about them.
func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
func (bc *BlockChain) Reorg(oldBlock, newBlock *types.Block) error {
var (
newChain types.Blocks
oldChain types.Blocks
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func (b *BlockGen) AddTxWithChain(bc *BlockChain, tx *types.Transaction) {
b.SetCoinbase(common.Address{})
}
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{})
receipt, err := ApplyTransaction(b.config, bc, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, &b.header.GasUsed, vm.Config{}, nil)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
// and uses the input parameters for its environment. It returns the receipt
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, bcctx *vm.BeaconChainContext) (*types.Receipt, error) {
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
if err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ type TxPoolConfig struct {
GlobalQueue uint64 // Maximum number of non-executable transaction slots for all accounts

Lifetime time.Duration // Maximum amount of time non-executable transaction are queued

ProcessTxs bool // Whether transaction processing is enabled upon node's launch
}

// DefaultTxPoolConfig contains the default configurations for the transaction
Expand Down
7 changes: 7 additions & 0 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
return nil, errors.New("no compatible interpreter")
}

type BeaconChainContext struct {
BeaconRoots []common.Hash // Provides information for BEACONSTATEROOT
RandaoMix common.Hash // Provides information for RANDAOMIX
}

// BlockContext provides the EVM with auxiliary information. Once provided
// it shouldn't be modified.
type BlockContext struct {
Expand All @@ -108,6 +113,8 @@ type BlockContext struct {
BlockNumber *big.Int // Provides information for NUMBER
Time *big.Int // Provides information for TIME
Difficulty *big.Int // Provides information for DIFFICULTY

BeaconCtx *BeaconChainContext // Provides eth2-specific information
}

// TxContext provides the EVM with information about a transaction.
Expand Down
26 changes: 26 additions & 0 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,32 @@ func opGasLimit(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) (
return nil, nil
}

func opBeaconStateRoot(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
num := callContext.stack.peek()
num64, overflow := num.Uint64WithOverflow()
if overflow {
num.Clear()
return nil, nil
}
var upper, lower uint64
upper = interpreter.evm.Context.BlockNumber.Uint64()
if upper < 257 {
lower = 0
} else {
lower = upper - 256
}
if num64 >= lower && num64 < upper {
num.SetBytes(interpreter.evm.Context.BeaconCtx.BeaconRoots[num64-lower].Bytes())
} else {
num.Clear()
}
return nil, nil
}
func opRandaoMix(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
callContext.stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.BeaconCtx.RandaoMix.Bytes()))
return nil, nil
}

func opPop(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) {
callContext.stack.pop()
return nil, nil
Expand Down
12 changes: 12 additions & 0 deletions core/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -1021,5 +1021,17 @@ func newFrontierInstructionSet() JumpTable {
halts: true,
writes: true,
},
BEACONSTATEROOT: {
execute: opBeaconStateRoot,
constantGas: GasExtStep,
minStack: minStack(1, 1),
maxStack: maxStack(1, 1),
},
RANDAOMIX: {
execute: opRandaoMix,
constantGas: GasExtStep,
minStack: minStack(0, 1),
maxStack: maxStack(0, 1),
},
}
}
Loading