github.com/baptiste-b-pegasys/quorum/v22@v22.4.2/core/upgrade_db_test.go (about) 1 package core 2 3 import ( 4 "encoding/base64" 5 "testing" 6 7 "github.com/ethereum/go-ethereum/common" 8 "github.com/ethereum/go-ethereum/consensus/ethash" 9 "github.com/ethereum/go-ethereum/core/mps" 10 "github.com/ethereum/go-ethereum/core/types" 11 "github.com/ethereum/go-ethereum/core/vm" 12 "github.com/ethereum/go-ethereum/params" 13 "github.com/ethereum/go-ethereum/private" 14 "github.com/ethereum/go-ethereum/private/engine" 15 "github.com/golang/mock/gomock" 16 "github.com/stretchr/testify/assert" 17 ) 18 19 var ( 20 PrivatePG = engine.PrivacyGroup{ 21 Type: "RESIDENT", 22 Name: "private", 23 PrivacyGroupId: base64.StdEncoding.EncodeToString([]byte("private")), 24 Description: "private", 25 From: "", 26 Members: []string{"CCC", "DDD"}, 27 } 28 DBUpgradeQuorumTestChainConfig = ¶ms.ChainConfig{ 29 ChainID: params.QuorumTestChainConfig.ChainID, 30 HomesteadBlock: params.QuorumTestChainConfig.HomesteadBlock, 31 DAOForkBlock: params.QuorumTestChainConfig.DAOForkBlock, 32 DAOForkSupport: params.QuorumTestChainConfig.DAOForkSupport, 33 EIP150Block: params.QuorumTestChainConfig.EIP150Block, 34 EIP150Hash: params.QuorumTestChainConfig.EIP150Hash, 35 EIP155Block: params.QuorumTestChainConfig.EIP155Block, 36 EIP158Block: params.QuorumTestChainConfig.EIP158Block, 37 ByzantiumBlock: params.QuorumTestChainConfig.ByzantiumBlock, 38 ConstantinopleBlock: params.QuorumTestChainConfig.ConstantinopleBlock, 39 PetersburgBlock: params.QuorumTestChainConfig.PetersburgBlock, 40 IstanbulBlock: params.QuorumTestChainConfig.IstanbulBlock, 41 MuirGlacierBlock: params.QuorumTestChainConfig.MuirGlacierBlock, 42 EWASMBlock: params.QuorumTestChainConfig.EWASMBlock, 43 Ethash: params.QuorumTestChainConfig.Ethash, 44 Clique: params.QuorumTestChainConfig.Clique, 45 Istanbul: params.QuorumTestChainConfig.Istanbul, 46 IsQuorum: params.QuorumTestChainConfig.IsQuorum, 47 TransactionSizeLimit: params.QuorumTestChainConfig.TransactionSizeLimit, 48 MaxCodeSize: params.QuorumTestChainConfig.MaxCodeSize, 49 QIP714Block: params.QuorumTestChainConfig.QIP714Block, 50 MaxCodeSizeChangeBlock: params.QuorumTestChainConfig.MaxCodeSizeChangeBlock, 51 MaxCodeSizeConfig: params.QuorumTestChainConfig.MaxCodeSizeConfig, 52 PrivacyEnhancementsBlock: params.QuorumTestChainConfig.PrivacyEnhancementsBlock, 53 IsMPS: params.QuorumTestChainConfig.IsMPS, 54 } 55 ) 56 57 // 1. Start the chain with isMPS=false and insert 3 blocks that each create a private contract. 58 // 2. Iterate over the private receipts and extract each contract address. Verify that the contracts have non empty bytecode. 59 // 3. Run mpsdbupbrade and start the chain with isMPS=true. 60 // 4. Insert an extra block which adds a new private contract. Verify that all the contracts identified at step 2 are 61 // still available in the "private" state and that all of the contracts are available as empty contracts in the empty 62 // state. 63 func TestMultiplePSMRDBUpgrade(t *testing.T) { 64 mockCtrl := gomock.NewController(t) 65 defer mockCtrl.Finish() 66 67 mockptm := private.NewMockPrivateTransactionManager(mockCtrl) 68 69 saved := private.P 70 defer func() { 71 private.P = saved 72 }() 73 private.P = mockptm 74 75 mockptm.EXPECT().Receive(gomock.Not(common.EncryptedPayloadHash{})).Return("", []string{"CCC"}, common.FromHex(testCode), nil, nil).AnyTimes() 76 mockptm.EXPECT().Receive(common.EncryptedPayloadHash{}).Return("", []string{}, common.EncryptedPayloadHash{}.Bytes(), nil, nil).AnyTimes() 77 mockptm.EXPECT().HasFeature(engine.MultiplePrivateStates).Return(true) 78 mockptm.EXPECT().Groups().Return([]engine.PrivacyGroup{PrivatePG}, nil).AnyTimes() 79 80 blocks, _, blockchain := buildTestChain(4, DBUpgradeQuorumTestChainConfig) 81 db := blockchain.db 82 83 count, err := blockchain.InsertChain(blocks[0:3]) 84 assert.NoError(t, err) 85 assert.Equal(t, 3, count) 86 87 c1Address := blockchain.GetReceiptsByHash(blocks[0].Hash())[0].ContractAddress 88 assert.NotNil(t, c1Address) 89 c2Address := blockchain.GetReceiptsByHash(blocks[1].Hash())[0].ContractAddress 90 assert.NotNil(t, c2Address) 91 c3Address := blockchain.GetReceiptsByHash(blocks[2].Hash())[0].ContractAddress 92 assert.NotNil(t, c3Address) 93 // check that the C3 receipt is a flat receipt (PSReceipts field is nil) 94 c3Receipt := blockchain.GetReceiptsByHash(blocks[2].Hash())[0] 95 assert.Empty(t, c3Receipt.PSReceipts) 96 97 standaloneStateRepo, err := blockchain.PrivateStateManager().StateRepository(blocks[2].Root()) 98 assert.NoError(t, err) 99 100 standaloneStateDB, err := standaloneStateRepo.DefaultState() 101 assert.NoError(t, err) 102 103 assert.True(t, standaloneStateDB.Exist(c1Address)) 104 assert.NotEqual(t, standaloneStateDB.GetCodeSize(c1Address), 0) 105 assert.True(t, standaloneStateDB.Exist(c2Address)) 106 assert.NotEqual(t, standaloneStateDB.GetCodeSize(c2Address), 0) 107 assert.True(t, standaloneStateDB.Exist(c3Address)) 108 assert.NotEqual(t, standaloneStateDB.GetCodeSize(c3Address), 0) 109 110 // execute mpsdbupgrade 111 assert.Nil(t, mps.UpgradeDB(db, blockchain)) 112 // UpgradeDB updates the chainconfig isMPS to true so set it back to false at the end of the test 113 defer func() { DBUpgradeQuorumTestChainConfig.IsMPS = false }() 114 assert.True(t, DBUpgradeQuorumTestChainConfig.IsMPS) 115 116 blockchain.Stop() 117 118 // reinstantiate the blockchain with isMPS enabled 119 blockchain, err = NewBlockChain(db, nil, DBUpgradeQuorumTestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil, nil) 120 assert.Nil(t, err) 121 122 count, err = blockchain.InsertChain(blocks[3:]) 123 assert.NoError(t, err) 124 assert.Equal(t, 1, count) 125 126 c4Address := blockchain.GetReceiptsByHash(blocks[3].Hash())[0].ContractAddress 127 assert.NotNil(t, c4Address) 128 129 mpsStateRepo, err := blockchain.PrivateStateManager().StateRepository(blocks[3].Root()) 130 assert.NoError(t, err) 131 132 emptyStateDB, err := mpsStateRepo.DefaultState() 133 assert.NoError(t, err) 134 privateStateDB, err := mpsStateRepo.StatePSI(types.DefaultPrivateStateIdentifier) 135 assert.NoError(t, err) 136 137 assert.True(t, privateStateDB.Exist(c1Address)) 138 assert.NotEqual(t, privateStateDB.GetCodeSize(c1Address), 0) 139 assert.True(t, privateStateDB.Exist(c2Address)) 140 assert.NotEqual(t, privateStateDB.GetCodeSize(c2Address), 0) 141 assert.True(t, privateStateDB.Exist(c3Address)) 142 assert.NotEqual(t, privateStateDB.GetCodeSize(c3Address), 0) 143 assert.True(t, privateStateDB.Exist(c4Address)) 144 assert.NotEqual(t, privateStateDB.GetCodeSize(c4Address), 0) 145 146 assert.True(t, emptyStateDB.Exist(c1Address)) 147 assert.Equal(t, emptyStateDB.GetCodeSize(c1Address), 0) 148 assert.True(t, emptyStateDB.Exist(c2Address)) 149 assert.Equal(t, emptyStateDB.GetCodeSize(c2Address), 0) 150 assert.True(t, emptyStateDB.Exist(c3Address)) 151 assert.Equal(t, emptyStateDB.GetCodeSize(c3Address), 0) 152 assert.True(t, emptyStateDB.Exist(c4Address)) 153 assert.Equal(t, emptyStateDB.GetCodeSize(c4Address), 0) 154 155 // check the receipts has the PSReceipts field populated (due to the newly applied block) 156 c4Receipt := blockchain.GetReceiptsByHash(blocks[3].Hash())[0] 157 assert.NotNil(t, c4Receipt.PSReceipts) 158 assert.Contains(t, c4Receipt.PSReceipts, types.DefaultPrivateStateIdentifier) 159 assert.Contains(t, c4Receipt.PSReceipts, types.EmptyPrivateStateIdentifier) 160 161 // check the block 3 receipts has been upgraded and it has PSReceipts field populated (by the upgrade process) 162 c3Receipt = blockchain.GetReceiptsByHash(blocks[2].Hash())[0] 163 assert.NotNil(t, c3Receipt.PSReceipts) 164 assert.Contains(t, c3Receipt.PSReceipts, types.DefaultPrivateStateIdentifier) 165 assert.Contains(t, c3Receipt.PSReceipts, types.EmptyPrivateStateIdentifier) 166 }