Skip to content

Commit

Permalink
Adding geths mempool (#1639)
Browse files Browse the repository at this point in the history
* Adding geths mempool

* lint

* rabbit reviews

* adding a unit test

* return err

* update test

* pr comments

* lint
  • Loading branch information
otherview authored Nov 15, 2023
1 parent 8248878 commit ef01370
Show file tree
Hide file tree
Showing 16 changed files with 826 additions and 258 deletions.
13 changes: 12 additions & 1 deletion go/common/gethencoding/geth_encoding.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"strings"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/trie"
"github.com/obscuronet/go-obscuro/go/common"
"github.com/obscuronet/go-obscuro/go/enclave/core"
"github.com/obscuronet/go-obscuro/go/enclave/crypto"

"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -243,7 +245,7 @@ func CreateEthHeaderForBatch(h *common.BatchHeader, secret []byte) (*types.Heade
Difficulty: big.NewInt(0),
Number: h.Number,
GasLimit: h.GasLimit,
GasUsed: 0,
GasUsed: h.GasUsed,
BaseFee: big.NewInt(0).SetUint64(baseFee),
Coinbase: h.Coinbase,
Time: h.Time,
Expand All @@ -252,6 +254,15 @@ func CreateEthHeaderForBatch(h *common.BatchHeader, secret []byte) (*types.Heade
}, nil
}

func CreateEthBlockFromBatch(b *core.Batch) (*types.Block, error) {
blockHeader, err := CreateEthHeaderForBatch(b.Header, nil)
if err != nil {
return nil, fmt.Errorf("unable to create eth block from batch - %w", err)
}

return types.NewBlock(blockHeader, b.Transactions, nil, nil, trie.NewStackTrie(nil)), nil
}

