github.com/corverroos/quorum@v21.1.0+incompatible/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/ethereum/go-ethereum/accounts/abi" 12 "github.com/ethereum/go-ethereum/common" 13 "github.com/ethereum/go-ethereum/common/math" 14 "github.com/ethereum/go-ethereum/core/rawdb" 15 "github.com/ethereum/go-ethereum/core/state" 16 "github.com/ethereum/go-ethereum/core/types" 17 "github.com/ethereum/go-ethereum/core/vm" 18 "github.com/ethereum/go-ethereum/crypto" 19 "github.com/ethereum/go-ethereum/log" 20 "github.com/ethereum/go-ethereum/params" 21 "github.com/ethereum/go-ethereum/private" 22 "github.com/ethereum/go-ethereum/private/engine" 23 "github.com/ethereum/go-ethereum/private/engine/notinuse" 24 "github.com/ethereum/go-ethereum/rlp" 25 "github.com/ethereum/go-ethereum/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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, gp) 151 152 assert.NoError(err, "EVM execution") 153 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, gp) 177 178 assert.NoError(err, "EVM execution") 179 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(evm, privateMsg, gp) 206 207 assert.Error(err, "EVM execution") 208 assert.True(fail, "Transaction receipt status") 209 // check that there is no privacy metadata for the newly created contract 210 assert.Len(evm.CreatedContracts(), 0, "no contracts createad") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 243 244 assert.NoError(err, "EVM execution") 245 assert.False(fail, "Transaction receipt status") 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, err := 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 281 282 assert.NoError(err, "EVM execution") 283 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 318 319 assert.NoError(err, "EVM execution") 320 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 355 356 assert.NoError(err, "EVM execution") 357 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 391 392 assert.NoError(err, "EVM execution") 393 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 425 426 assert.NoError(err, "EVM execution") 427 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 468 469 assert.NoError(err, "EVM execution") 470 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 510 511 assert.NoError(err, "EVM execution") 512 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 553 554 assert.NoError(err, "EVM execution") 555 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 597 598 assert.NoError(err, "EVM execution") 599 assert.True(fail, "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 _, _, fail, 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(fail, "Transaction receipt status") 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, err := 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 699 700 assert.NoError(err, "EVM execution") 701 assert.False(fail, "Transaction receipt status") 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, err := 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 746 747 assert.NoError(err, "EVM execution") 748 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 784 785 assert.NoError(err, "EVM execution") 786 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, new(GasPool).AddGas(math.MaxUint64)) 823 824 assert.NoError(err, "EVM execution") 825 assert.True(fail, "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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, gp) 847 848 assert.NoError(err, "EVM execution") 849 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(newEVM(cfg), privateMsg, gp) 871 872 assert.NoError(err, "EVM execution") 873 assert.False(fail, "Transaction receipt status") 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 _, _, fail, err := ApplyMessage(evm, privateMsg, new(GasPool).AddGas(math.MaxUint64)) 892 893 assert.NoError(err, "%s: EVM execution", c.name) 894 assert.False(fail, "%s: Transaction receipt status", c.name) 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 _, _, fail, err := ApplyMessage(evm, msg, new(GasPool).AddGas(math.MaxUint64)) 910 assert.NoError(err, "%s: EVM execution", c.name) 911 assert.False(fail, "%s: Transaction receipt status", c.name) 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)) 996 privateState, _ := state.New(common.Hash{}, state.NewDatabase(privDatabase)) 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.Context{ 1030 CanTransfer: CanTransfer, 1031 Transfer: Transfer, 1032 GetHash: func(uint64) common.Hash { return common.Hash{} }, 1033 1034 Origin: common.Address{}, 1035 Coinbase: common.Address{}, 1036 BlockNumber: new(big.Int), 1037 Time: big.NewInt(time.Now().Unix()), 1038 Difficulty: new(big.Int), 1039 GasLimit: uint64(3450366), 1040 GasPrice: big.NewInt(0), 1041 } 1042 evm := vm.NewEVM(context, cfg.publicState, cfg.privateState, ¶ms.ChainConfig{ 1043 ChainID: big.NewInt(1), 1044 ByzantiumBlock: new(big.Int), 1045 HomesteadBlock: new(big.Int), 1046 DAOForkBlock: new(big.Int), 1047 DAOForkSupport: false, 1048 EIP150Block: new(big.Int), 1049 EIP155Block: new(big.Int), 1050 EIP158Block: new(big.Int), 1051 IsQuorum: true, 1052 PrivacyEnhancementsBlock: new(big.Int), 1053 }, vm.Config{}) 1054 evm.SetCurrentTX(cfg.currentTx) 1055 return evm 1056 } 1057 1058 func mustParse(def string) abi.ABI { 1059 ret, err := abi.JSON(strings.NewReader(def)) 1060 if err != nil { 1061 panic(fmt.Sprintf("Can't parse ABI def %s", err)) 1062 } 1063 return ret 1064 } 1065 1066 type stubSigner struct { 1067 } 1068 1069 func (ss *stubSigner) Sender(tx *types.Transaction) (common.Address, error) { 1070 return signingAddress, nil 1071 } 1072 1073 func (ss *stubSigner) SignatureValues(tx *types.Transaction, sig []byte) (r, s, v *big.Int, err error) { 1074 panic("implement me") 1075 } 1076 1077 func (ss *stubSigner) Hash(tx *types.Transaction) common.Hash { 1078 panic("implement me") 1079 } 1080 1081 func (ss *stubSigner) Equal(types.Signer) bool { 1082 panic("implement me") 1083 } 1084 1085 type mockPrivateTransactionManager struct { 1086 notinuse.PrivateTransactionManager 1087 returns map[string][]interface{} 1088 currentMethod string 1089 count map[string]int 1090 } 1091 1092 func (mpm *mockPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool { 1093 return true 1094 } 1095 1096 func (mpm *mockPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) { 1097 mpm.count["Receive"]++ 1098 values := mpm.returns["Receive"] 1099 var ( 1100 r1 []byte 1101 r2 *engine.ExtraMetadata 1102 r3 error 1103 ) 1104 if values[0] != nil { 1105 r1 = values[0].([]byte) 1106 } 1107 if values[1] != nil { 1108 r2 = values[1].(*engine.ExtraMetadata) 1109 } 1110 if values[2] != nil { 1111 r3 = values[2].(error) 1112 } 1113 return "", nil, r1, r2, r3 1114 } 1115 1116 func (mpm *mockPrivateTransactionManager) When(name string) *mockPrivateTransactionManager { 1117 mpm.currentMethod = name 1118 mpm.count[name] = -1 1119 return mpm 1120 } 1121 1122 func (mpm *mockPrivateTransactionManager) Return(values ...interface{}) { 1123 mpm.returns[mpm.currentMethod] = values 1124 } 1125 1126 func (mpm *mockPrivateTransactionManager) Verify(assert *testifyassert.Assertions) { 1127 for m, c := range mpm.count { 1128 assert.True(c > -1, "%s has not been called", m) 1129 } 1130 } 1131 1132 func (mpm *mockPrivateTransactionManager) reset() { 1133 mpm.count = make(map[string]int) 1134 mpm.currentMethod = "" 1135 mpm.returns = make(map[string][]interface{}) 1136 } 1137 1138 func newMockPrivateTransactionManager() *mockPrivateTransactionManager { 1139 return &mockPrivateTransactionManager{ 1140 returns: make(map[string][]interface{}), 1141 count: make(map[string]int), 1142 } 1143 } 1144 1145 const ( 1146 c1AbiDefinition = ` 1147 [ 1148 { 1149 "constant": false, 1150 "inputs": [ 1151 { 1152 "name": "newValue", 1153 "type": "uint256" 1154 } 1155 ], 1156 "name": "set", 1157 "outputs": [ 1158 { 1159 "name": "", 1160 "type": "uint256" 1161 } 1162 ], 1163 "payable": false, 1164 "stateMutability": "nonpayable", 1165 "type": "function" 1166 }, 1167 { 1168 "constant": true, 1169 "inputs": [], 1170 "name": "get", 1171 "outputs": [ 1172 { 1173 "name": "", 1174 "type": "uint256" 1175 } 1176 ], 1177 "payable": false, 1178 "stateMutability": "view", 1179 "type": "function" 1180 }, 1181 { 1182 "constant": false, 1183 "inputs": [ 1184 { 1185 "name": "newValue", 1186 "type": "uint256" 1187 } 1188 ], 1189 "name": "newContractC2", 1190 "outputs": [], 1191 "payable": false, 1192 "stateMutability": "nonpayable", 1193 "type": "function" 1194 }, 1195 { 1196 "inputs": [ 1197 { 1198 "name": "initVal", 1199 "type": "uint256" 1200 } 1201 ], 1202 "payable": false, 1203 "stateMutability": "nonpayable", 1204 "type": "constructor" 1205 } 1206 ] 1207 ` 1208 c2AbiDefinition = ` 1209 [ 1210 { 1211 "constant": false, 1212 "inputs": [ 1213 { 1214 "name": "_val", 1215 "type": "uint256" 1216 } 1217 ], 1218 "name": "set", 1219 "outputs": [], 1220 "payable": false, 1221 "stateMutability": "nonpayable", 1222 "type": "function" 1223 }, 1224 { 1225 "constant": true, 1226 "inputs": [], 1227 "name": "get", 1228 "outputs": [ 1229 { 1230 "name": "result", 1231 "type": "uint256" 1232 } 1233 ], 1234 "payable": false, 1235 "stateMutability": "view", 1236 "type": "function" 1237 }, 1238 { 1239 "inputs": [ 1240 { 1241 "name": "_t", 1242 "type": "address" 1243 } 1244 ], 1245 "payable": false, 1246 "stateMutability": "nonpayable", 1247 "type": "constructor" 1248 } 1249 ] 1250 ` 1251 ) 1252 1253 func verifyGasPoolCalculation(t *testing.T, pm private.PrivateTransactionManager) { 1254 assert := testifyassert.New(t) 1255 saved := private.P 1256 defer func() { 1257 private.P = saved 1258 }() 1259 private.P = pm 1260 1261 txGasLimit := uint64(100000) 1262 gasPool := new(GasPool).AddGas(200000) 1263 // this payload would give us 25288 intrinsic gas 1264 arbitraryEncryptedPayload := "4ab80888354582b92ab442a317828386e4bf21ea4a38d1a9183fbb715f199475269d7686939017f4a6b28310d5003ebd8e012eade530b79e157657ce8dd9692a" 1265 expectedGasPool := new(GasPool).AddGas(177988) // only intrinsic gas is deducted 1266 1267 db := rawdb.NewMemoryDatabase() 1268 privateState, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1269 publicState, _ := state.New(common.Hash{}, state.NewDatabase(db)) 1270 msg := privateCallMsg{ 1271 callmsg: callmsg{ 1272 addr: common.Address{2}, 1273 to: &common.Address{}, 1274 value: new(big.Int), 1275 gas: txGasLimit, 1276 gasPrice: big.NewInt(0), 1277 data: common.Hex2Bytes(arbitraryEncryptedPayload), 1278 }, 1279 } 1280 ctx := NewEVMContext(msg, &dualStateTestHeader, nil, &common.Address{}) 1281 evm := vm.NewEVM(ctx, publicState, privateState, params.QuorumTestChainConfig, vm.Config{}) 1282 1283 tx := types.NewTransaction( 1284 0, 1285 common.Address{}, 1286 big.NewInt(0), 1287 txGasLimit, 1288 big.NewInt(0), 1289 common.Hex2Bytes(arbitraryEncryptedPayload)) 1290 evm.SetCurrentTX(tx) 1291 1292 arbitraryBalance := big.NewInt(100000000) 1293 publicState.SetBalance(evm.Coinbase, arbitraryBalance) 1294 publicState.SetBalance(msg.From(), arbitraryBalance) 1295 1296 testObject := NewStateTransition(evm, msg, gasPool) 1297 1298 _, _, failed, err := testObject.TransitionDb() 1299 1300 assert.NoError(err) 1301 assert.False(failed) 1302 1303 assert.Equal(new(big.Int).SetUint64(expectedGasPool.Gas()), new(big.Int).SetUint64(gasPool.Gas()), "gas pool must be calculated correctly") 1304 assert.Equal(arbitraryBalance, publicState.GetBalance(evm.Coinbase), "balance must not be changed") 1305 assert.Equal(arbitraryBalance, publicState.GetBalance(msg.From()), "balance must not be changed") 1306 } 1307 1308 func TestStateTransition_TransitionDb_GasPoolCalculation_whenNonPartyNodeProcessingPrivateTransactions(t *testing.T) { 1309 stubPTM := &StubPrivateTransactionManager{ 1310 responses: map[string][]interface{}{ 1311 "Receive": { 1312 []byte{}, 1313 nil, 1314 }, 1315 }, 1316 } 1317 verifyGasPoolCalculation(t, stubPTM) 1318 } 1319 1320 func TestStateTransition_TransitionDb_GasPoolCalculation_whenPartyNodeProcessingPrivateTransactions(t *testing.T) { 1321 stubPTM := &StubPrivateTransactionManager{ 1322 responses: map[string][]interface{}{ 1323 "Receive": { 1324 common.Hex2Bytes("600a6000526001601ff300"), 1325 nil, 1326 }, 1327 }, 1328 } 1329 verifyGasPoolCalculation(t, stubPTM) 1330 } 1331 1332 type privateCallMsg struct { 1333 callmsg 1334 } 1335 1336 func (pm privateCallMsg) IsPrivate() bool { return true } 1337 1338 type StubPrivateTransactionManager struct { 1339 notinuse.PrivateTransactionManager 1340 responses map[string][]interface{} 1341 } 1342 1343 func (spm *StubPrivateTransactionManager) Receive(data common.EncryptedPayloadHash) (string, []string, []byte, *engine.ExtraMetadata, error) { 1344 res := spm.responses["Receive"] 1345 if err, ok := res[1].(error); ok { 1346 return "", nil, nil, nil, err 1347 } 1348 if ret, ok := res[0].([]byte); ok { 1349 return "", nil, ret, &engine.ExtraMetadata{ 1350 PrivacyFlag: engine.PrivacyFlagStandardPrivate, 1351 }, nil 1352 } 1353 return "", nil, nil, nil, nil 1354 } 1355 1356 func (spm *StubPrivateTransactionManager) ReceiveRaw(hash common.EncryptedPayloadHash) ([]byte, string, *engine.ExtraMetadata, error) { 1357 _, sender, data, metadata, err := spm.Receive(hash) 1358 return data, sender[0], metadata, err 1359 } 1360 1361 func (spm *StubPrivateTransactionManager) HasFeature(f engine.PrivateTransactionManagerFeature) bool { 1362 return true 1363 }