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