From ae50ace84f48b1a587abac5b4bb4ff7dfdef24e4 Mon Sep 17 00:00:00 2001 From: Baptiste Boussemart Date: Tue, 31 Aug 2021 14:53:33 +0200 Subject: [PATCH] fix: use the ChainContext interface in state_processor to be aligned with geth --- core/blockchain.go | 3 +++ core/evm.go | 19 +++++++++++++++++++ core/state_processor.go | 12 ++++++------ core/vm/runtime/runtime_test.go | 14 ++++++++++++++ light/lightchain.go | 11 +++++++++++ 5 files changed, 53 insertions(+), 6 deletions(-) diff --git a/core/blockchain.go b/core/blockchain.go index ad9b453285..c94e7605ca 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -2816,6 +2816,9 @@ func (bc *BlockChain) GetTransactionLookup(hash common.Hash) *rawdb.LegacyTxLook // Config retrieves the chain's fork configuration. func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } +// QuorumConfig retrieves the Quorum chain's configuration +func (bc *BlockChain) QuorumConfig() *QuorumChainConfig { return bc.quorumConfig } + // Engine retrieves the blockchain's consensus engine. func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } diff --git a/core/evm.go b/core/evm.go index 8f69d51499..b94a275d6f 100644 --- a/core/evm.go +++ b/core/evm.go @@ -21,8 +21,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core/mps" + "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/params" ) // ChainContext supports retrieving headers and consensus parameters from the @@ -33,6 +36,22 @@ type ChainContext interface { // GetHeader returns the hash corresponding to their hash. GetHeader(common.Hash, uint64) *types.Header + + // Config retrieves the chain's fork configuration + Config() *params.ChainConfig + + // Quorum + + // QuorumConfig retrieves the Quorum chain's configuration + QuorumConfig() *QuorumChainConfig + + // PrivateStateManager returns the private state manager + PrivateStateManager() mps.PrivateStateManager + + // CheckAndSetPrivateState updates the private state as a part contract state extension + CheckAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) + + // End Quorum } // NewEVMBlockContext creates a new context for use in the EVM. diff --git a/core/state_processor.go b/core/state_processor.go index 82020a0fac..11094bdeb9 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -207,7 +207,7 @@ func PrivateStateDBForTxn(isQuorum bool, tx *types.Transaction, stateDb, private // handling MPS scenario for a private transaction // // handleMPS returns the auxiliary receipt and not the standard receipt -func handleMPS(ti int, tx *types.Transaction, gp *GasPool, usedGas *uint64, cfg vm.Config, statedb *state.StateDB, privateStateRepo mps.PrivateStateRepository, config *params.ChainConfig, bc *BlockChain, header *types.Header, applyOnPartiesOnly bool) (mpsReceipt *types.Receipt, err error) { +func handleMPS(ti int, tx *types.Transaction, gp *GasPool, usedGas *uint64, cfg vm.Config, statedb *state.StateDB, privateStateRepo mps.PrivateStateRepository, config *params.ChainConfig, bc ChainContext, header *types.Header, applyOnPartiesOnly bool) (mpsReceipt *types.Receipt, err error) { if tx.IsPrivate() && privateStateRepo != nil && privateStateRepo.IsMPS() { publicStateDBFactory := func() *state.StateDB { db := statedb.Copy() @@ -237,7 +237,7 @@ func handleMPS(ti int, tx *types.Transaction, gp *GasPool, usedGas *uint64, cfg // multiple private receipts and logs array. Logs are decorated with types.PrivateStateIdentifier // // The originalGP gas pool will not be modified -func ApplyTransactionOnMPS(config *params.ChainConfig, bc *BlockChain, author *common.Address, originalGP *GasPool, +func ApplyTransactionOnMPS(config *params.ChainConfig, bc ChainContext, author *common.Address, originalGP *GasPool, publicStateDBFactory func() *state.StateDB, privateStateDBFactory func(psi types.PrivateStateIdentifier) (*state.StateDB, error), header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, privateStateRepo mps.PrivateStateRepository, applyOnPartiesOnly bool) (*types.Receipt, error) { @@ -301,7 +301,7 @@ func ApplyTransactionOnMPS(config *params.ChainConfig, bc *BlockChain, author *c // /Quorum -func applyTransaction(msg types.Message, config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb, privateStateDB *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, cfg vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository) (*types.Receipt, *types.Receipt, error) { +func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb, privateStateDB *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, evm *vm.EVM, cfg vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository) (*types.Receipt, *types.Receipt, error) { // Add addresses to access list if applicable if config.IsYoloV2(header.Number) { statedb.AddAddressToAccessList(msg.From()) @@ -384,7 +384,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc *BlockCh } // Save revert reason if feature enabled - if bc != nil && bc.quorumConfig.RevertReasonEnabled() { + if bc != nil && bc.QuorumConfig().RevertReasonEnabled() { revertReason := result.Revert() if revertReason != nil { if config.IsQuorum && tx.IsPrivate() { @@ -403,7 +403,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc *BlockCh // 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 *BlockChain, author *common.Address, gp *GasPool, statedb, privateStateDB *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository) (*types.Receipt, *types.Receipt, error) { +func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb, privateStateDB *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository) (*types.Receipt, *types.Receipt, error) { // Quorum - decide the privateStateDB to use privateStateDbToUse := PrivateStateDBForTxn(config.IsQuorum, tx, statedb, privateStateDB) // End Quorum @@ -443,7 +443,7 @@ func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common // ApplyInnerTransaction is called from within the Quorum precompile for privacy marker transactions. // It's a call back which essentially duplicates the logic in Process(), // in this case to process the actual private transaction. -func ApplyInnerTransaction(bc *BlockChain, author *common.Address, gp *GasPool, stateDB *state.StateDB, privateStateDB *state.StateDB, header *types.Header, outerTx *types.Transaction, usedGas *uint64, evmConf vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository, vmenv *vm.EVM, innerTx *types.Transaction, txIndex int) error { +func ApplyInnerTransaction(bc ChainContext, author *common.Address, gp *GasPool, stateDB *state.StateDB, privateStateDB *state.StateDB, header *types.Header, outerTx *types.Transaction, usedGas *uint64, evmConf vm.Config, forceNonParty bool, privateStateRepo mps.PrivateStateRepository, vmenv *vm.EVM, innerTx *types.Transaction, txIndex int) error { // this should never happen, but added as sanity check if !innerTx.IsPrivate() { return errors.New("attempt to process non-private transaction from within ApplyInnerTransaction()") diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 0f4db8f4ee..d3ef8b4422 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/asm" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -253,6 +254,19 @@ func (d *dummyChain) SupportsMultitenancy(context.Context) (*proto.PreAuthentica return nil, false } +// Config retrieves the chain's fork configuration +func (d *dummyChain) Config() *params.ChainConfig { return nil } + +// QuorumConfig retrieves the Quorum chain's configuration +func (d *dummyChain) QuorumConfig() *core.QuorumChainConfig { return nil } + +// PrivateStateManager returns the private state manager +func (d *dummyChain) PrivateStateManager() mps.PrivateStateManager { return nil } + +// CheckAndSetPrivateState updates the private state as a part contract state extension +func (d *dummyChain) CheckAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) { +} + // TestBlockhash tests the blockhash operation. It's a bit special, since it internally // requires access to a chain reader. func TestBlockhash(t *testing.T) { diff --git a/light/lightchain.go b/light/lightchain.go index 9fa668fbde..0514cd98ec 100644 --- a/light/lightchain.go +++ b/light/lightchain.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/mps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -600,3 +601,13 @@ func (lc *LightChain) EnableCheckFreq() { func (lc *LightChain) SupportsMultitenancy(context.Context) (*proto.PreAuthenticatedAuthenticationToken, bool) { return nil, lc.isMultitenant } + +// QuorumConfig retrieves the Quorum chain's configuration +func (lc *LightChain) QuorumConfig() *core.QuorumChainConfig { return nil } + +// PrivateStateManager returns the private state manager +func (lc *LightChain) PrivateStateManager() mps.PrivateStateManager { return nil } + +// CheckAndSetPrivateState updates the private state as a part contract state extension +func (lc *LightChain) CheckAndSetPrivateState(txLogs []*types.Log, privateState *state.StateDB, psi types.PrivateStateIdentifier) { +}