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 = &params.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  }