Skip to content

Commit

Permalink
Merge pull request #526 from onflow/add-state-building-tests
Browse files Browse the repository at this point in the history
Add an E2E test for filling the EVM state with blocks & transactions
  • Loading branch information
sideninja authored Sep 6, 2024
2 parents 5d58ddb + f7a8726 commit 88c3830
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
4 changes: 4 additions & 0 deletions tests/e2e_web3js_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ var (

func TestWeb3_E2E(t *testing.T) {

t.Run("build EVM state", func(t *testing.T) {
runWeb3Test(t, "build_evm_state_test")
})

t.Run("test setup sanity check", func(t *testing.T) {
runWeb3Test(t, "setup_test")
})
Expand Down
112 changes: 112 additions & 0 deletions tests/web3js/build_evm_state_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
const utils = require('web3-utils')
const { assert } = require('chai')
const conf = require('./config')
const helpers = require('./helpers')
const web3 = conf.web3

it('should handle a large number of EVM interactions', async () => {
let latest = await web3.eth.getBlockNumber()
assert.equal(latest, 2n)

let eoaCount = 20
let accounts = []

// Generate 20 EOAs
// Fund them with some arbitrary number of tokens
// Make them do transfers to each other

for (let i = 0; i < eoaCount; i++) {
let receiver = web3.eth.accounts.create()

let transferValue = utils.toWei('0.15', 'ether')
let transfer = await helpers.signAndSend({
from: conf.eoa.address,
to: receiver.address,
value: transferValue,
gasPrice: conf.minGasPrice,
gasLimit: 21_000,
})

assert.equal(transfer.receipt.status, conf.successStatus)
assert.equal(transfer.receipt.from, conf.eoa.address)
assert.equal(transfer.receipt.to, receiver.address)

// check balance was moved
let receiverWei = await web3.eth.getBalance(receiver.address)
assert.equal(receiverWei, transferValue)

accounts.push(receiver)
}

let senderBalance = await web3.eth.getBalance(conf.eoa.address)
assert.equal(senderBalance, 1999999999937000000n)

let transferAmounts = ['0.01', '0.03', '0.05']
for (let i = 0; i < eoaCount; i++) {
let sender = accounts[i]

for (let j = 0; j < 3; j++) {
let receiver = randomItem(accounts)

let amount = randomItem(transferAmounts)
let transferValue = utils.toWei(amount, 'ether')
let transfer = await helpers.signAndSendFrom(sender, {
from: sender.address,
to: receiver.address,
value: transferValue,
gasPrice: conf.minGasPrice,
gasLimit: 21_000,
})

assert.equal(transfer.receipt.status, conf.successStatus)
assert.equal(transfer.receipt.from, sender.address)
assert.equal(transfer.receipt.to, receiver.address)
}
}

latest = await web3.eth.getBlockNumber()
assert.equal(latest, 82n)

for (let i = 0; i < eoaCount; i++) {
let sender = accounts[i]

let deployed = await helpers.deployContractFrom(sender, 'storage')
let contractAddress = deployed.receipt.contractAddress

assert.equal(deployed.receipt.status, conf.successStatus)
assert.isString(contractAddress)
assert.equal(deployed.receipt.from, sender.address)

let storeNumber = Math.floor(Math.random() * 10_000)
// set the value on the contract, to its current value
let updateData = deployed.contract.methods.store(storeNumber).encodeABI()
// store a value in the contract
let res = await helpers.signAndSendFrom(sender, {
from: sender.address,
to: contractAddress,
data: updateData,
value: '0',
gasPrice: conf.minGasPrice,
})
assert.equal(res.receipt.status, conf.successStatus)

sender = randomItem(accounts)
let sumA = Math.floor(Math.random() * 10_000)
let sumB = Math.floor(Math.random() * 100_000)
res = await helpers.signAndSendFrom(sender, {
from: sender.address,
to: contractAddress,
data: deployed.contract.methods.sum(sumA, sumB).encodeABI(),
gas: 55_000,
gasPrice: conf.minGasPrice
})
assert.equal(res.receipt.status, conf.successStatus)
}

latest = await web3.eth.getBlockNumber()
assert.equal(latest, 142n)
})

function randomItem(items) {
return items[Math.floor(Math.random() * items.length)]
}
39 changes: 39 additions & 0 deletions tests/web3js/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,30 @@ async function deployContract(name) {
}
}

async function deployContractFrom(from, name) {
const abi = require(`../fixtures/${name}ABI.json`)
const code = await fs.promises.readFile(`${__dirname}/../fixtures/${name}.byte`, 'utf8')
const contractABI = new web3.eth.Contract(abi, { handleReverted: true })

let data = contractABI
.deploy({ data: `0x${code}` })
.encodeABI()

let signed = await from.signTransaction({
from: from.address,
data: data,
value: '0',
gasPrice: conf.minGasPrice,
})

let receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction)

return {
contract: new web3.eth.Contract(abi, receipt.contractAddress, { handleReverted: true }),
receipt: receipt
}
}

// signAndSend signs a transactions and submits it to the network,
// returning a transaction hash and receipt
async function signAndSend(tx) {
Expand All @@ -49,6 +73,19 @@ async function signAndSend(tx) {
}
}

// signAndSendFrom signs a transactions from the given EOA and submits it
// to the network, returning a transaction hash and receipt
async function signAndSendFrom(from, tx) {
const signedTx = await from.signTransaction(tx)
// send transaction and make sure interaction was success
const receipt = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)

return {
hash: signedTx.transactionHash,
receipt: receipt,
}
}

// callRPCMethod accepts a method name and its params and
// makes a POST request to the JSON-RPC API server.
// Returns a promise for the response.
Expand All @@ -67,4 +104,6 @@ async function callRPCMethod(methodName, params) {

exports.signAndSend = signAndSend
exports.deployContract = deployContract
exports.deployContractFrom = deployContractFrom
exports.callRPCMethod = callRPCMethod
exports.signAndSendFrom = signAndSendFrom

0 comments on commit 88c3830

Please sign in to comment.