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

Commit

Permalink
refactor(blockchain): Minor cleanup and add safety checks. (#1266)
Browse files Browse the repository at this point in the history
  • Loading branch information
itsdevbear authored Nov 1, 2023
1 parent b5236fe commit 949a826
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 118 deletions.
44 changes: 40 additions & 4 deletions cosmos/miner/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/miner"

evmkeeper "pkg.berachain.dev/polaris/cosmos/x/evm/keeper"
"pkg.berachain.dev/polaris/eth"
"pkg.berachain.dev/polaris/eth/core/types"
)
Expand All @@ -45,17 +46,33 @@ type EnvelopeSerializer interface {
ToSdkTxBytes(*engine.ExecutionPayloadEnvelope, uint64) ([]byte, error)
}

type App interface {
BeginBlocker(sdk.Context) (sdk.BeginBlock, error)
PreBlocker(sdk.Context, *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error)
}

// EVMKeeper is an interface that defines the methods needed for the EVM setup.
type EVMKeeper interface {
// Setup initializes the EVM keeper.
Setup(evmkeeper.Blockchain) error
SetLatestQueryContext(context.Context) error
}

// Miner implements the baseapp.TxSelector interface.
type Miner struct {
eth.Miner
app App
keeper EVMKeeper
serializer EnvelopeSerializer
currentPayload *miner.Payload
}

