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, ¶ms.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 }