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