// New produces a cosmos miner from a geth miner.
func New(gm eth.Miner) *Miner {
func New(gm eth.Miner, app App, keeper EVMKeeper) *Miner {
return &Miner{
Miner: gm,
Miner: gm,
keeper: keeper,
app: app,
}
}

Expand All @@ -68,11 +85,30 @@ func (m *Miner) Init(serializer EnvelopeSerializer) {
func (m *Miner) PrepareProposal(
ctx sdk.Context, _ *abci.RequestPrepareProposal,
) (*abci.ResponsePrepareProposal, error) {
var payloadEnvelopeBz []byte
var err error
var (
payloadEnvelopeBz []byte
err error
)

// We have to prime the state plugin.
if err = m.keeper.SetLatestQueryContext(ctx); err != nil {
return nil, err
}

// We have to run the PreBlocker && BeginBlocker to get the chain into the state
// it'll be in when the EVM transaction actually runs.
if _, err = m.app.PreBlocker(ctx, nil); err != nil {
return nil, err
} else if _, err = m.app.BeginBlocker(ctx); err != nil {
return nil, err
}

// Trigger the geth miner to build a block.
if payloadEnvelopeBz, err = m.buildBlock(ctx); err != nil {
return nil, err
}

// Return the payload as a transaction in the proposal.
return &abci.ResponsePrepareProposal{Txs: [][]byte{payloadEnvelopeBz}}, err
}

Expand Down
11 changes: 7 additions & 4 deletions cosmos/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package runtime

import (
"context"
"time"

"cosmossdk.io/log"
Expand Down Expand Up @@ -50,13 +51,15 @@ import (
type EVMKeeper interface {
// Setup initializes the EVM keeper.
Setup(evmkeeper.Blockchain) error
SetLatestQueryContext(context.Context) error
}

// CosmosApp is an interface that defines the methods needed for the Cosmos setup.
type CosmosApp interface {
SetPrepareProposal(sdk.PrepareProposalHandler)
SetMempool(mempool.Mempool)
SetAnteHandler(sdk.AnteHandler)
miner.App
}

// Polaris is a struct that wraps the Polaris struct from the polar package.
Expand Down Expand Up @@ -92,17 +95,17 @@ func New(
panic(err)
}

// Wrap the geth miner and txpool with the cosmos miner and txpool.
p.WrappedTxPool = txpool.New(p.Blockchain(), p.TxPool())
p.WrappedMiner = miner.New(p.Miner())

return p
}

// Build is a function that sets up the Polaris struct.
// It takes a BaseApp and an EVMKeeper as arguments.
// It returns an error if the setup fails.
func (p *Polaris) Build(app CosmosApp, ek EVMKeeper) error {
// Wrap the geth miner and txpool with the cosmos miner and txpool.
p.WrappedTxPool = txpool.New(p.Blockchain(), p.TxPool())
p.WrappedMiner = miner.New(p.Miner(), app, ek)

app.SetMempool(p.WrappedTxPool)
app.SetPrepareProposal(p.WrappedMiner.PrepareProposal)

Expand Down
8 changes: 5 additions & 3 deletions cosmos/x/evm/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ func (k *Keeper) Precommit(ctx context.Context) error {
block := k.chain.GetBlockByNumber(blockNum)
if block == nil {
panic(
fmt.Sprintf("EVM BLOCK FAILURE AT BLOCK %d", blockNum),
fmt.Sprintf(
"EVM BLOCK %d FAILED TO PROCESS", blockNum,
),
)
} else if block.NumberU64() != blockNum {
panic(
Expand All @@ -47,8 +49,8 @@ func (k *Keeper) Precommit(ctx context.Context) error {
return nil
}

// PrepareCheckState runs on the Cosmos-SDK lifecycle PrepareCheckState().
func (k *Keeper) PrepareCheckState(ctx context.Context) error {
// SetLatestQueryContext runs on the Cosmos-SDK lifecycle SetLatestQueryContext().
func (k *Keeper) SetLatestQueryContext(ctx context.Context) error {
k.sp.Prepare(ctx)
return nil
}
5 changes: 2 additions & 3 deletions cosmos/x/evm/keeper/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ func (k *Keeper) InitGenesis(ctx sdk.Context, genState *core.Genesis) error {
}

// Insert to chain.
k.chain.
PreparePlugins(ctx.WithEventManager(sdk.NewEventManager()))
return k.chain.InsertBlockWithoutSetHead(genState.ToBlock())
k.chain.PreparePlugins(ctx.WithEventManager(sdk.NewEventManager()))
return k.chain.WriteGenesisBlock(genState.ToBlock())
}

// ExportGenesis returns the exported genesis state.
Expand Down
7 changes: 4 additions & 3 deletions cosmos/x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@ import (
"pkg.berachain.dev/polaris/cosmos/config"
"pkg.berachain.dev/polaris/cosmos/x/evm/plugins/state"
"pkg.berachain.dev/polaris/cosmos/x/evm/types"
"pkg.berachain.dev/polaris/eth/core"
ethprecompile "pkg.berachain.dev/polaris/eth/core/precompile"
coretypes "pkg.berachain.dev/polaris/eth/core/types"
"pkg.berachain.dev/polaris/eth/params"
)

type Blockchain interface {
PreparePlugins(context.Context)
Config() *params.ChainConfig
core.ChainWriter
core.ChainReader
WriteGenesisBlock(*coretypes.Block) error
InsertBlockAndSetHead(*coretypes.Block) error
GetBlockByNumber(uint64) *coretypes.Block
}

type Keeper struct {
Expand Down
2 changes: 1 addition & 1 deletion cosmos/x/evm/keeper/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (k *Keeper) ProcessPayloadEnvelope(

// Prepare should be moved to the blockchain? THIS IS VERY HOOD YES NEEDS TO BE MOVED.
k.chain.PreparePlugins(ctx)
if err = k.chain.InsertBlockWithoutSetHead(block); err != nil {
if err = k.chain.InsertBlockAndSetHead(block); err != nil {
return nil, err
}

Expand Down
4 changes: 2 additions & 2 deletions cosmos/x/evm/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ func (am AppModule) RegisterServices(registrar grpc.ServiceRegistrar) error {
// ConsensusVersion implements AppModule/ConsensusVersion.
func (AppModule) ConsensusVersion() uint64 { return ConsensusVersion }

// PrepareCheckState prepares the application state for a check.
// SetLatestQueryContext prepares the application state for a check.
func (am AppModule) PrepareCheckState(ctx context.Context) error {
return am.keeper.PrepareCheckState(ctx)
return am.keeper.SetLatestQueryContext(ctx)
}

// Precommit performs precommit operations.
Expand Down
4 changes: 2 additions & 2 deletions e2e/precompile/contracts/distribution/distribution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ var _ = Describe("Distribution Precompile", func() {
Expect(err).ToNot(HaveOccurred())
ExpectSuccessReceipt(tf.EthClient(), tx)

// Wait for 2 blocks to be produced, to make sure there are rewards.
for i := 0; i < 2; i++ {
// Wait for 5 blocks to be produced, to make sure there are rewards.
for i := 0; i < 5; i++ {
Expect(tf.WaitForNextBlock()).To(Succeed())
}

Expand Down
2 changes: 1 addition & 1 deletion e2e/testapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func NewPolarisApp(
)

// Setup Polaris Runtime.
if err := app.Polaris.Build(app.BaseApp, app.EVMKeeper); err != nil {
if err := app.Polaris.Build(app, app.EVMKeeper); err != nil {
panic(err)
}

Expand Down
21 changes: 9 additions & 12 deletions eth/core/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type blockchain struct {

engine consensus.Engine
processor core.Processor
validator core.Validator

// statedb is the state database that is used to mange state during transactions.
statedb state.StateDB
Expand All @@ -79,10 +80,6 @@ type blockchain struct {
currentBlock atomic.Pointer[types.Block]
// finalizedBlock is the finalized/latest block.
finalizedBlock atomic.Pointer[types.Block]
// currentReceipts is the current/pending receipts.
currentReceipts atomic.Value
// currentLogs is the current/pending logs.
currentLogs atomic.Value

// receiptsCache is a cache of the receipts for the last `defaultCacheSizeBytes` bytes of
// blocks. blockHash -> receipts
Expand All @@ -98,14 +95,13 @@ type blockchain struct {
txLookupCache *lru.Cache[common.Hash, *types.TxLookupEntry]

// subscription event feeds
scope event.SubscriptionScope
chainFeed event.Feed
chainHeadFeed event.Feed
logsFeed event.Feed
pendingLogsFeed event.Feed
rmLogsFeed event.Feed // currently never used
chainSideFeed event.Feed // currently never used
logger log.Logger
scope event.SubscriptionScope
chainFeed event.Feed
chainHeadFeed event.Feed
logsFeed event.Feed
rmLogsFeed event.Feed // currently never used
chainSideFeed event.Feed // currently never used
logger log.Logger
}

// =========================================================================
Expand Down Expand Up @@ -134,6 +130,7 @@ func NewChain(
}
bc.statedb = state.NewStateDB(bc.sp, bc.pp)
bc.processor = core.NewStateProcessor(bc.config, bc, bc.engine)
bc.validator = core.NewBlockValidator(bc.config, bc, bc.engine)
// TODO: hmm...
bc.currentBlock.Store(
types.NewBlock(&types.Header{Time: 0, Number: big.NewInt(0),
Expand Down
1 change: 0 additions & 1 deletion eth/core/chain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ func (bc *blockchain) CurrentFinalBlock() *types.Header {
// CurrentSafeBlock retrieves the current safe block of the canonical
// chain. The block is retrieved from the blockchain's internal cache.
func (bc *blockchain) CurrentSafeBlock() *types.Header {
// TODO: determine the difference between safe and final in polaris.
return bc.CurrentFinalBlock()
}

Expand Down
21 changes: 21 additions & 0 deletions eth/core/chain_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ func (bc *blockchain) StateAtBlockNumber(number uint64) (state.StateDB, error) {
return state.NewStateDB(sp, bc.pp), nil
}

// HasBlockAndState checks if the blockchain has a block and its state at
// a given hash and number.
func (bc *blockchain) HasBlockAndState(hash common.Hash, number uint64) bool {
// Check for State.
if sdb, err := bc.StateAt(hash); sdb == nil || err == nil {
sdb, err = bc.StateAtBlockNumber(number)
if sdb == nil || err != nil {
return false
}
}

// Check for Block.
if block := bc.GetBlockByNumber(number); block == nil {
block = bc.GetBlockByHash(hash)
if block == nil {
return false
}
}
return true
}

// GetVMConfig returns the vm.Config for the current chain.
func (bc *blockchain) GetVMConfig() *vm.Config {
return bc.vmConfig
Expand Down
Loading

0 comments on commit 949a826

Please sign in to comment.