github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/core/state_transition_test.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  	"math/big"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/kisexp/xdchain/accounts/abi"
    12  	"github.com/kisexp/xdchain/common"
    13  	"github.com/kisexp/xdchain/common/math"
    14  	"github.com/kisexp/xdchain/core/rawdb"
    15  	"github.com/kisexp/xdchain/core/state"
    16  	"github.com/kisexp/xdchain/core/types"
    17  	"github.com/kisexp/xdchain/core/vm"
    18  	"github.com/kisexp/xdchain/crypto"
    19  	"github.com/kisexp/xdchain/log"
    20  	"github.com/kisexp/xdchain/params"
    21  	"github.com/kisexp/xdchain/private"
    22  	"github.com/kisexp/xdchain/private/engine"
    23  	"github.com/kisexp/xdchain/private/engine/notinuse"
    24  	"github.com/kisexp/xdchain/rlp"
    25  	"github.com/kisexp/xdchain/trie"
    26  	testifyassert "github.com/stretchr/testify/assert"
    27  )
    28  
    29  var (
    30  	c1 = &contract{
    31  		name:     "c1",
    32  		abi:      mustParse(c1AbiDefinition),
    33  		bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806105a88339810180604052602081101561003057600080fd5b81019080805190602001909291905050508060008190555050610550806100586000396000f3fe608060405260043610610051576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100565780636d4ce63c146100a5578063d7139463146100d0575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b810190808035906020019092919050505061010b565b6040518082815260200191505060405180910390f35b3480156100b157600080fd5b506100ba61011e565b6040518082815260200191505060405180910390f35b3480156100dc57600080fd5b50610109600480360360208110156100f357600080fd5b8101908080359060200190929190505050610127565b005b6000816000819055506000549050919050565b60008054905090565b600030610132610212565b808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050604051809103906000f080158015610184573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff166360fe47b1836040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101f657600080fd5b505af115801561020a573d6000803e3d6000fd5b505050505050565b604051610302806102238339019056fe608060405234801561001057600080fd5b506040516020806103028339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610271806100916000396000f3fe608060405260043610610046576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b11461004b5780636d4ce63c14610086575b600080fd5b34801561005757600080fd5b506100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100b1565b005b34801561009257600080fd5b5061009b610180565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561014157600080fd5b505af1158015610155573d6000803e3d6000fd5b505050506040513d602081101561016b57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b15801561020557600080fd5b505afa158015610219573d6000803e3d6000fd5b505050506040513d602081101561022f57600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820a537f4c360ce5c6f55523298e314e6456e5c3e02c170563751dfda37d3aeddb30029a165627a7a7230582060396bfff29d2dfc5a9f4216bfba5e24d031d54fd4b26ebebde1a26c59df0c1e0029"),
    34  	}
    35  	c2 = &contract{
    36  		name:     "c2",
    37  		abi:      mustParse(c2AbiDefinition),
    38  		bytecode: common.Hex2Bytes("608060405234801561001057600080fd5b506040516020806102f58339810180604052602081101561003057600080fd5b8101908080519060200190929190505050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050610264806100916000396000f3fe608060405234801561001057600080fd5b5060043610610053576000357c01000000000000000000000000000000000000000000000000000000009004806360fe47b1146100585780636d4ce63c14610086575b600080fd5b6100846004803603602081101561006e57600080fd5b81019080803590602001909291905050506100a4565b005b61008e610173565b6040518082815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166360fe47b1826040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561013457600080fd5b505af1158015610148573d6000803e3d6000fd5b505050506040513d602081101561015e57600080fd5b81019080805190602001909291905050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156101f857600080fd5b505afa15801561020c573d6000803e3d6000fd5b505050506040513d602081101561022257600080fd5b810190808051906020019092919050505090509056fea165627a7a72305820dd8a5dcf693e1969289c444a282d0684a9760bac26f1e4e0139d46821ec1979b0029"),
    39  	}
    40  
    41  	// exec hash helper vars (accounts/tries)
    42  	signingAddress = common.StringToAddress("contract")
    43  
    44  	c1AccAddress = crypto.CreateAddress(signingAddress, 0)
    45  	c2AccAddress = crypto.CreateAddress(signingAddress, 1)
    46  
    47  	// this is used as the field key in account storage (which is the index/sequence of the field in the contract)
    48  	// both contracts have only one field (c1 - has the value while c2 has c1's address)
    49  	// For more info please see: https://solidity.readthedocs.io/en/v0.6.8/internals/layout_in_storage.html
    50  	firstFieldKey = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000")
    51  
    52  	val42        = common.Hex2Bytes("000000000000000000000000000000000000000000000000000000000000002A")
    53  	val53        = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000035")
    54  	valC1Address = append(common.Hex2Bytes("000000000000000000000000"), c1AccAddress.Bytes()...)
    55  
    56  	// this is the contract storage trie after storing value 42
    57  	c1StorageTrieWithValue42   = secureTrieWithStoredValue(firstFieldKey, val42)
    58  	c1StorageTrieWithValue53   = secureTrieWithStoredValue(firstFieldKey, val53)
    59  	c2StorageTrieWithC1Address = secureTrieWithStoredValue(firstFieldKey, valC1Address)
    60  
    61  	// The contract bytecode above includes the constructor bytecode (which is removed by the EVM before storing the
    62  	// contract bytecode) thus it can't be used to calculate the code hash for the contract.
    63  	// Below we deploy both of them as public contracts and extract the resulting codeHashes from the public state.
    64  	c1CodeHash, c2CodeHash = contractCodeHashes()
    65  
    66  	c1AccountWithValue42Stored   = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c1StorageTrieWithValue42.Hash(), CodeHash: c1CodeHash.Bytes()}
    67  	c1AccountWithValue53Stored   = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c1StorageTrieWithValue53.Hash(), CodeHash: c1CodeHash.Bytes()}
    68  	c2AccountWithC1AddressStored = &state.Account{Nonce: 1, Balance: big.NewInt(0), Root: c2StorageTrieWithC1Address.Hash(), CodeHash: c2CodeHash.Bytes()}
    69  )
    70  
    71  type contract struct {
    72  	abi      abi.ABI
    73  	bytecode []byte
    74  	name     string
    75  }
    76  
    77  func (c *contract) create(args ...interface{}) []byte {
    78  	bytes, err := c.abi.Pack("", args...)
    79  	if err != nil {
    80  		panic("can't pack: " + err.Error())
    81  	}
    82  	return append(c.bytecode, bytes...)
    83  }
    84  
    85  func (c *contract) set(value int64) []byte {
    86  	bytes, err := c.abi.Pack("set", big.NewInt(value))
    87  	if err != nil {
    88  		panic("can't pack: " + err.Error())
    89  	}
    90  	return bytes
    91  }
    92  
    93  func (c *contract) get() []byte {
    94  	bytes, err := c.abi.Pack("get")
    95  	if err != nil {
    96  		panic("can't pack: " + err.Error())
    97  	}
    98  	return bytes
    99  }
   100  
   101  func init() {
   102  	log.PrintOrigins(true)
   103  	log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true)))
   104  }
   105  
   106  func secureTrieWithStoredValue(key []byte, value []byte) *trie.SecureTrie {
   107  	res, _ := trie.NewSecure(common.Hash{}, trie.NewDatabase(rawdb.NewMemoryDatabase()))
   108  	v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(value[:]))
   109  	res.Update(key, v)
   110  	return res
   111  }
   112  
   113  func contractCodeHashes() (c1CodeHash common.Hash, c2CodeHash common.Hash) {
   114  	assert := testifyassert.New(nil)
   115  	cfg := newConfig()
   116  
   117  	// create public c1
   118  	cfg.setData(c1.create(big.NewInt(42)))
   119  	c1Address := createPublicContract(cfg, assert, c1)
   120  	c1CodeHash = cfg.publicState.GetCodeHash(c1Address)
   121  
   122  	// create public c2
   123  	cfg.setNonce(1)
   124  	cfg.setData(c2.create(c1Address))
   125  	c2Address := createPublicContract(cfg, assert, c2)
   126  	c2CodeHash = cfg.publicState.GetCodeHash(c2Address)
   127  
   128  	return
   129  }
   130  
   131  func TestApplyMessage_Private_whenTypicalCreate_Success(t *testing.T) {
   132  	originalP := private.P
   133  	defer func() { private.P = originalP }()
   134  	mockPM := newMockPrivateTransactionManager()
   135  	private.P = mockPM
   136  	assert := testifyassert.New(t)
   137  
   138  	// calling C1.Create standard private
   139  	cfg := newConfig().
   140  		setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   141  		setData([]byte("arbitrary encrypted payload hash"))
   142  	gp := new(GasPool).AddGas(math.MaxUint64)
   143  	privateMsg := newTypicalPrivateMessage(cfg)
   144  
   145  	//since standard private create only get back PrivacyFlag
   146  	mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{
   147  		PrivacyFlag: engine.PrivacyFlagStandardPrivate,
   148  	}, nil)
   149  
   150  	result, err := ApplyMessage(newEVM(cfg), privateMsg, gp)
   151  
   152  	assert.NoError(err, "EVM execution")
   153  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   154  	mockPM.Verify(assert)
   155  }
   156  
   157  func TestApplyMessage_Private_whenCreatePartyProtectionC1_Success(t *testing.T) {
   158  	originalP := private.P
   159  	defer func() { private.P = originalP }()
   160  	mockPM := newMockPrivateTransactionManager()
   161  	private.P = mockPM
   162  	assert := testifyassert.New(t)
   163  
   164  	// calling C1.Create party protection
   165  	cfg := newConfig().
   166  		setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   167  		setData([]byte("arbitrary encrypted payload hash"))
   168  	gp := new(GasPool).AddGas(math.MaxUint64)
   169  	privateMsg := newTypicalPrivateMessage(cfg)
   170  
   171  	//since party protection create only get back privacyFlag
   172  	mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{
   173  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   174  	}, nil)
   175  
   176  	result, err := ApplyMessage(newEVM(cfg), privateMsg, gp)
   177  
   178  	assert.NoError(err, "EVM execution")
   179  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   180  	mockPM.Verify(assert)
   181  }
   182  
   183  func TestApplyMessage_Private_whenCreatePartyProtectionC1WithPrivacyEnhancementsDisabledReturnsError(t *testing.T) {
   184  	originalP := private.P
   185  	defer func() { private.P = originalP }()
   186  	mockPM := newMockPrivateTransactionManager()
   187  	private.P = mockPM
   188  	assert := testifyassert.New(t)
   189  
   190  	// calling C1.Create party protection
   191  	cfg := newConfig().
   192  		setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   193  		setData([]byte("arbitrary encrypted payload hash"))
   194  
   195  	gp := new(GasPool).AddGas(math.MaxUint64)
   196  	privateMsg := newTypicalPrivateMessage(cfg)
   197  
   198  	//since party protection create only get back privacyFlag
   199  	mockPM.When("Receive").Return(c1.create(big.NewInt(42)), &engine.ExtraMetadata{
   200  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   201  	}, nil)
   202  
   203  	evm := newEVM(cfg)
   204  	evm.ChainConfig().PrivacyEnhancementsBlock = nil
   205  	result, err := ApplyMessage(evm, privateMsg, gp)
   206  
   207  	assert.Error(err, "EVM execution")
   208  	assert.True(result.Failed(), "Transaction receipt status")
   209  	// check that there is no privacy metadata for the newly created contract
   210  	assert.Len(evm.CreatedContracts(), 0, "no contracts created")
   211  	mockPM.Verify(assert)
   212  }
   213  
   214  func TestApplyMessage_Private_whenInteractWithPartyProtectionC1_Success(t *testing.T) {
   215  	originalP := private.P
   216  	defer func() { private.P = originalP }()
   217  	mockPM := newMockPrivateTransactionManager()
   218  	private.P = mockPM
   219  	assert := testifyassert.New(t)
   220  	cfg := newConfig()
   221  
   222  	//create party protection c1
   223  	c1EncPayloadHash := []byte("c1")
   224  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   225  		setData(c1EncPayloadHash)
   226  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   227  
   228  	// calling C1.Set() party protection
   229  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   230  		setData([]byte("arbitrary enc payload hash")).
   231  		setNonce(1).
   232  		setTo(c1Address)
   233  	privateMsg := newTypicalPrivateMessage(cfg)
   234  	//since party protection need ACHashes and PrivacyFlag
   235  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   236  		ACHashes: common.EncryptedPayloadHashes{
   237  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   238  		},
   239  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   240  	}, nil)
   241  
   242  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   243  
   244  	assert.NoError(err, "EVM execution")
   245  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   246  	mockPM.Verify(assert)
   247  }
   248  
   249  func TestApplyMessage_Private_whenInteractWithStateValidationC1_Success(t *testing.T) {
   250  	originalP := private.P
   251  	defer func() { private.P = originalP }()
   252  	mockPM := newMockPrivateTransactionManager()
   253  	private.P = mockPM
   254  	assert := testifyassert.New(t)
   255  	cfg := newConfig()
   256  
   257  	//create state validation c1
   258  	c1EncPayloadHash := []byte("c1")
   259  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   260  		setData(c1EncPayloadHash)
   261  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored})
   262  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   263  
   264  	// calling C1.Set() state validation
   265  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   266  		setData([]byte("arbitrary enc payload hash")).
   267  		setNonce(1).
   268  		setTo(c1Address)
   269  	privateMsg := newTypicalPrivateMessage(cfg)
   270  	mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored})
   271  	//since state validation need ACHashes, MerkleRoot and PrivacyFlag
   272  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   273  		ACHashes: common.EncryptedPayloadHashes{
   274  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   275  		},
   276  		PrivacyFlag:  engine.PrivacyFlagStateValidation,
   277  		ACMerkleRoot: mr,
   278  	}, nil)
   279  
   280  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   281  
   282  	assert.NoError(err, "EVM execution")
   283  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   284  	mockPM.Verify(assert)
   285  }
   286  
   287  func TestApplyMessage_Private_whenInteractWithStateValidationC1WithEmptyMRFromTessera_Fail(t *testing.T) {
   288  	originalP := private.P
   289  	defer func() { private.P = originalP }()
   290  	mockPM := newMockPrivateTransactionManager()
   291  	private.P = mockPM
   292  	assert := testifyassert.New(t)
   293  	cfg := newConfig()
   294  
   295  	// create state validation c1
   296  	c1EncPayloadHash := []byte("c1")
   297  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   298  		setData(c1EncPayloadHash)
   299  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored})
   300  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   301  
   302  	// calling C1.Set() state validation
   303  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   304  		setData([]byte("arbitrary enc payload hash")).
   305  		setNonce(1).
   306  		setTo(c1Address)
   307  	privateMsg := newTypicalPrivateMessage(cfg)
   308  	// since state validation need ACHashes, privacyFlag, MerkleRoot
   309  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   310  		ACHashes: common.EncryptedPayloadHashes{
   311  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   312  		},
   313  		PrivacyFlag:  engine.PrivacyFlagStateValidation,
   314  		ACMerkleRoot: common.Hash{},
   315  	}, nil)
   316  
   317  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   318  
   319  	assert.NoError(err, "EVM execution")
   320  	assert.True(result.Failed(), "Transaction receipt status")
   321  	mockPM.Verify(assert)
   322  }
   323  
   324  func TestApplyMessage_Private_whenInteractWithStateValidationC1WithWrongMRFromTessera_Fail(t *testing.T) {
   325  	originalP := private.P
   326  	defer func() { private.P = originalP }()
   327  	mockPM := newMockPrivateTransactionManager()
   328  	private.P = mockPM
   329  	assert := testifyassert.New(t)
   330  	cfg := newConfig()
   331  
   332  	//create state validation c1
   333  	c1EncPayloadHash := []byte("c1")
   334  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   335  		setData(c1EncPayloadHash)
   336  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored})
   337  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   338  
   339  	// calling C1.Set() state validation
   340  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   341  		setData([]byte("arbitrary enc payload hash")).
   342  		setNonce(1).
   343  		setTo(c1Address)
   344  	privateMsg := newTypicalPrivateMessage(cfg)
   345  	//since state validation need ACHashes, PrivacyFlag, MerkleRoot
   346  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   347  		ACHashes: common.EncryptedPayloadHashes{
   348  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   349  		},
   350  		PrivacyFlag:  engine.PrivacyFlagStateValidation,
   351  		ACMerkleRoot: common.Hash{123},
   352  	}, nil)
   353  
   354  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   355  
   356  	assert.NoError(err, "EVM execution")
   357  	assert.True(result.Failed(), "Transaction receipt status")
   358  	mockPM.Verify(assert)
   359  }
   360  
   361  //Limitation of design --if don't send privacyFlag can't be guaranteed to catch non-party
   362  //review this...
   363  func TestApplyMessage_Private_whenNonPartyTriesInteractingWithPartyProtectionC1_NoFlag_Succeed(t *testing.T) {
   364  	originalP := private.P
   365  	defer func() { private.P = originalP }()
   366  	mockPM := newMockPrivateTransactionManager()
   367  	private.P = mockPM
   368  	assert := testifyassert.New(t)
   369  	cfg := newConfig()
   370  
   371  	//act like doesnt exist on non-party node
   372  	c1EncPayloadHash := []byte("c1")
   373  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   374  		setData(c1EncPayloadHash)
   375  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   376  
   377  	// calling C1.Set()
   378  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   379  		setData([]byte("arbitrary enc payload hash")).
   380  		setNonce(1).
   381  		setTo(c1Address)
   382  	privateMsg := newTypicalPrivateMessage(cfg)
   383  	//will have no ACHashes because when non-party sends tx, because no flag it doesn't generate privacyMetadata info
   384  	//actual execution will find affected contract, but non-party won't have info
   385  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   386  		ACHashes:    common.EncryptedPayloadHashes{},
   387  		PrivacyFlag: engine.PrivacyFlagStandardPrivate,
   388  	}, nil)
   389  
   390  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   391  
   392  	assert.NoError(err, "EVM execution")
   393  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   394  	mockPM.Verify(assert)
   395  }
   396  
   397  func TestApplyMessage_Private_whenNonPartyTriesInteractingWithPartyProtectionC1_WithFlag_Fail(t *testing.T) {
   398  	originalP := private.P
   399  	defer func() { private.P = originalP }()
   400  	mockPM := newMockPrivateTransactionManager()
   401  	private.P = mockPM
   402  	assert := testifyassert.New(t)
   403  	cfg := newConfig()
   404  
   405  	//act like doesnt exist on non-party node
   406  	c1EncPayloadHash := []byte("c1")
   407  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   408  		setData(c1EncPayloadHash)
   409  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   410  
   411  	// calling C1.Set() party protection
   412  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   413  		setData([]byte("arbitrary enc payload hash")).
   414  		setNonce(1).
   415  		setTo(c1Address)
   416  	privateMsg := newTypicalPrivateMessage(cfg)
   417  	mockPM.When("Receive").Return(c1.set(53), &engine.ExtraMetadata{
   418  		ACHashes: common.EncryptedPayloadHashes{
   419  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   420  		},
   421  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   422  	}, nil)
   423  
   424  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   425  
   426  	assert.NoError(err, "EVM execution")
   427  	assert.True(result.Failed(), "Transaction receipt status")
   428  	mockPM.Verify(assert)
   429  }
   430  
   431  // C1 is a existing contract before privacy enhancements implementation
   432  func TestApplyMessage_Private_whenPartyProtectionC2InteractsExistingStandardPrivateC1_Fail(t *testing.T) {
   433  	originalP := private.P
   434  	defer func() { private.P = originalP }()
   435  	mockPM := newMockPrivateTransactionManager()
   436  	private.P = mockPM
   437  	assert := testifyassert.New(t)
   438  	cfg := newConfig()
   439  
   440  	// create c1 like c1 already exist before privacy enhancements
   441  	c1EncPayloadHash := []byte("c1")
   442  	cfg.setPrivacyFlag(math.MaxUint64).
   443  		setData(c1EncPayloadHash)
   444  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   445  
   446  	// create party protection c2
   447  	c2EncPayloadHash := []byte("c2")
   448  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   449  		setData(c2EncPayloadHash).
   450  		setNonce(1)
   451  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   452  
   453  	// calling C2.Set() party protection
   454  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   455  		setData([]byte("arbitrary enc payload hash")).
   456  		setNonce(2).
   457  		setTo(c2Address)
   458  	privateMsg := newTypicalPrivateMessage(cfg)
   459  	// since party protection need ACHashes (only private non standard) and PrivacyFlag
   460  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   461  		ACHashes: common.EncryptedPayloadHashes{
   462  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   463  		},
   464  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   465  	}, nil)
   466  
   467  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   468  
   469  	assert.NoError(err, "EVM execution")
   470  	assert.True(result.Failed(), "Transaction receipt status")
   471  	mockPM.Verify(assert)
   472  }
   473  
   474  func TestApplyMessage_Private_whenPartyProtectionC2InteractsNewStandardPrivateC1_Fail(t *testing.T) {
   475  	originalP := private.P
   476  	defer func() { private.P = originalP }()
   477  	mockPM := newMockPrivateTransactionManager()
   478  	private.P = mockPM
   479  	assert := testifyassert.New(t)
   480  	cfg := newConfig()
   481  
   482  	// create default standard private c1
   483  	c1EncPayloadHash := []byte("c1")
   484  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   485  		setData(c1EncPayloadHash)
   486  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   487  
   488  	// create party protection c2
   489  	c2EncPayloadHash := []byte("c2")
   490  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   491  		setData(c2EncPayloadHash).
   492  		setNonce(1)
   493  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   494  
   495  	// calling C2.Set() party protection
   496  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   497  		setData([]byte("arbitrary enc payload hash")).
   498  		setNonce(2).
   499  		setTo(c2Address)
   500  	privateMsg := newTypicalPrivateMessage(cfg)
   501  	// since party protection need ACHashes (only private non standard) and PrivacyFlag
   502  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   503  		ACHashes: common.EncryptedPayloadHashes{
   504  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   505  		},
   506  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   507  	}, nil)
   508  
   509  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   510  
   511  	assert.NoError(err, "EVM execution")
   512  	assert.True(result.Failed(), "Transaction receipt status")
   513  	mockPM.Verify(assert)
   514  }
   515  
   516  func TestApplyMessage_Private_whenPartyProtectionC2InteractsWithPartyProtectionC1_Succeed(t *testing.T) {
   517  	originalP := private.P
   518  	defer func() { private.P = originalP }()
   519  	mockPM := newMockPrivateTransactionManager()
   520  	private.P = mockPM
   521  	assert := testifyassert.New(t)
   522  	cfg := newConfig()
   523  
   524  	// create party protection c1
   525  	c1EncPayloadHash := []byte("c1")
   526  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   527  		setData(c1EncPayloadHash)
   528  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   529  
   530  	// create party protection c2
   531  	c2EncPayloadHash := []byte("c2")
   532  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   533  		setData(c2EncPayloadHash).
   534  		setNonce(1)
   535  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   536  
   537  	// calling C2.Set() party protection
   538  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   539  		setData([]byte("arbitrary enc payload hash")).
   540  		setNonce(2).
   541  		setTo(c2Address)
   542  	privateMsg := newTypicalPrivateMessage(cfg)
   543  	// since party protection need ACHashes and PrivacyFlag
   544  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   545  		ACHashes: common.EncryptedPayloadHashes{
   546  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   547  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   548  		},
   549  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   550  	}, nil)
   551  
   552  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   553  
   554  	assert.NoError(err, "EVM execution")
   555  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   556  	mockPM.Verify(assert)
   557  }
   558  
   559  //scenario where sender Q1 runs simulation which affects c2 and c1 privy for Q3 and Q7
   560  //Q3 receives block but wasn't privy to C1 so doesn't have creation info in tessera
   561  func TestApplyMessage_Private_whenPartyProtectionC2AndC1ButMissingC1CreationInTessera_Fail(t *testing.T) {
   562  	originalP := private.P
   563  	defer func() { private.P = originalP }()
   564  	mockPM := newMockPrivateTransactionManager()
   565  	private.P = mockPM
   566  	assert := testifyassert.New(t)
   567  	cfg := newConfig()
   568  
   569  	// create c1 as a party protection
   570  	c1EncPayloadHash := []byte("c1")
   571  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   572  		setData(c1EncPayloadHash)
   573  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   574  
   575  	// create party protection c2
   576  	c2EncPayloadHash := []byte("c2")
   577  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   578  		setData(c2EncPayloadHash).
   579  		setNonce(1)
   580  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   581  
   582  	// calling C2.Set() party protection
   583  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   584  		setData([]byte("arbitrary enc payload hash")).
   585  		setNonce(2).
   586  		setTo(c2Address)
   587  	privateMsg := newTypicalPrivateMessage(cfg)
   588  	// since party protection need ACHashes and PrivacyFlag
   589  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   590  		ACHashes: common.EncryptedPayloadHashes{
   591  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   592  		},
   593  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   594  	}, nil)
   595  
   596  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   597  
   598  	assert.NoError(err, "EVM execution")
   599  	assert.True(result.Failed(), "Transaction receipt status")
   600  	mockPM.Verify(assert)
   601  }
   602  
   603  //scenario where the simulation is run on the Q1 (privatefor Q3 and Q7) and 3 contracts are affected (C2,C1,C0)
   604  //but now Q3 receives block and should be privy to all 3 given tessera response
   605  //but doesn't have C0 privacyMetadata stored in its db
   606  // UPDATE - after relaxing the ACOTH checks this is a valid scenario where C0 acoth is ignored if it isn't detected as an
   607  // affected contract during transaction execution
   608  func TestApplyMessage_Private_whenPartyProtectionC2AndC1AndC0ButMissingC0InStateDB_Fail(t *testing.T) {
   609  	originalP := private.P
   610  	defer func() { private.P = originalP }()
   611  	mockPM := newMockPrivateTransactionManager()
   612  	private.P = mockPM
   613  	assert := testifyassert.New(t)
   614  	cfg := newConfig()
   615  
   616  	// create party protection c1
   617  	c1EncPayloadHash := []byte("c1")
   618  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   619  		setData(c1EncPayloadHash)
   620  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   621  
   622  	// create party protection c2
   623  	c2EncPayloadHash := []byte("c2")
   624  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   625  		setData(c2EncPayloadHash).
   626  		setNonce(1)
   627  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   628  
   629  	c3EncPayloadHash := []byte("c3")
   630  	// calling C2.Set() party protection
   631  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   632  		setData([]byte("arbitrary enc payload hash")).
   633  		setNonce(2).
   634  		setTo(c2Address)
   635  	privateMsg := newTypicalPrivateMessage(cfg)
   636  	// since party protection need ACHashes and PrivacyFlag
   637  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   638  		ACHashes: common.EncryptedPayloadHashes{
   639  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   640  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   641  			common.BytesToEncryptedPayloadHash(c3EncPayloadHash): struct{}{},
   642  		},
   643  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   644  	}, nil)
   645  
   646  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   647  
   648  	assert.NoError(err, "EVM execution")
   649  	// after ACOTH check updates this is a successful scenario
   650  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   651  	mockPM.Verify(assert)
   652  }
   653  
   654  func TestApplyMessage_Private_whenStateValidationC2InteractsWithStateValidationC1_Succeed(t *testing.T) {
   655  	originalP := private.P
   656  	defer func() { private.P = originalP }()
   657  	mockPM := newMockPrivateTransactionManager()
   658  	private.P = mockPM
   659  	assert := testifyassert.New(t)
   660  	cfg := newConfig()
   661  
   662  	// create party protection c1
   663  	c1EncPayloadHash := []byte("c1")
   664  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   665  		setData(c1EncPayloadHash)
   666  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue42Stored})
   667  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   668  
   669  	// create state validation c2
   670  	c2EncPayloadHash := []byte("c2")
   671  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   672  		setData(c2EncPayloadHash).
   673  		setNonce(1)
   674  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored})
   675  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   676  
   677  	// calling C2.Set() state validation
   678  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   679  		setData([]byte("arbitrary enc payload hash")).
   680  		setNonce(2).
   681  		setTo(c2Address)
   682  
   683  	stuff := crypto.Keccak256Hash(c2.bytecode)
   684  	log.Trace("stuff", "c2code", stuff[:])
   685  
   686  	privateMsg := newTypicalPrivateMessage(cfg)
   687  	mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored}, accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored})
   688  	//since state validation need ACHashes, PrivacyFlag & MerkleRoot
   689  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   690  		ACHashes: common.EncryptedPayloadHashes{
   691  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   692  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   693  		},
   694  		PrivacyFlag:  engine.PrivacyFlagStateValidation,
   695  		ACMerkleRoot: mr,
   696  	}, nil)
   697  
   698  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   699  
   700  	assert.NoError(err, "EVM execution")
   701  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   702  	mockPM.Verify(assert)
   703  }
   704  
   705  func TestApplyMessage_Private_whenStateValidationC2InteractsWithPartyProtectionC1_Fail(t *testing.T) {
   706  	originalP := private.P
   707  	defer func() { private.P = originalP }()
   708  	mockPM := newMockPrivateTransactionManager()
   709  	private.P = mockPM
   710  	assert := testifyassert.New(t)
   711  	cfg := newConfig()
   712  
   713  	// create party protection c1
   714  	c1EncPayloadHash := []byte("c1")
   715  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   716  		setData(c1EncPayloadHash)
   717  	c1Address := createContract(cfg, mockPM, assert, c1, big.NewInt(42))
   718  
   719  	// create state validation c2
   720  	c2EncPayloadHash := []byte("c2")
   721  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   722  		setData(c2EncPayloadHash).
   723  		setNonce(1)
   724  	cfg.acMerkleRoot, _ = calcAccMR(accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored})
   725  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   726  
   727  	// calling C2.Set() state validation
   728  	cfg.setPrivacyFlag(engine.PrivacyFlagStateValidation).
   729  		setData([]byte("arbitrary enc payload hash")).
   730  		setNonce(2).
   731  		setTo(c2Address)
   732  	privateMsg := newTypicalPrivateMessage(cfg)
   733  	// use the correctly calculated MR so that it can't be a source of false positives
   734  	mr, _ := calcAccMR(accEntry{address: c1AccAddress, account: c1AccountWithValue53Stored}, accEntry{address: c2AccAddress, account: c2AccountWithC1AddressStored})
   735  	//since state validation need ACHashes, PrivacyFlag & MerkleRoot
   736  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   737  		ACHashes: common.EncryptedPayloadHashes{
   738  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   739  			common.BytesToEncryptedPayloadHash(c1EncPayloadHash): struct{}{},
   740  		},
   741  		PrivacyFlag:  engine.PrivacyFlagStateValidation,
   742  		ACMerkleRoot: mr,
   743  	}, nil)
   744  
   745  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   746  
   747  	assert.NoError(err, "EVM execution")
   748  	assert.True(result.Failed(), "Transaction receipt status")
   749  	mockPM.Verify(assert)
   750  }
   751  
   752  func TestApplyMessage_Private_whenStandardPrivateC2InteractsWithPublicC1_Fail(t *testing.T) {
   753  	originalP := private.P
   754  	defer func() { private.P = originalP }()
   755  	mockPM := newMockPrivateTransactionManager()
   756  	private.P = mockPM
   757  	assert := testifyassert.New(t)
   758  	cfg := newConfig()
   759  
   760  	// create public c1
   761  	cfg.setData(c1.create(big.NewInt(42)))
   762  	c1Address := createPublicContract(cfg, assert, c1)
   763  
   764  	// create standard private c2
   765  	c2EncPayloadHash := []byte("c2")
   766  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   767  		setData(c2EncPayloadHash).
   768  		setNonce(1)
   769  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   770  
   771  	// calling C2.Set() standard private
   772  	cfg.setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   773  		setData([]byte("arbitrary enc payload hash")).
   774  		setNonce(2).
   775  		setTo(c2Address)
   776  	privateMsg := newTypicalPrivateMessage(cfg)
   777  	//since standard private call no ACHashes, no MerkleRoot
   778  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   779  		ACHashes:    common.EncryptedPayloadHashes{},
   780  		PrivacyFlag: engine.PrivacyFlagStandardPrivate,
   781  	}, nil)
   782  
   783  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   784  
   785  	assert.NoError(err, "EVM execution")
   786  	assert.True(result.Failed(), "Transaction receipt status")
   787  	mockPM.Verify(assert)
   788  }
   789  
   790  func TestApplyMessage_Private_whenPartyProtectionC2InteractsWithPublicC1_Fail(t *testing.T) {
   791  	originalP := private.P
   792  	defer func() { private.P = originalP }()
   793  	mockPM := newMockPrivateTransactionManager()
   794  	private.P = mockPM
   795  	assert := testifyassert.New(t)
   796  	cfg := newConfig()
   797  
   798  	// create public c1
   799  	cfg.setData(c1.create(big.NewInt(42)))
   800  	c1Address := createPublicContract(cfg, assert, c1)
   801  
   802  	// create party protection c2
   803  	c2EncPayloadHash := []byte("c2")
   804  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   805  		setData(c2EncPayloadHash).
   806  		setNonce(1)
   807  	c2Address := createContract(cfg, mockPM, assert, c2, c1Address)
   808  
   809  	// calling C2.Set() party protection
   810  	cfg.setPrivacyFlag(engine.PrivacyFlagPartyProtection).
   811  		setData([]byte("arbitrary enc payload hash")).
   812  		setNonce(2).
   813  		setTo(c2Address)
   814  	privateMsg := newTypicalPrivateMessage(cfg)
   815  	mockPM.When("Receive").Return(c2.set(53), &engine.ExtraMetadata{
   816  		ACHashes: common.EncryptedPayloadHashes{
   817  			common.BytesToEncryptedPayloadHash(c2EncPayloadHash): struct{}{},
   818  		},
   819  		PrivacyFlag: engine.PrivacyFlagPartyProtection,
   820  	}, nil)
   821  
   822  	result, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64))
   823  
   824  	assert.NoError(err, "EVM execution")
   825  	assert.True(result.Failed(), "Transaction receipt status")
   826  	mockPM.Verify(assert)
   827  }
   828  
   829  func TestApplyMessage_Private_whenTxManagerReturnsError_Success(t *testing.T) {
   830  	originalP := private.P
   831  	defer func() { private.P = originalP }()
   832  	mockPM := newMockPrivateTransactionManager()
   833  	private.P = mockPM
   834  	assert := testifyassert.New(t)
   835  
   836  	// calling C1.Create standard private
   837  	cfg := newConfig().
   838  		setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   839  		setData([]byte("arbitrary encrypted payload hash"))
   840  	gp := new(GasPool).AddGas(math.MaxUint64)
   841  	privateMsg := newTypicalPrivateMessage(cfg)
   842  
   843  	//since standard private create only get back PrivacyFlag
   844  	mockPM.When("Receive").Return(nil, nil, fmt.Errorf("Error during receive"))
   845  
   846  	result, err := ApplyMessage(newEVM(cfg), privateMsg, gp)
   847  
   848  	assert.NoError(err, "EVM execution")
   849  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   850  	mockPM.Verify(assert)
   851  }
   852  
   853  func TestApplyMessage_Private_whenTxManagerReturnsEmptyResult_Success(t *testing.T) {
   854  	originalP := private.P
   855  	defer func() { private.P = originalP }()
   856  	mockPM := newMockPrivateTransactionManager()
   857  	private.P = mockPM
   858  	assert := testifyassert.New(t)
   859  
   860  	// calling C1.Create standard private
   861  	cfg := newConfig().
   862  		setPrivacyFlag(engine.PrivacyFlagStandardPrivate).
   863  		setData([]byte("arbitrary encrypted payload hash"))
   864  	gp := new(GasPool).AddGas(math.MaxUint64)
   865  	privateMsg := newTypicalPrivateMessage(cfg)
   866  
   867  	//since standard private create only get back PrivacyFlag
   868  	mockPM.When("Receive").Return(nil, nil, nil)
   869  
   870  	result, err := ApplyMessage(newEVM(cfg), privateMsg, gp)
   871  
   872  	assert.NoError(err, "EVM execution")
   873  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
   874  	mockPM.Verify(assert)
   875  }
   876  
   877  func createContract(cfg *config, mockPM *mockPrivateTransactionManager, assert *testifyassert.Assertions, c *contract, args ...interface{}) common.Address {
   878  	defer mockPM.reset()
   879  
   880  	privateMsg := newTypicalPrivateMessage(cfg)
   881  	metadata := &engine.ExtraMetadata{}
   882  	if cfg.privacyFlag < math.MaxUint64 {
   883  		metadata.PrivacyFlag = cfg.privacyFlag
   884  		if metadata.PrivacyFlag == engine.PrivacyFlagStateValidation {
   885  			metadata.ACMerkleRoot = cfg.acMerkleRoot
   886  		}
   887  	}
   888  	mockPM.When("Receive").Return(c.create(args...), metadata, nil)
   889  
   890  	evm := newEVM(cfg)
   891  	result, err := ApplyMessage(evm, privateMsg, new(GasPool).AddGas(math.MaxUint64))
   892  
   893  	assert.NoError(err, "%s: EVM execution", c.name)
   894  	assert.False(result.Failed(), fmt.Sprintf("%s: Transaction receipt status is 'failed', error == [%v]", c.name, result.Err))
   895  	mockPM.Verify(assert)
   896  	createdContracts := evm.CreatedContracts()
   897  	log.Trace("priv statedb", "evmstatedb", evm.StateDB)
   898  	assert.Len(createdContracts, 1, "%s: Number of created contracts", c.name)
   899  	address := createdContracts[0]
   900  	log.Debug("Created "+c.name, "address", address)
   901  	return address
   902  }
   903  
   904  func createPublicContract(cfg *config, assert *testifyassert.Assertions, c *contract) common.Address {
   905  	pubcfg := cfg.setPublicToPrivateState()
   906  	msg := newTypicalPublicMessage(pubcfg)
   907  
   908  	evm := newEVM(pubcfg)
   909  	result, err := ApplyMessage(evm, msg, new(GasPool).AddGas(math.MaxUint64))
   910  	assert.NoError(err, "%s: EVM execution", c.name)
   911  	assert.False(result.Failed(), fmt.Sprintf("%s: Transaction receipt status is 'failed', error == [%v]", c.name, result.Err))
   912  	createdContracts := evm.CreatedContracts()
   913  	log.Trace("pub statedb", "evmstatedb", evm.StateDB)
   914  	assert.Len(createdContracts, 1, "%s: Number of created contracts", c.name)
   915  	address := createdContracts[0]
   916  	log.Debug("Created "+c.name, "address", address)
   917  	return address
   918  }
   919  
   920  func newTypicalPrivateMessage(cfg *config) PrivateMessage {
   921  	var tx *types.Transaction
   922  	if cfg.to == nil {
   923  		tx = types.NewContractCreation(cfg.nonce, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data)
   924  	} else {
   925  		tx = types.NewTransaction(cfg.nonce, *cfg.to, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data)
   926  	}
   927  	tx.SetPrivate()
   928  	if cfg.privacyFlag < math.MaxUint64 {
   929  		tx.SetTxPrivacyMetadata(&types.PrivacyMetadata{
   930  			PrivacyFlag: cfg.privacyFlag,
   931  		})
   932  	} else {
   933  		tx.SetTxPrivacyMetadata(nil) // simulate standard private transaction
   934  	}
   935  	msg, err := tx.AsMessage(&stubSigner{})
   936  	if err != nil {
   937  		panic(fmt.Sprintf("can't create a new private message: %s", err))
   938  	}
   939  	cfg.currentTx = tx
   940  	return PrivateMessage(msg)
   941  }
   942  
   943  func newTypicalPublicMessage(cfg *config) Message {
   944  	var tx *types.Transaction
   945  	if cfg.to == nil {
   946  		tx = types.NewContractCreation(cfg.nonce, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data)
   947  	} else {
   948  		tx = types.NewTransaction(cfg.nonce, *cfg.to, big.NewInt(0), math.MaxUint64, big.NewInt(0), cfg.data)
   949  	}
   950  	tx.SetTxPrivacyMetadata(nil)
   951  	msg, err := tx.AsMessage(&stubSigner{})
   952  	if err != nil {
   953  		panic(fmt.Sprintf("can't create a new private message: %s", err))
   954  	}
   955  	cfg.currentTx = tx
   956  	return msg
   957  }
   958  
   959  type accEntry struct {
   960  	address common.Address
   961  	account *state.Account
   962  }
   963  
   964  func calcAccMR(entries ...accEntry) (common.Hash, error) {
   965  	combined := new(trie.Trie)
   966  	for _, entry := range entries {
   967  		data, err := rlp.EncodeToBytes(entry.account)
   968  		if err != nil {
   969  			return common.Hash{}, err
   970  		}
   971  		if err = combined.TryUpdate(entry.address.Bytes(), data); err != nil {
   972  			return common.Hash{}, err
   973  		}
   974  	}
   975  	return combined.Hash(), nil
   976  }
   977  
   978  type config struct {
   979  	from  common.Address
   980  	to    *common.Address
   981  	data  []byte
   982  	nonce uint64
   983  
   984  	privacyFlag  engine.PrivacyFlagType
   985  	acMerkleRoot common.Hash
   986  
   987  	currentTx *types.Transaction
   988  
   989  	publicState, privateState *state.StateDB
   990  }
   991  
   992  func newConfig() *config {
   993  	pubDatabase := rawdb.NewMemoryDatabase()
   994  	privDatabase := rawdb.NewMemoryDatabase()
   995  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(pubDatabase), nil)
   996  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(privDatabase), nil)
   997  	return &config{
   998  		privateState: privateState,
   999  		publicState:  publicState,
  1000  	}
  1001  }
  1002  
  1003  func (cfg config) setPublicToPrivateState() *config {
  1004  	cfg.privateState = cfg.publicState
  1005  	return &cfg
  1006  }
  1007  
  1008  func (cfg *config) setPrivacyFlag(f engine.PrivacyFlagType) *config {
  1009  	cfg.privacyFlag = f
  1010  	return cfg
  1011  }
  1012  
  1013  func (cfg *config) setData(bytes []byte) *config {
  1014  	cfg.data = bytes
  1015  	return cfg
  1016  }
  1017  
  1018  func (cfg *config) setNonce(n uint64) *config {
  1019  	cfg.nonce = n
  1020  	return cfg
  1021  }
  1022  
  1023  func (cfg *config) setTo(address common.Address) *config {
  1024  	cfg.to = &address
  1025  	return cfg
  1026  }
  1027  
  1028  func newEVM(cfg *config) *vm.EVM {
  1029  	context := vm.BlockContext{
  1030  		CanTransfer: CanTransfer,
  1031  		Transfer:    Transfer,
  1032  		GetHash:     func(uint64) common.Hash { return common.Hash{} },
  1033  
  1034  		Coinbase:    common.Address{},
  1035  		BlockNumber: new(big.Int),
  1036  		Time:        big.NewInt(time.Now().Unix()),
  1037  		Difficulty:  new(big.Int),
  1038  		GasLimit:    uint64(3450366),
  1039  	}
  1040  	txContext := vm.TxContext{
  1041  		Origin:   common.Address{},
  1042  		GasPrice: big.NewInt(0),
  1043  	}
  1044  	evm := vm.NewEVM(context, txContext, cfg.publicState, cfg.privateState, &params.ChainConfig{
  1045  		ChainID:                  big.NewInt(1),
  1046  		ByzantiumBlock:           new(big.Int),
  1047  		HomesteadBlock:           new(big.Int),
  1048  		DAOForkBlock:             new(big.Int),
  1049  		DAOForkSupport:           false,
  1050  		EIP150Block:              new(big.Int),
  1051  		EIP155Block:              new(big.Int),
  1052  		EIP158Block:              new(big.Int),
  1053  		IsQuorum:                 true,
  1054  		PrivacyEnhancementsBlock: new(big.Int),
  1055  	}, vm.Config{})
  1056  	evm.SetCurrentTX(cfg.currentTx)
  1057  	return evm
  1058  }
  1059  
  1060  func mustParse(def string) abi.ABI {
  1061  	ret, err := abi.JSON(strings.NewReader(def))
  1062  	if err != nil {
  1063  		panic(fmt.Sprintf("Can't parse ABI def %s", err))
  1064  	}
  1065  	return ret
  1066  }
  1067  
  1068  type stubSigner struct {
  1069  }
  1070  
  1071  func (ss *stubSigner) Sender(tx *types.Transaction) (common.Address, error) {
  1072  	return signingAddress, nil
  1073  }
  1074  
  1075  func (ss *stubSigner) SignatureValues(tx *types.Transaction, sig []byte) (r, s, v *big.Int, err error) {
  1076  	panic("implement me")
  1077  }
  1078  
  1079  func (ss *stubSigner) Hash(tx *types.Transaction) common.Hash {
  1080  	panic("implement me")
  1081  }
  1082  
  1083  func (ss *stubSigner) Equal(types.Signer) bool {
  1084  	panic("implement me")
  1085  }
  1086  
  1087  type mockPrivateTransactionManager struct {
  1088  	notinuse.PrivateTransactionManager
  1089  	returns       map[string][]interface{}
  1090  	currentMethod string
  1091  	count         map[string]int
  1092  }
  1093  
  1094  func (mpm *mockPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool {
  1095  	return true
  1096  }
  1097  
  1098  func (mpm *mockPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) {
  1099  	mpm.count["Receive"]++
  1100  	values := mpm.returns["Receive"]
  1101  	var (
  1102  		r1 []byte
  1103  		r2 *engine.ExtraMetadata
  1104  		r3 error
  1105  	)
  1106  	if values[0] != nil {
  1107  		r1 = values[0].([]byte)
  1108  	}
  1109  	if values[1] != nil {
  1110  		r2 = values[1].(*engine.ExtraMetadata)
  1111  	}
  1112  	if values[2] != nil {
  1113  		r3 = values[2].(error)
  1114  	}
  1115  	return "", nil, r1, r2, r3
  1116  }
  1117  
  1118  func (mpm *mockPrivateTransactionManager) When(name string) *mockPrivateTransactionManager {
  1119  	mpm.currentMethod = name
  1120  	mpm.count[name] = -1
  1121  	return mpm
  1122  }
  1123  
  1124  func (mpm *mockPrivateTransactionManager) Return(values ...interface{}) {
  1125  	mpm.returns[mpm.currentMethod] = values
  1126  }
  1127  
  1128  func (mpm *mockPrivateTransactionManager) Verify(assert *testifyassert.Assertions) {
  1129  	for m, c := range mpm.count {
  1130  		assert.True(c > -1, "%s has not been called", m)
  1131  	}
  1132  }
  1133  
  1134  func (mpm *mockPrivateTransactionManager) reset() {
  1135  	mpm.count = make(map[string]int)
  1136  	mpm.currentMethod = ""
  1137  	mpm.returns = make(map[string][]interface{})
  1138  }
  1139  
  1140  func newMockPrivateTransactionManager() *mockPrivateTransactionManager {
  1141  	return &mockPrivateTransactionManager{
  1142  		returns: make(map[string][]interface{}),
  1143  		count:   make(map[string]int),
  1144  	}
  1145  }
  1146  
  1147  const (
  1148  	c1AbiDefinition = `
  1149  [
  1150  	{
  1151  		"constant": false,
  1152  		"inputs": [
  1153  			{
  1154  				"name": "newValue",
  1155  				"type": "uint256"
  1156  			}
  1157  		],
  1158  		"name": "set",
  1159  		"outputs": [
  1160  			{
  1161  				"name": "",
  1162  				"type": "uint256"
  1163  			}
  1164  		],
  1165  		"payable": false,
  1166  		"stateMutability": "nonpayable",
  1167  		"type": "function"
  1168  	},
  1169  	{
  1170  		"constant": true,
  1171  		"inputs": [],
  1172  		"name": "get",
  1173  		"outputs": [
  1174  			{
  1175  				"name": "",
  1176  				"type": "uint256"
  1177  			}
  1178  		],
  1179  		"payable": false,
  1180  		"stateMutability": "view",
  1181  		"type": "function"
  1182  	},
  1183  	{
  1184  		"constant": false,
  1185  		"inputs": [
  1186  			{
  1187  				"name": "newValue",
  1188  				"type": "uint256"
  1189  			}
  1190  		],
  1191  		"name": "newContractC2",
  1192  		"outputs": [],
  1193  		"payable": false,
  1194  		"stateMutability": "nonpayable",
  1195  		"type": "function"
  1196  	},
  1197  	{
  1198  		"inputs": [
  1199  			{
  1200  				"name": "initVal",
  1201  				"type": "uint256"
  1202  			}
  1203  		],
  1204  		"payable": false,
  1205  		"stateMutability": "nonpayable",
  1206  		"type": "constructor"
  1207  	}
  1208  ]
  1209  `
  1210  	c2AbiDefinition = `
  1211  [
  1212  	{
  1213  		"constant": false,
  1214  		"inputs": [
  1215  			{
  1216  				"name": "_val",
  1217  				"type": "uint256"
  1218  			}
  1219  		],
  1220  		"name": "set",
  1221  		"outputs": [],
  1222  		"payable": false,
  1223  		"stateMutability": "nonpayable",
  1224  		"type": "function"
  1225  	},
  1226  	{
  1227  		"constant": true,
  1228  		"inputs": [],
  1229  		"name": "get",
  1230  		"outputs": [
  1231  			{
  1232  				"name": "result",
  1233  				"type": "uint256"
  1234  			}
  1235  		],
  1236  		"payable": false,
  1237  		"stateMutability": "view",
  1238  		"type": "function"
  1239  	},
  1240  	{
  1241  		"inputs": [
  1242  			{
  1243  				"name": "_t",
  1244  				"type": "address"
  1245  			}
  1246  		],
  1247  		"payable": false,
  1248  		"stateMutability": "nonpayable",
  1249  		"type": "constructor"
  1250  	}
  1251  ]
  1252  `
  1253  )
  1254  
  1255  func verifyGasPoolCalculation(t *testing.T, pm private.PrivateTransactionManager) {
  1256  	assert := testifyassert.New(t)
  1257  	saved := private.P
  1258  	defer func() {
  1259  		private.P = saved
  1260  	}()
  1261  	private.P = pm
  1262  
  1263  	txGasLimit := uint64(100000)
  1264  	gasPool := new(GasPool).AddGas(200000)
  1265  	// this payload would give us 25288 intrinsic gas
  1266  	arbitraryEncryptedPayload := "4ab80888354582b92ab442a317828386e4bf21ea4a38d1a9183fbb715f199475269d7686939017f4a6b28310d5003ebd8e012eade530b79e157657ce8dd9692a"
  1267  	expectedGasPool := new(GasPool).AddGas(177988) // only intrinsic gas is deducted
  1268  
  1269  	db := rawdb.NewMemoryDatabase()
  1270  	privateState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
  1271  	publicState, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
  1272  	msg := privateCallMsg{
  1273  		callmsg: callmsg{
  1274  			addr:     common.Address{2},
  1275  			to:       &common.Address{},
  1276  			value:    new(big.Int),
  1277  			gas:      txGasLimit,
  1278  			gasPrice: big.NewInt(0),
  1279  			data:     common.Hex2Bytes(arbitraryEncryptedPayload),
  1280  		},
  1281  	}
  1282  	ctx := NewEVMBlockContext(&dualStateTestHeader, nil, &common.Address{})
  1283  	txCtx := NewEVMTxContext(msg)
  1284  	evm := vm.NewEVM(ctx, txCtx, publicState, privateState, params.QuorumTestChainConfig, vm.Config{})
  1285  
  1286  	tx := types.NewTransaction(
  1287  		0,
  1288  		common.Address{},
  1289  		big.NewInt(0),
  1290  		txGasLimit,
  1291  		big.NewInt(0),
  1292  		common.Hex2Bytes(arbitraryEncryptedPayload))
  1293  	evm.SetCurrentTX(tx)
  1294  
  1295  	arbitraryBalance := big.NewInt(100000000)
  1296  	publicState.SetBalance(evm.Context.Coinbase, arbitraryBalance)
  1297  	publicState.SetBalance(msg.From(), arbitraryBalance)
  1298  
  1299  	testObject := NewStateTransition(evm, msg, gasPool)
  1300  
  1301  	result, err := testObject.TransitionDb()
  1302  
  1303  	assert.NoError(err)
  1304  	assert.False(result.Failed(), fmt.Sprintf("Transaction receipt status is 'failed', error == [%v]", result.Err))
  1305  
  1306  	assert.Equal(new(big.Int).SetUint64(expectedGasPool.Gas()), new(big.Int).SetUint64(gasPool.Gas()), "gas pool must be calculated correctly")
  1307  	assert.Equal(arbitraryBalance, publicState.GetBalance(evm.Context.Coinbase), "balance must not be changed")
  1308  	assert.Equal(arbitraryBalance, publicState.GetBalance(msg.From()), "balance must not be changed")
  1309  }
  1310  
  1311  func TestStateTransition_TransitionDb_GasPoolCalculation_whenNonPartyNodeProcessingPrivateTransactions(t *testing.T) {
  1312  	stubPTM := &StubPrivateTransactionManager{
  1313  		responses: map[string][]interface{}{
  1314  			"Receive": {
  1315  				[]byte{},
  1316  				nil,
  1317  			},
  1318  		},
  1319  	}
  1320  	verifyGasPoolCalculation(t, stubPTM)
  1321  }
  1322  
  1323  func TestStateTransition_TransitionDb_GasPoolCalculation_whenPartyNodeProcessingPrivateTransactions(t *testing.T) {
  1324  	stubPTM := &StubPrivateTransactionManager{
  1325  		responses: map[string][]interface{}{
  1326  			"Receive": {
  1327  				common.Hex2Bytes("600a6000526001601ff300"),
  1328  				nil,
  1329  			},
  1330  		},
  1331  	}
  1332  	verifyGasPoolCalculation(t, stubPTM)
  1333  }
  1334  
  1335  type privateCallMsg struct {
  1336  	callmsg
  1337  }
  1338  
  1339  func (pm privateCallMsg) IsPrivate() bool { return true }
  1340  
  1341  type StubPrivateTransactionManager struct {
  1342  	notinuse.PrivateTransactionManager
  1343  	responses map[string][]interface{}
  1344  }
  1345  
  1346  func (spm *StubPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) {
  1347  	res := spm.responses["Receive"]
  1348  	if err, ok := res[1].(error); ok {
  1349  		return "", nil, nil, nil, err
  1350  	}
  1351  	if ret, ok := res[0].([]byte); ok {
  1352  		return "", nil, ret, &engine.ExtraMetadata{
  1353  			PrivacyFlag: engine.PrivacyFlagStandardPrivate,
  1354  		}, nil
  1355  	}
  1356  	return "", nil, nil, nil, nil
  1357  }
  1358  
  1359  func (spm *StubPrivateTransactionManager) ReceiveRaw(hash common.EncryptedPayloadHash) ([]byte, string, *engine.ExtraMetadata, error) {
  1360  	_, sender, data, metadata, err := spm.Receive(hash)
  1361  	return data, sender[0], metadata, err
  1362  }
  1363  
  1364  func (spm *StubPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool {
  1365  	return true
  1366  }