upgrade_db_test.go 7.5 KB

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