// DecodeParamBytes decodes the parameters byte array into a slice of interfaces
// Helps each calling method to manage the positional data
func DecodeParamBytes(paramBytes []byte) ([]interface{}, error) {
Expand Down
55 changes: 19 additions & 36 deletions go/enclave/enclave.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@ import (
"sync"
"time"

"github.com/obscuronet/go-obscuro/go/common/compression"
"github.com/obscuronet/go-obscuro/go/common/measure"

"github.com/obscuronet/go-obscuro/go/enclave/evm/ethchainadapter"
"github.com/obscuronet/go-obscuro/go/enclave/gas"
"github.com/obscuronet/go-obscuro/go/enclave/storage"

"github.com/obscuronet/go-obscuro/go/enclave/txpool"
"github.com/obscuronet/go-obscuro/go/enclave/vkhandler"

"github.com/obscuronet/go-obscuro/go/common/compression"

"github.com/obscuronet/go-obscuro/go/enclave/components"
"github.com/obscuronet/go-obscuro/go/enclave/nodetype"

Expand Down Expand Up @@ -52,7 +51,6 @@ import (
"github.com/obscuronet/go-obscuro/go/enclave/debugger"
"github.com/obscuronet/go-obscuro/go/enclave/events"

"github.com/obscuronet/go-obscuro/go/enclave/mempool"
"github.com/obscuronet/go-obscuro/go/enclave/rpc"
"github.com/obscuronet/go-obscuro/go/ethadapter/mgmtcontractlib"

Expand Down Expand Up @@ -127,29 +125,9 @@ func NewEnclave(
}
}

zeroTimestamp := uint64(0)
// Initialise the database
chainConfig := params.ChainConfig{
ChainID: big.NewInt(config.ObscuroChainID),
HomesteadBlock: gethcommon.Big0,
DAOForkBlock: gethcommon.Big0,
EIP150Block: gethcommon.Big0,
EIP155Block: gethcommon.Big0,
EIP158Block: gethcommon.Big0,
ByzantiumBlock: gethcommon.Big0,
ConstantinopleBlock: gethcommon.Big0,
PetersburgBlock: gethcommon.Big0,
IstanbulBlock: gethcommon.Big0,
MuirGlacierBlock: gethcommon.Big0,
BerlinBlock: gethcommon.Big0,
LondonBlock: gethcommon.Big0,

CancunTime: &zeroTimestamp,
ShanghaiTime: &zeroTimestamp,
PragueTime: &zeroTimestamp,
VerkleTime: &zeroTimestamp,
}
storage := storage.NewStorageFromConfig(config, &chainConfig, logger)
chainConfig := ethchainadapter.ChainParams(big.NewInt(config.ObscuroChainID))
storage := storage.NewStorageFromConfig(config, chainConfig, logger)

// Initialise the Ethereum "Blockchain" structure that will allow us to validate incoming blocks
// todo (#1056) - valid block
Expand Down Expand Up @@ -200,25 +178,29 @@ func NewEnclave(
dataEncryptionService := crypto.NewDataEncryptionService(logger)
dataCompressionService := compression.NewBrotliDataCompressionService()

memp := mempool.New(config.ObscuroChainID, logger)

crossChainProcessors := crosschain.New(&config.MessageBusAddress, storage, big.NewInt(config.ObscuroChainID), logger)

subscriptionManager := events.NewSubscriptionManager(&rpcEncryptionManager, storage, logger)

gasOracle := gas.NewGasOracle()
blockProcessor := components.NewBlockProcessor(storage, crossChainProcessors, gasOracle, logger)
batchExecutor := components.NewBatchExecutor(storage, crossChainProcessors, genesis, gasOracle, &chainConfig, logger)
batchExecutor := components.NewBatchExecutor(storage, crossChainProcessors, genesis, gasOracle, chainConfig, logger)
sigVerifier, err := components.NewSignatureValidator(config.SequencerID, storage)
registry := components.NewBatchRegistry(storage, logger)
rProducer := components.NewRollupProducer(config.SequencerID, storage, registry, logger)
if err != nil {
logger.Crit("Could not initialise the signature validator", log.ErrKey, err)
}
rollupCompression := components.NewRollupCompression(registry, batchExecutor, dataEncryptionService, dataCompressionService, storage, &chainConfig, logger)
rollupCompression := components.NewRollupCompression(registry, batchExecutor, dataEncryptionService, dataCompressionService, storage, chainConfig, logger)
rConsumer := components.NewRollupConsumer(mgmtContractLib, registry, rollupCompression, storage, logger, sigVerifier)
sharedSecretProcessor := components.NewSharedSecretProcessor(mgmtContractLib, attestationProvider, storage, logger)

blockchain := ethchainadapter.NewEthChainAdapter(big.NewInt(config.ObscuroChainID), registry, storage, logger)
mempool, err := txpool.NewTxPool(blockchain, config.MinGasPrice)
if err != nil {
logger.Crit("unable to init eth tx pool", log.ErrKey, err)
}

var service nodetype.NodeType
if config.NodeType == common.Sequencer {
service = nodetype.NewSequencer(
Expand All @@ -230,9 +212,9 @@ func NewEnclave(
rollupCompression,
logger,
config.HostID,
&chainConfig,
chainConfig,
enclaveKey,
memp,
mempool,
storage,
dataEncryptionService,
dataCompressionService,
Expand All @@ -243,14 +225,15 @@ func NewEnclave(
BatchGasLimit: config.GasLimit,
BaseFee: config.BaseFee,
},
blockchain,
)
} else {
service = nodetype.NewValidator(blockProcessor, batchExecutor, registry, rConsumer, &chainConfig, config.SequencerID, storage, sigVerifier, logger)
service = nodetype.NewValidator(blockProcessor, batchExecutor, registry, rConsumer, chainConfig, config.SequencerID, storage, sigVerifier, logger)
}

chain := l2chain.NewChain(
storage,
&chainConfig,
chainConfig,
genesis,
logger,
registry,
Expand All @@ -263,7 +246,7 @@ func NewEnclave(
}

// TODO ensure debug is allowed/disallowed
debug := debugger.New(chain, storage, &chainConfig)
debug := debugger.New(chain, storage, chainConfig)

logger.Info("Enclave service created with following config", log.CfgKey, config.HostID)
return &enclaveImpl{
Expand Down
153 changes: 153 additions & 0 deletions go/enclave/evm/ethchainadapter/eth_chainadapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package ethchainadapter

import (
"fmt"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool/legacypool"
"github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/params"
"github.com/obscuronet/go-obscuro/go/common/gethencoding"
"github.com/obscuronet/go-obscuro/go/common/log"
"github.com/obscuronet/go-obscuro/go/enclave/components"
"github.com/obscuronet/go-obscuro/go/enclave/core"
"github.com/obscuronet/go-obscuro/go/enclave/storage"

gethcore "github.com/ethereum/go-ethereum/core"
gethtypes "github.com/ethereum/go-ethereum/core/types"
gethlog "github.com/ethereum/go-ethereum/log"
)

// EthChainAdapter is an obscuro wrapper around the ethereum core.Blockchain object
type EthChainAdapter struct {
newHeadChan chan gethcore.ChainHeadEvent
batchRegistry components.BatchRegistry
storage storage.Storage
chainID *big.Int
logger gethlog.Logger
}

// NewEthChainAdapter returns a new instance
func NewEthChainAdapter(chainID *big.Int, batchRegistry components.BatchRegistry, storage storage.Storage, logger gethlog.Logger) *EthChainAdapter {
return &EthChainAdapter{
newHeadChan: make(chan gethcore.ChainHeadEvent),
batchRegistry: batchRegistry,
storage: storage,
chainID: chainID,
logger: logger,
}
}

// Config retrieves the chain's fork configuration.
func (e *EthChainAdapter) Config() *params.ChainConfig {
return ChainParams(e.chainID)
}

// CurrentBlock returns the current head of the chain.
func (e *EthChainAdapter) CurrentBlock() *gethtypes.Header {
currentBatchSeqNo := e.batchRegistry.HeadBatchSeq()
if currentBatchSeqNo == nil {
return nil
}
currentBatch, err := e.storage.FetchBatchBySeqNo(currentBatchSeqNo.Uint64())
if err != nil {
e.logger.Warn("unable to retrieve batch seq no: %d", "currentBatchSeqNo", currentBatchSeqNo, log.ErrKey, err)
return nil
}
batch, err := gethencoding.CreateEthHeaderForBatch(currentBatch.Header, secret(e.storage))
if err != nil {
e.logger.Warn("unable to convert batch to eth header ", "currentBatchSeqNo", currentBatchSeqNo, log.ErrKey, err)
return nil
}
return batch
}

func (e *EthChainAdapter) SubscribeChainHeadEvent(ch chan<- gethcore.ChainHeadEvent) event.Subscription {
return event.NewSubscription(func(quit <-chan struct{}) error {
for {
select {
case head := <-e.newHeadChan:
select {
case ch <- head:
case <-quit:
return nil
}
case <-quit:
return nil
}
}
})
}

// GetBlock retrieves a specific block, used during pool resets.
func (e *EthChainAdapter) GetBlock(_ common.Hash, number uint64) *gethtypes.Block {
nbatch, err := e.storage.FetchBatchByHeight(number)
if err != nil {
e.logger.Warn("unable to get batch by height", "number", number, log.ErrKey, err)
return nil
}

nfromBatch, err := gethencoding.CreateEthBlockFromBatch(nbatch)
if err != nil {
e.logger.Error("unable to convert batch to eth block", log.ErrKey, err)
return nil
}

return nfromBatch
}

// StateAt returns a state database for a given root hash (generally the head).
func (e *EthChainAdapter) StateAt(root common.Hash) (*state.StateDB, error) {
if root.Hex() == gethtypes.EmptyCodeHash.Hex() {
return nil, nil //nolint:nilnil
}

currentBatchSeqNo := e.batchRegistry.HeadBatchSeq()
if currentBatchSeqNo == nil {
return nil, fmt.Errorf("not ready yet")
}
currentBatch, err := e.storage.FetchBatchBySeqNo(currentBatchSeqNo.Uint64())
if err != nil {
e.logger.Warn("unable to get batch by height", "currentBatchSeqNo", currentBatchSeqNo, log.ErrKey, err)
return nil, nil //nolint:nilnil
}

return e.storage.CreateStateDB(currentBatch.Hash())
}

func (e *EthChainAdapter) IngestNewBlock(batch *core.Batch) error {
convertedBlock, err := gethencoding.CreateEthBlockFromBatch(batch)
if err != nil {
return err
}

go func() {
e.newHeadChan <- gethcore.ChainHeadEvent{Block: convertedBlock}
}()

return nil
}

func NewLegacyPoolConfig() legacypool.Config {
return legacypool.Config{
Locals: nil,
NoLocals: false,
Journal: "",
Rejournal: 0,
PriceLimit: 0,
PriceBump: 0,
AccountSlots: 100,
GlobalSlots: 10000000,
AccountQueue: 100,
GlobalQueue: 10000000,
Lifetime: 0,
}
}

func secret(storage storage.Storage) []byte {
// todo (#1053) - handle secret not being found.
secret, _ := storage.FetchSecret()
return secret[:]
}
36 changes: 36 additions & 0 deletions go/enclave/evm/ethchainadapter/eth_chainparams.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package ethchainadapter

import (
"math/big"

gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params"
)

// ChainParams defines the forks of the EVM machine
// obscuro should typically be on the last fork version
func ChainParams(obscuroChainID *big.Int) *params.ChainConfig {
zeroTimestamp := uint64(0)

// Initialise the database
return &params.ChainConfig{
ChainID: obscuroChainID,
HomesteadBlock: gethcommon.Big0,
DAOForkBlock: gethcommon.Big0,
EIP150Block: gethcommon.Big0,
EIP155Block: gethcommon.Big0,
EIP158Block: gethcommon.Big0,
ByzantiumBlock: gethcommon.Big0,
ConstantinopleBlock: gethcommon.Big0,
PetersburgBlock: gethcommon.Big0,
IstanbulBlock: gethcommon.Big0,
MuirGlacierBlock: gethcommon.Big0,
BerlinBlock: gethcommon.Big0,
LondonBlock: gethcommon.Big0,

CancunTime: &zeroTimestamp,
ShanghaiTime: &zeroTimestamp,
PragueTime: &zeroTimestamp,
VerkleTime: &zeroTimestamp,
}
}
2 changes: 0 additions & 2 deletions go/enclave/mempool/README.md

This file was deleted.

20 changes: 0 additions & 20 deletions go/enclave/mempool/interface.go

This file was deleted.

Loading

0 comments on commit ef01370

Please sign in to comment.