diff --git a/test/contract/contracts/GLDToken.sol b/test/contract/contracts/GLDToken.sol index 76c9c3b0..596baad3 100644 --- a/test/contract/contracts/GLDToken.sol +++ b/test/contract/contracts/GLDToken.sol @@ -7,5 +7,4 @@ contract GLDToken is ERC20 { function destroy() public { selfdestruct(payable(msg.sender)); } - receive() external payable {} } diff --git a/test/contract/contracts/SLVToken.sol b/test/contract/contracts/SLVToken.sol new file mode 100644 index 00000000..00b7249b --- /dev/null +++ b/test/contract/contracts/SLVToken.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: AGPL-3.0 +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +contract SLVToken is ERC20 { + uint256 private countA; + uint256 private countB; + + constructor() ERC20("Silver", "SLV") { + _mint(msg.sender, 1000000000000000000000); + } + + function incrementCountA() public { + countA = countA + 1; + } + + function incrementCountB() public { + countB = countB + 1; + } + + receive() external payable {} +} diff --git a/test/contract/hardhat.config.js b/test/contract/hardhat.config.js index b474482c..c452b963 100644 --- a/test/contract/hardhat.config.js +++ b/test/contract/hardhat.config.js @@ -17,7 +17,18 @@ task("accounts", "Prints the list of accounts", async () => { * @type import('hardhat/config').HardhatUserConfig */ module.exports = { - solidity: "0.8.0", + solidity: { + version: "0.8.0", + settings: { + outputSelection: { + '*': { + '*': [ + 'abi', 'storageLayout', + ] + } + } + } + }, networks: { local: { url: 'http://127.0.0.1:8545', diff --git a/test/contract/src/index.js b/test/contract/src/index.js index 6e6f5be1..9ff8f177 100644 --- a/test/contract/src/index.js +++ b/test/contract/src/index.js @@ -1,5 +1,6 @@ const fastify = require('fastify')({ logger: true }); const hre = require("hardhat"); +const { getStorageSlotKey } = require('./utils'); // readiness check @@ -12,15 +13,14 @@ fastify.get('/v1/healthz', async (req, reply) => { fastify.get('/v1/deployContract', async (req, reply) => { const GLDToken = await hre.ethers.getContractFactory("GLDToken"); - const token = await GLDToken.deploy(); + let token = await GLDToken.deploy(); await token.deployed(); - const rct = await token.deployTransaction.wait(); return { address: token.address, txHash: token.deployTransaction.hash, - blockNumber: rct.blockNumber, - blockHash: rct.blockHash, + blockNumber: token.deployTransaction.blockNumber, + blockHash: token.deployTransaction.blockHash, } }); @@ -64,6 +64,58 @@ fastify.get('/v1/sendEth', async (req, reply) => { } }); +fastify.get('/v1/deploySLVContract', async (req, reply) => { + const SLVToken = await hre.ethers.getContractFactory("SLVToken"); + const token = await SLVToken.deploy(); + const receipt = await token.deployTransaction.wait(); + + return { + address: token.address, + txHash: token.deployTransaction.hash, + blockNumber: receipt.blockNumber, + blockHash: receipt.blockHash, + } +}); + +fastify.get('/v1/incrementCountA', async (req, reply) => { + const addr = req.query.addr; + + const SLVToken = await hre.ethers.getContractFactory("SLVToken"); + const token = await SLVToken.attach(addr); + + const tx = await token.incrementCountA(); + const receipt = await tx.wait(); + + return { + blockNumber: receipt.blockNumber, + } +}); + +fastify.get('/v1/incrementCountB', async (req, reply) => { + const addr = req.query.addr; + + const SLVToken = await hre.ethers.getContractFactory("SLVToken"); + const token = await SLVToken.attach(addr); + + const tx = await token.incrementCountB(); + const receipt = await tx.wait(); + + return { + blockNumber: receipt.blockNumber, + } +}); + +fastify.get('/v1/getStorageKey', async (req, reply) => { + const contract = req.query.contract; + const label = req.query.label; + + const key = await getStorageSlotKey(contract, label) + + return { + key + } +}); + async function main() { try { await fastify.listen(3000, '0.0.0.0'); diff --git a/test/contract/src/utils.js b/test/contract/src/utils.js new file mode 100644 index 00000000..42e45cac --- /dev/null +++ b/test/contract/src/utils.js @@ -0,0 +1,38 @@ +// import { artifacts } from 'hardhat'; +const { artifacts } = require("hardhat") +const { utils, BigNumber } = require("ethers") + +async function getStorageLayout(contractName) { + const artifact = await artifacts.readArtifact(contractName); + const buildInfo = await artifacts.getBuildInfo(`${artifact.sourceName}:${artifact.contractName}`); + + if (!buildInfo) { + throw new Error('storageLayout not present in compiler output.'); + } + + const output = buildInfo.output; + const { storageLayout } = output.contracts[artifact.sourceName][artifact.contractName]; + + if (!storageLayout) { + throw new Error('Contract hasn\'t been compiled.'); + } + + return storageLayout; +}; + +async function getStorageSlotKey(contractName, variableName) { + storageLayout = await getStorageLayout(contractName) + + const { storage } = storageLayout; + const targetState = storage.find((state) => state.label === variableName); + + // Throw if state variable could not be found in storage layout. + if (!targetState) { + throw new Error('Variable not present in storage layout.'); + } + + key = utils.hexlify(BigNumber.from(targetState.slot)); + return key +}; + +module.exports = { getStorageSlotKey } diff --git a/test/helper.go b/test/helper.go index 5cd8ee2a..e7c1540e 100644 --- a/test/helper.go +++ b/test/helper.go @@ -27,6 +27,10 @@ type Tx struct { BlockHash string `json:"blockHash"` } +type StorageKey struct { + Key string `json:"key"` +} + const srvUrl = "http://localhost:3000" func DeployContract() (*ContractDeployed, error) { @@ -77,3 +81,57 @@ func SendEth(to string, value string) (*Tx, error) { return &tx, nil } + +func DeploySLVContract() (*ContractDeployed, error) { + res, err := http.Get(fmt.Sprintf("%s/v1/deploySLVContract", srvUrl)) + if err != nil { + return nil, err + } + defer res.Body.Close() + + var contract ContractDeployed + + decoder := json.NewDecoder(res.Body) + err = decoder.Decode(&contract) + if err != nil { + return nil, err + } + + return &contract, nil +} + +func IncrementCountA(addr string) error { + _, err := http.Get(fmt.Sprintf("%s/v1/incrementCountA?addr=%s", srvUrl, addr)) + if err != nil { + return err + } + + return nil +} + +func IncrementCountB(addr string) error { + _, err := http.Get(fmt.Sprintf("%s/v1/incrementCountB?addr=%s", srvUrl, addr)) + if err != nil { + return err + } + + return nil +} + +func GetStorageSlotKey(contract string, label string) (*StorageKey, error) { + res, err := http.Get(fmt.Sprintf("%s/v1/getStorageKey?contract=%s&label=%s", srvUrl, contract, label)) + if err != nil { + return nil, err + } + defer res.Body.Close() + + var key StorageKey + + decoder := json.NewDecoder(res.Body) + err = decoder.Decode(&key) + if err != nil { + return nil, err + } + + return &key, nil +} diff --git a/test/watch_address_integration_test.go b/test/watch_address_integration_test.go index 62f9b56b..19da4f5e 100644 --- a/test/watch_address_integration_test.go +++ b/test/watch_address_integration_test.go @@ -7,8 +7,10 @@ import ( "strconv" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff" sdtypes "github.com/ethereum/go-ethereum/statediff/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -32,7 +34,6 @@ var _ = Describe("WatchAddressIntegration", func() { ctx := context.Background() var ( - txErr error contractErr error gethMethod = "statediff_watchAddress" @@ -41,14 +42,6 @@ var _ = Describe("WatchAddressIntegration", func() { contract1 *integration.ContractDeployed contract2 *integration.ContractDeployed contract3 *integration.ContractDeployed - - prevBalance1 *big.Int - prevBalance2 *big.Int - prevBalance3 *big.Int - - actualBalance1 *big.Int - actualBalance2 *big.Int - actualBalance3 *big.Int ) BeforeEach(func() { @@ -59,269 +52,700 @@ var _ = Describe("WatchAddressIntegration", func() { It("WatchAddress test init", func() { // Deploy three contracts - contract1, contractErr = integration.DeployContract() + contract1, contractErr = integration.DeploySLVContract() Expect(contractErr).ToNot(HaveOccurred()) - contract2, contractErr = integration.DeployContract() + contract2, contractErr = integration.DeploySLVContract() Expect(contractErr).ToNot(HaveOccurred()) - contract3, contractErr = integration.DeployContract() + contract3, contractErr = integration.DeploySLVContract() Expect(contractErr).ToNot(HaveOccurred()) + }) - // Get initial balances for all the contracts - actualBalance1 = big.NewInt(0) - prevBalance1 = big.NewInt(0) - initBalance1, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Describe("watched addresses", func() { + var ( + txErr error + + prevBalance1 *big.Int + prevBalance2 *big.Int + prevBalance3 *big.Int + + actualBalance1 *big.Int + actualBalance2 *big.Int + actualBalance3 *big.Int + ) + + It("gets initial balances", func() { + // Get initial balances for all the contracts + // Contract 1 + actualBalance1 = big.NewInt(0) + prevBalance1 = big.NewInt(0) + initBalance1, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(initBalance1.String()).To(Equal(actualBalance1.String())) + + // Contract 2 + actualBalance2 = big.NewInt(0) + prevBalance2 = big.NewInt(0) + initBalance2, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(initBalance2.String()).To(Equal(actualBalance2.String())) + + // Contract 3 + actualBalance3 = big.NewInt(0) + prevBalance3 = big.NewInt(0) + initBalance3, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(initBalance3.String()).To(Equal(actualBalance3.String())) + }) + + Context("no contracts being watched", func() { + It("indexes state for all the contracts", func() { + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) + prevBalance1.Set(actualBalance1) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) + prevBalance2.Set(actualBalance2) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) + prevBalance3.Set(actualBalance3) + }) + }) + + Context("one contract being watched", func() { + It("indexes state only for the watched contract", func() { + operation := statediff.AddAddresses + args := []sdtypes.WatchAddressArg{ + { + Address: contract1.Address, + CreatedAt: uint64(contract1.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) + prevBalance1.Set(actualBalance1) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String())) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + }) + }) + + Context("contract added to a non-empty watch-list", func() { + It("indexes state only for the watched contracts", func() { + operation := statediff.AddAddresses + args := []sdtypes.WatchAddressArg{ + { + Address: contract2.Address, + CreatedAt: uint64(contract2.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) + prevBalance1.Set(actualBalance1) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) + prevBalance2.Set(actualBalance2) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + }) + }) + + Context("contract removed from the watch-list", func() { + It("indexes state only for the watched contract", func() { + operation := statediff.RemoveAddresses + args := []sdtypes.WatchAddressArg{ + { + Address: contract1.Address, + CreatedAt: uint64(contract1.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(prevBalance1.String())) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) + prevBalance2.Set(actualBalance2) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + }) + }) + + Context("set the list of watched addresses", func() { + It("indexes state only for the watched contracts", func() { + operation := statediff.SetAddresses + args := []sdtypes.WatchAddressArg{ + { + Address: contract1.Address, + CreatedAt: uint64(contract1.BlockNumber), + }, + { + Address: contract3.Address, + CreatedAt: uint64(contract3.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) + prevBalance1.Set(actualBalance1) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String())) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) + prevBalance3.Set(actualBalance3) + }) + }) + + Context("clear the list of watched addresses", func() { + It("indexes state for all the contracts", func() { + operation := statediff.ClearAddresses + args := []sdtypes.WatchAddressArg{} + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Send eth to all three contract accounts + // Contract 1 + _, txErr = integration.SendEth(contract1.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + + balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) + prevBalance1.Set(actualBalance1) + + // Contract 2 + _, txErr = integration.SendEth(contract2.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + + balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) + prevBalance2.Set(actualBalance2) + + // Contract 3 + _, txErr = integration.SendEth(contract3.Address, "0.01") + Expect(txErr).ToNot(HaveOccurred()) + actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + + balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + Expect(err).ToNot(HaveOccurred()) + Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) + prevBalance3.Set(actualBalance3) + }) + }) + }) + + Describe("watched storage slots", func() { + storageSlotAKey, err := integration.GetStorageSlotKey("SLVToken", "countA") Expect(err).ToNot(HaveOccurred()) - Expect(initBalance1.String()).To(Equal(actualBalance1.String())) + countAIndex := storageSlotAKey.Key - actualBalance2 = big.NewInt(0) - prevBalance2 = big.NewInt(0) - initBalance2, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + storageSlotBKey, err := integration.GetStorageSlotKey("SLVToken", "countB") Expect(err).ToNot(HaveOccurred()) - Expect(initBalance2.String()).To(Equal(actualBalance2.String())) + countBIndex := storageSlotBKey.Key - actualBalance3 = big.NewInt(0) - prevBalance3 = big.NewInt(0) - initBalance3, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(initBalance3.String()).To(Equal(actualBalance3.String())) - }) + var ( + incErr error - Context("no contracts being watched", func() { - It("indexes state for all the contracts", func() { - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + countAStorageHash = crypto.Keccak256Hash(common.HexToHash(countAIndex).Bytes()) + countBStorageHash = crypto.Keccak256Hash(common.HexToHash(countBIndex).Bytes()) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) + prevCountA1 *big.Int + prevCountB1 *big.Int + prevCountA2 *big.Int + prevCountB2 *big.Int + + actualCountA1 *big.Int + actualCountB1 *big.Int + actualCountA2 *big.Int + actualCountB2 *big.Int + ) + + It("gets initial storage values", func() { + // Get initial storage values for the contracts + // Contract 1, countA + actualCountA1 = big.NewInt(0) + prevCountA1 = big.NewInt(0) + ipldCountA1Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) - prevBalance1.Set(actualBalance1) + ipldCountA1 := new(big.Int).SetBytes(ipldCountA1Storage) + Expect(ipldCountA1.String()).To(Equal(actualCountA1.String())) - _, txErr = integration.SendEth(contract2.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) - - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) + // Contract 1, countB + actualCountB1 = big.NewInt(0) + prevCountB1 = big.NewInt(0) + ipldCountB1Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) - prevBalance2.Set(actualBalance2) + ipldCountB1 := new(big.Int).SetBytes(ipldCountB1Storage) + Expect(ipldCountB1.String()).To(Equal(actualCountB1.String())) - _, txErr = integration.SendEth(contract3.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) - - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) + // Contract 2, countA + actualCountA2 = big.NewInt(0) + prevCountA2 = big.NewInt(0) + ipldCountA2Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) - prevBalance3.Set(actualBalance3) + ipldCountA2 := new(big.Int).SetBytes(ipldCountA2Storage) + Expect(ipldCountA2.String()).To(Equal(actualCountA2.String())) + + // Contract 2, countB + actualCountB2 = big.NewInt(0) + prevCountB2 = big.NewInt(0) + ipldCountB2Storage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + ipldCountB2 := new(big.Int).SetBytes(ipldCountB2Storage) + Expect(ipldCountB2.String()).To(Equal(actualCountB2.String())) }) - }) - Context("one contract being watched", func() { - It("indexes state only for the watched contract", func() { - operation := "AddAddresses" - args := []sdtypes.WatchAddressArg{ - { - Address: contract1.Address, - CreatedAt: uint64(contract1.BlockNumber), - }, - } - ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) - Expect(ipldErr).ToNot(HaveOccurred()) + Context("no addresses or storage slots being watched", func() { + It("indexes state for all the slots", func() { + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String())) + prevCountA1.Set(actualCountA1) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) - prevBalance1.Set(actualBalance1) + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) - _, txErr = integration.SendEth(contract2.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(actualCountB1.String())) + prevCountB1.Set(actualCountB1) - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String())) + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) - _, txErr = integration.SendEth(contract3.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String())) + prevCountA2.Set(actualCountA2) - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(actualCountB2.String())) + prevCountB2.Set(actualCountB2) + }) }) - }) - Context("contract added to a non-empty watch-list", func() { - It("indexes state only for the watched contracts", func() { - operation := "AddAddresses" - args := []sdtypes.WatchAddressArg{ - { - Address: contract2.Address, - CreatedAt: uint64(contract2.BlockNumber), - }, - } - ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) - Expect(ipldErr).ToNot(HaveOccurred()) + Context("one storage slot being watched", func() { + It("indexes only for the watched storage slot", func() { + operation := statediff.AddStorageSlots + args := []sdtypes.WatchAddressArg{ + { + Address: countAStorageHash.Hex(), + CreatedAt: uint64(contract1.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) - prevBalance1.Set(actualBalance1) + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String())) + prevCountA1.Set(actualCountA1) - _, txErr = integration.SendEth(contract2.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) - prevBalance2.Set(actualBalance2) + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(prevCountB1.String())) - _, txErr = integration.SendEth(contract3.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String())) + prevCountA2.Set(actualCountA2) + + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(prevCountB2.String())) + }) }) - }) - Context("contract removed from the watch-list", func() { - It("indexes state only for the watched contract", func() { - operation := "RemoveAddresses" - args := []sdtypes.WatchAddressArg{ - { - Address: contract1.Address, - CreatedAt: uint64(contract1.BlockNumber), - }, - } - ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) - Expect(ipldErr).ToNot(HaveOccurred()) + Context("set the list of watched storage slots", func() { + It("indexes state only for the watched storage slots", func() { + operation := statediff.SetStorageSlots + args := []sdtypes.WatchAddressArg{ + { + Address: countAStorageHash.Hex(), + CreatedAt: uint64(contract1.BlockNumber), + }, + { + Address: countBStorageHash.Hex(), + CreatedAt: uint64(contract2.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(prevBalance1.String())) + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String())) + prevCountA1.Set(actualCountA1) - _, txErr = integration.SendEth(contract2.Address, "0.01") - // time.Sleep(sleepInterval) - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) - prevBalance2.Set(actualBalance2) + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(actualCountB1.String())) + prevCountB1.Set(actualCountB1) - _, txErr = integration.SendEth(contract3.Address, "0.01") - // time.Sleep(sleepInterval) - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(prevBalance3.String())) + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(actualCountA2.String())) + prevCountA2.Set(actualCountA2) + + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(actualCountB2.String())) + prevCountB2.Set(actualCountB2) + }) }) - }) - Context("set the list of watched addresses", func() { - It("indexes state only for the watched contracts", func() { - operation := "SetAddresses" - args := []sdtypes.WatchAddressArg{ - { - Address: contract1.Address, - CreatedAt: uint64(contract1.BlockNumber), - }, - { - Address: contract3.Address, - CreatedAt: uint64(contract3.BlockNumber), - }, - } - ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) - Expect(ipldErr).ToNot(HaveOccurred()) + Context("storage slot removed from the watch-list", func() { + It("indexes state only for the watched storage slots", func() { + operation := statediff.RemoveStorageSlots + args := []sdtypes.WatchAddressArg{ + { + Address: countAStorageHash.Hex(), + CreatedAt: uint64(contract1.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) - prevBalance1.Set(actualBalance1) + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(prevCountA1.String())) - _, txErr = integration.SendEth(contract2.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(prevBalance2.String())) + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(actualCountB1.String())) + prevCountB1.Set(actualCountB1) - _, txErr = integration.SendEth(contract3.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) - prevBalance3.Set(actualBalance3) + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(prevCountA2.String())) + + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(actualCountB2.String())) + prevCountB2.Set(actualCountB2) + }) }) - }) - Context("clear the list of watched addresses", func() { - It("indexes state for all the contracts", func() { - operation := "ClearAddresses" - args := []sdtypes.WatchAddressArg{} - ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) - Expect(ipldErr).ToNot(HaveOccurred()) + Context("one contract and one storage slot being watched", func() { + It("indexes state only for the watched storage slots of watched contracts", func() { + operation := statediff.SetAddresses + args := []sdtypes.WatchAddressArg{ + { + Address: contract1.Address, + CreatedAt: uint64(contract1.BlockNumber), + }, + } + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) - // Send eth to all three contract accounts - _, txErr = integration.SendEth(contract1.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance1.Add(actualBalance1, big.NewInt(10000000000000000)) + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) - balance1AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract1.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance1AfterTransfer.String()).To(Equal(actualBalance1.String())) - prevBalance1.Set(actualBalance1) + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(prevCountA1.String())) - _, txErr = integration.SendEth(contract2.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance2.Add(actualBalance2, big.NewInt(10000000000000000)) + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) - balance2AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract2.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance2AfterTransfer.String()).To(Equal(actualBalance2.String())) - prevBalance2.Set(actualBalance2) + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(actualCountB1.String())) + prevCountB1.Set(actualCountB1) - _, txErr = integration.SendEth(contract3.Address, "0.01") - Expect(txErr).ToNot(HaveOccurred()) - actualBalance3.Add(actualBalance3, big.NewInt(10000000000000000)) + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) - balance3AfterTransfer, err := ipldClient.BalanceAt(ctx, common.HexToAddress(contract3.Address), nil) - Expect(err).ToNot(HaveOccurred()) - Expect(balance3AfterTransfer.String()).To(Equal(actualBalance3.String())) - prevBalance3.Set(actualBalance3) + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(prevCountA2.String())) + + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(prevCountB2.String())) + }) + }) + + Context("clear the list of watched storage slots", func() { + It("indexes state for all the storage slots of watched contracts", func() { + operation := statediff.ClearStorageSlots + args := []sdtypes.WatchAddressArg{} + ipldErr := ipldRPCClient.Call(nil, ipldMethod, operation, args) + Expect(ipldErr).ToNot(HaveOccurred()) + + // Increment counts + // Contract 1, countA + incErr = integration.IncrementCountA(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA1.Add(actualCountA1, big.NewInt(1)) + + countA1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA1AfterIncrement := new(big.Int).SetBytes(countA1AfterIncrementStorage) + Expect(countA1AfterIncrement.String()).To(Equal(actualCountA1.String())) + prevCountA1.Set(actualCountA1) + + // Contract 1, countB + incErr = integration.IncrementCountB(contract1.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB1.Add(actualCountB1, big.NewInt(1)) + + countB1AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract1.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB1AfterIncrement := new(big.Int).SetBytes(countB1AfterIncrementStorage) + Expect(countB1AfterIncrement.String()).To(Equal(actualCountB1.String())) + prevCountB1.Set(actualCountB1) + + // Contract 2, countA + incErr = integration.IncrementCountA(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountA2.Add(actualCountA2, big.NewInt(1)) + + countA2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countAIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countA2AfterIncrement := new(big.Int).SetBytes(countA2AfterIncrementStorage) + Expect(countA2AfterIncrement.String()).To(Equal(prevCountA2.String())) + + // Contract 2, countB + incErr = integration.IncrementCountB(contract2.Address) + Expect(incErr).ToNot(HaveOccurred()) + actualCountB2.Add(actualCountB2, big.NewInt(1)) + + countB2AfterIncrementStorage, err := ipldClient.StorageAt(ctx, common.HexToAddress(contract2.Address), common.HexToHash(countBIndex), nil) + Expect(err).ToNot(HaveOccurred()) + countB2AfterIncrement := new(big.Int).SetBytes(countB2AfterIncrementStorage) + Expect(countB2AfterIncrement.String()).To(Equal(prevCountB2.String())) + }) }) }) @@ -340,7 +764,7 @@ var _ = Describe("WatchAddressIntegration", func() { }) It("returns an error on args of invalid type", func() { - operation := "AddAddresses" + operation := statediff.AddAddresses args := []string{"WrongArg"} gethErr := gethRPCClient.Call(nil, gethMethod, operation, args)