123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- package core
- import (
- "encoding/base64"
- "testing"
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/consensus/ethash"
- "github.com/ethereum/go-ethereum/core/mps"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/core/vm"
- "github.com/ethereum/go-ethereum/params"
- "github.com/ethereum/go-ethereum/private"
- "github.com/ethereum/go-ethereum/private/engine"
- "github.com/golang/mock/gomock"
- "github.com/stretchr/testify/assert"
- )
- var (
- PrivatePG = engine.PrivacyGroup{
- Type: "RESIDENT",
- Name: "private",
- PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte("private")),
- Description: "private",
- From: "",
- Members: []string{"CCC", "DDD"},
- }
- DBUpgradeQuorumTestChainConfig = ¶ms.ChainConfig{
- ChainID: params.QuorumTestChainConfig.ChainID,
- HomesteadBlock: params.QuorumTestChainConfig.HomesteadBlock,
- DAOForkBlock: params.QuorumTestChainConfig.DAOForkBlock,
- DAOForkSupport: params.QuorumTestChainConfig.DAOForkSupport,
- EIP150Block: params.QuorumTestChainConfig.EIP150Block,
- EIP150Hash: params.QuorumTestChainConfig.EIP150Hash,
- EIP155Block: params.QuorumTestChainConfig.EIP155Block,
- EIP158Block: params.QuorumTestChainConfig.EIP158Block,
- ByzantiumBlock: params.QuorumTestChainConfig.ByzantiumBlock,
- ConstantinopleBlock: params.QuorumTestChainConfig.ConstantinopleBlock,
- PetersburgBlock: params.QuorumTestChainConfig.PetersburgBlock,
- IstanbulBlock: params.QuorumTestChainConfig.IstanbulBlock,
- MuirGlacierBlock: params.QuorumTestChainConfig.MuirGlacierBlock,
- EWASMBlock: params.QuorumTestChainConfig.EWASMBlock,
- Ethash: params.QuorumTestChainConfig.Ethash,
- Clique: params.QuorumTestChainConfig.Clique,
- Istanbul: params.QuorumTestChainConfig.Istanbul,
- IsQuorum: params.QuorumTestChainConfig.IsQuorum,
- TransactionSizeLimit: params.QuorumTestChainConfig.TransactionSizeLimit,
- MaxCodeSize: params.QuorumTestChainConfig.MaxCodeSize,
- QIP714Block: params.QuorumTestChainConfig.QIP714Block,
- MaxCodeSizeChangeBlock: params.QuorumTestChainConfig.MaxCodeSizeChangeBlock,
- MaxCodeSizeConfig: params.QuorumTestChainConfig.MaxCodeSizeConfig,
- PrivacyEnhancementsBlock: params.QuorumTestChainConfig.PrivacyEnhancementsBlock,
- IsMPS: params.QuorumTestChainConfig.IsMPS,
- }
- )
- // 1. Start the chain with isMPS=false and insert 3 blocks that each create a private contract.
- // 2. Iterate over the private receipts and extract each contract address. Verify that the contracts have non empty bytecode.
- // 3. Run mpsdbupbrade and start the chain with isMPS=true.
- // 4. Insert an extra block which adds a new private contract. Verify that all the contracts identified at step 2 are
- // still available in the "private" state and that all of the contracts are available as empty contracts in the empty
- // state.
- func TestMultiplePSMRDBUpgrade(t *testing.T) {
- mockCtrl := gomock.NewController(t)
- defer mockCtrl.Finish()
- mockptm := private.NewMockPrivateTransactionManager(mockCtrl)
- saved := private.P
- defer func() {
- private.P = saved
- }()
- private.P = mockptm
- mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"CCC"}, common.FromHex(testCode), nil, nil).AnyTimes()
- mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes()
- mockptm.EXPECT().HasFeature(engine.MultiplePrivateStates).Return(true)
- mockptm.EXPECT().Groups().Return([]engine.PrivacyGroup{PrivatePG}, nil).AnyTimes()
- blocks, _, blockchain := buildTestChain(4, DBUpgradeQuorumTestChainConfig)
- db := blockchain.db
- count, err := blockchain.InsertChain(blocks[0:3])
- assert.NoError(t, err)
- assert.Equal(t, 3, count)
- c1Address := blockchain.GetReceiptsByHash(blocks[0].Hash())[0].ContractAddress
- assert.NotNil(t, c1Address)
- c2Address := blockchain.GetReceiptsByHash(blocks[1].Hash())[0].ContractAddress
- assert.NotNil(t, c2Address)
- c3Address := blockchain.GetReceiptsByHash(blocks[2].Hash())[0].ContractAddress
- assert.NotNil(t, c3Address)
- // check that the C3 receipt is a flat receipt (PSReceipts field is nil)
- c3Receipt := blockchain.GetReceiptsByHash(blocks[2].Hash())[0]
- assert.Empty(t, c3Receipt.PSReceipts)
- standaloneStateRepo, err := blockchain.PrivateStateManager().StateRepository(blocks[2].Root())
- assert.NoError(t, err)
- standaloneStateDB, err := standaloneStateRepo.DefaultState()
- assert.NoError(t, err)
- assert.True(t, standaloneStateDB.Exist(c1Address))
- assert.NotEqual(t, standaloneStateDB.GetCodeSize(c1Address), 0)
- assert.True(t, standaloneStateDB.Exist(c2Address))
- assert.NotEqual(t, standaloneStateDB.GetCodeSize(c2Address), 0)
- assert.True(t, standaloneStateDB.Exist(c3Address))
- assert.NotEqual(t, standaloneStateDB.GetCodeSize(c3Address), 0)
- // execute mpsdbupgrade
- assert.Nil(t, mps.UpgradeDB(db, blockchain))
- // UpgradeDB updates the chainconfig isMPS to true so set it back to false at the end of the test
- defer func() { DBUpgradeQuorumTestChainConfig.IsMPS = false }()
- assert.True(t, DBUpgradeQuorumTestChainConfig.IsMPS)
- blockchain.Stop()
- // reinstantiate the blockchain with isMPS enabled
- blockchain, err = NewBlockChain(db, nil, DBUpgradeQuorumTestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, nil)
- assert.Nil(t, err)
- count, err = blockchain.InsertChain(blocks[3:])
- assert.NoError(t, err)
- assert.Equal(t, 1, count)
- c4Address := blockchain.GetReceiptsByHash(blocks[3].Hash())[0].ContractAddress
- assert.NotNil(t, c4Address)
- mpsStateRepo, err := blockchain.PrivateStateManager().StateRepository(blocks[3].Root())
- assert.NoError(t, err)
- emptyStateDB, err := mpsStateRepo.DefaultState()
- assert.NoError(t, err)
- privateStateDB, err := mpsStateRepo.StatePSI(types.DefaultPrivateStateIdentifier)
- assert.NoError(t, err)
- assert.True(t, privateStateDB.Exist(c1Address))
- assert.NotEqual(t, privateStateDB.GetCodeSize(c1Address), 0)
- assert.True(t, privateStateDB.Exist(c2Address))
- assert.NotEqual(t, privateStateDB.GetCodeSize(c2Address), 0)
- assert.True(t, privateStateDB.Exist(c3Address))
- assert.NotEqual(t, privateStateDB.GetCodeSize(c3Address), 0)
- assert.True(t, privateStateDB.Exist(c4Address))
- assert.NotEqual(t, privateStateDB.GetCodeSize(c4Address), 0)
- assert.True(t, emptyStateDB.Exist(c1Address))
- assert.Equal(t, emptyStateDB.GetCodeSize(c1Address), 0)
- assert.True(t, emptyStateDB.Exist(c2Address))
- assert.Equal(t, emptyStateDB.GetCodeSize(c2Address), 0)
- assert.True(t, emptyStateDB.Exist(c3Address))
- assert.Equal(t, emptyStateDB.GetCodeSize(c3Address), 0)
- assert.True(t, emptyStateDB.Exist(c4Address))
- assert.Equal(t, emptyStateDB.GetCodeSize(c4Address), 0)
- // check the receipts has the PSReceipts field populated (due to the newly applied block)
- c4Receipt := blockchain.GetReceiptsByHash(blocks[3].Hash())[0]
- assert.NotNil(t, c4Receipt.PSReceipts)
- assert.Contains(t, c4Receipt.PSReceipts, types.DefaultPrivateStateIdentifier)
- assert.Contains(t, c4Receipt.PSReceipts, types.EmptyPrivateStateIdentifier)
- // check the block 3 receipts has been upgraded and it has PSReceipts field populated (by the upgrade process)
- c3Receipt = blockchain.GetReceiptsByHash(blocks[2].Hash())[0]
- assert.NotNil(t, c3Receipt.PSReceipts)
- assert.Contains(t, c3Receipt.PSReceipts, types.DefaultPrivateStateIdentifier)
- assert.Contains(t, c3Receipt.PSReceipts, types.EmptyPrivateStateIdentifier)
- }
|