Commit 3273df8b authored by Kelvin Fichter's avatar Kelvin Fichter Committed by GitHub

Added changes to make state transitioner work (#91)

parent d824abcc
...@@ -7,6 +7,8 @@ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol"; ...@@ -7,6 +7,8 @@ import { Lib_OVMCodec } from "../../libraries/codec/Lib_OVMCodec.sol";
import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol"; import { Lib_AddressResolver } from "../../libraries/resolver/Lib_AddressResolver.sol";
import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol"; import { Lib_EthUtils } from "../../libraries/utils/Lib_EthUtils.sol";
import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol"; import { Lib_SecureMerkleTrie } from "../../libraries/trie/Lib_SecureMerkleTrie.sol";
import { Lib_RLPWriter } from "../../libraries/rlp/Lib_RLPWriter.sol";
import { Lib_RLPReader } from "../../libraries/rlp/Lib_RLPReader.sol";
/* Interface Imports */ /* Interface Imports */
import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol"; import { iOVM_StateTransitioner } from "../../iOVM/verification/iOVM_StateTransitioner.sol";
...@@ -266,13 +268,15 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -266,13 +268,15 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
( (
bool exists, bool exists,
bytes memory value bytes memory encodedValue
) = Lib_SecureMerkleTrie.get( ) = Lib_SecureMerkleTrie.get(
abi.encodePacked(_key), abi.encodePacked(_key),
_storageTrieWitness, _storageTrieWitness,
ovmStateManager.getAccountStorageRoot(_ovmContractAddress) ovmStateManager.getAccountStorageRoot(_ovmContractAddress)
); );
bytes memory value = Lib_RLPReader.readBytes(encodedValue);
if (exists == true) { if (exists == true) {
require( require(
keccak256(value) == keccak256(abi.encodePacked(_value)), keccak256(value) == keccak256(abi.encodePacked(_value)),
...@@ -393,7 +397,9 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV ...@@ -393,7 +397,9 @@ contract OVM_StateTransitioner is Lib_AddressResolver, OVM_FraudContributor, iOV
account.storageRoot = Lib_SecureMerkleTrie.update( account.storageRoot = Lib_SecureMerkleTrie.update(
abi.encodePacked(_key), abi.encodePacked(_key),
abi.encodePacked(value), Lib_RLPWriter.writeBytes(
abi.encodePacked(value)
),
_storageTrieWitness, _storageTrieWitness,
account.storageRoot account.storageRoot
); );
......
...@@ -302,11 +302,7 @@ describe('BondManager', () => { ...@@ -302,11 +302,7 @@ describe('BondManager', () => {
// a dispute is created about a block that intersects // a dispute is created about a block that intersects
const disputeTimestamp = withdrawalTimestamp - 100 const disputeTimestamp = withdrawalTimestamp - 100
await fraudVerifier.finalize( await fraudVerifier.finalize(preStateRoot, sender, disputeTimestamp)
preStateRoot,
sender,
disputeTimestamp
)
await mineBlock(deployer.provider, timestamp) await mineBlock(deployer.provider, timestamp)
await expect(bondManager.finalizeWithdrawal()).to.be.revertedWith( await expect(bondManager.finalizeWithdrawal()).to.be.revertedWith(
...@@ -321,11 +317,7 @@ describe('BondManager', () => { ...@@ -321,11 +317,7 @@ describe('BondManager', () => {
// a dispute is created, but since the fraud period is already over // a dispute is created, but since the fraud period is already over
// it doesn't matter // it doesn't matter
const disputeTimestamp = withdrawalTimestamp - ONE_WEEK - 1 const disputeTimestamp = withdrawalTimestamp - ONE_WEEK - 1
await fraudVerifier.finalize( await fraudVerifier.finalize(preStateRoot, sender, disputeTimestamp)
preStateRoot,
sender,
disputeTimestamp
)
const finalizeWithdrawalTimestamp = withdrawalTimestamp + ONE_WEEK const finalizeWithdrawalTimestamp = withdrawalTimestamp + ONE_WEEK
await mineBlock(deployer.provider, finalizeWithdrawalTimestamp) await mineBlock(deployer.provider, finalizeWithdrawalTimestamp)
......
...@@ -214,7 +214,7 @@ describe('OVM_ECDSAContractAccount', () => { ...@@ -214,7 +214,7 @@ describe('OVM_ECDSAContractAccount', () => {
it(`should revert on incorrect chainId`, async () => { it(`should revert on incorrect chainId`, async () => {
const alteredChainIdTx = { const alteredChainIdTx = {
...DEFAULT_EIP155_TX, ...DEFAULT_EIP155_TX,
chainId : 421 chainId: 421,
} }
const message = serializeNativeTransaction(alteredChainIdTx) const message = serializeNativeTransaction(alteredChainIdTx)
const sig = await signNativeTransaction(wallet, alteredChainIdTx) const sig = await signNativeTransaction(wallet, alteredChainIdTx)
......
...@@ -6,7 +6,15 @@ import { Contract, ContractFactory, Signer, BigNumber } from 'ethers' ...@@ -6,7 +6,15 @@ import { Contract, ContractFactory, Signer, BigNumber } from 'ethers'
import _ from 'lodash' import _ from 'lodash'
/* Internal Imports */ /* Internal Imports */
import { DUMMY_ACCOUNTS, DUMMY_BYTES32, ZERO_ADDRESS, EMPTY_ACCOUNT_CODE_HASH, NON_ZERO_ADDRESS, NON_NULL_BYTES32, STORAGE_XOR_VALUE } from '../../../helpers' import {
DUMMY_ACCOUNTS,
DUMMY_BYTES32,
ZERO_ADDRESS,
EMPTY_ACCOUNT_CODE_HASH,
NON_ZERO_ADDRESS,
NON_NULL_BYTES32,
STORAGE_XOR_VALUE,
} from '../../../helpers'
const DUMMY_ACCOUNT = DUMMY_ACCOUNTS[0] const DUMMY_ACCOUNT = DUMMY_ACCOUNTS[0]
const DUMMY_KEY = DUMMY_BYTES32[0] const DUMMY_KEY = DUMMY_BYTES32[0]
...@@ -14,514 +22,428 @@ const DUMMY_VALUE_1 = DUMMY_BYTES32[1] ...@@ -14,514 +22,428 @@ const DUMMY_VALUE_1 = DUMMY_BYTES32[1]
const DUMMY_VALUE_2 = DUMMY_BYTES32[2] const DUMMY_VALUE_2 = DUMMY_BYTES32[2]
describe('OVM_StateManager gas consumption', () => { describe('OVM_StateManager gas consumption', () => {
let owner: Signer let owner: Signer
before(async () => { before(async () => {
;[owner] = await ethers.getSigners() ;[owner] = await ethers.getSigners()
}) })
let Factory__OVM_StateManager: ContractFactory
let Helper_GasMeasurer: Contract
before(async () => {
Factory__OVM_StateManager = await ethers.getContractFactory(
'OVM_StateManager'
)
Helper_GasMeasurer = await (await (await ethers.getContractFactory( let Factory__OVM_StateManager: ContractFactory
'Helper_GasMeasurer' let Helper_GasMeasurer: Contract
)).deploy()).connect(owner) before(async () => {
}) Factory__OVM_StateManager = await ethers.getContractFactory(
'OVM_StateManager'
)
let OVM_StateManager: Contract Helper_GasMeasurer = await (
beforeEach(async () => { await (await ethers.getContractFactory('Helper_GasMeasurer')).deploy()
OVM_StateManager = ( ).connect(owner)
await Factory__OVM_StateManager.deploy(await owner.getAddress()) })
).connect(owner)
await OVM_StateManager.setExecutionManager(Helper_GasMeasurer.address) let OVM_StateManager: Contract
}) beforeEach(async () => {
OVM_StateManager = (
const measure = ( await Factory__OVM_StateManager.deploy(await owner.getAddress())
methodName: string, ).connect(owner)
methodArgs: Array<any> = [],
doFirst: () => Promise<any> = async () => {return}
) => {
it('measured consumption!', async () => {
await doFirst()
await getSMGasCost(methodName, methodArgs)
})
}
const getSMGasCost = async (methodName: string, methodArgs: Array<any> = []): Promise<number> => { await OVM_StateManager.setExecutionManager(Helper_GasMeasurer.address)
const gasCost: number = await Helper_GasMeasurer.callStatic.measureCallGas( })
OVM_StateManager.address,
OVM_StateManager.interface.encodeFunctionData(
methodName,
methodArgs
)
)
console.log(` calculated gas cost of ${gasCost}`)
return gasCost const measure = (
methodName: string,
methodArgs: Array<any> = [],
doFirst: () => Promise<any> = async () => {
return
} }
) => {
it('measured consumption!', async () => {
await doFirst()
await getSMGasCost(methodName, methodArgs)
})
}
const setupFreshAccount = async () => { const getSMGasCost = async (
await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, { methodName: string,
...DUMMY_ACCOUNT.data, methodArgs: Array<any> = []
isFresh: true, ): Promise<number> => {
}) const gasCost: number = await Helper_GasMeasurer.callStatic.measureCallGas(
} OVM_StateManager.address,
const setupNonFreshAccount = async () => { OVM_StateManager.interface.encodeFunctionData(methodName, methodArgs)
await OVM_StateManager.putAccount( )
DUMMY_ACCOUNT.address, console.log(` calculated gas cost of ${gasCost}`)
DUMMY_ACCOUNT.data
)
}
const putSlot = async (value: string) => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNT.address,
DUMMY_KEY,
value
)
}
describe('ItemState testAndSetters', () => { return gasCost
describe('testAndSetAccountLoaded', () => { }
describe('when account ItemState is ITEM_UNTOUCHED', () => {
measure(
'testAndSetAccountLoaded',
[NON_ZERO_ADDRESS]
)
})
describe('when account ItemState is ITEM_LOADED', () => {
measure(
'testAndSetAccountLoaded',
[NON_ZERO_ADDRESS],
async () => {
await OVM_StateManager.testAndSetAccountLoaded(NON_ZERO_ADDRESS)
}
)
})
describe('when account ItemState is ITEM_CHANGED', () => {
measure(
'testAndSetAccountLoaded',
[NON_ZERO_ADDRESS],
async () => {
await OVM_StateManager.testAndSetAccountChanged(NON_ZERO_ADDRESS)
}
)
})
})
describe('testAndSetAccountChanged', () => {
describe('when account ItemState is ITEM_UNTOUCHED', () => {
measure(
'testAndSetAccountChanged',
[NON_ZERO_ADDRESS]
)
})
describe('when account ItemState is ITEM_LOADED', () => {
measure(
'testAndSetAccountChanged',
[NON_ZERO_ADDRESS],
async () => {
await OVM_StateManager.testAndSetAccountLoaded(NON_ZERO_ADDRESS)
}
)
})
describe('when account ItemState is ITEM_CHANGED', () => {
measure(
'testAndSetAccountChanged',
[NON_ZERO_ADDRESS],
async () => {
await OVM_StateManager.testAndSetAccountChanged(NON_ZERO_ADDRESS)
}
)
})
})
describe('testAndSetContractStorageLoaded', () => { const setupFreshAccount = async () => {
describe('when storage ItemState is ITEM_UNTOUCHED', () => { await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
measure( ...DUMMY_ACCOUNT.data,
'testAndSetContractStorageLoaded', isFresh: true,
[NON_ZERO_ADDRESS, DUMMY_KEY]
)
})
describe('when storage ItemState is ITEM_LOADED', () => {
measure(
'testAndSetContractStorageLoaded',
[NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageLoaded(NON_ZERO_ADDRESS, DUMMY_KEY)
}
)
})
describe('when storage ItemState is ITEM_CHANGED', () => {
measure(
'testAndSetContractStorageLoaded',
[NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageChanged(NON_ZERO_ADDRESS, DUMMY_KEY)
}
)
})
})
describe('testAndSetContractStorageChanged', () => {
describe('when storage ItemState is ITEM_UNTOUCHED', () => {
measure(
'testAndSetContractStorageChanged',
[NON_ZERO_ADDRESS, DUMMY_KEY]
)
})
describe('when storage ItemState is ITEM_LOADED', () => {
measure(
'testAndSetContractStorageChanged',
[NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageLoaded(NON_ZERO_ADDRESS, DUMMY_KEY)
}
)
})
describe('when storage ItemState is ITEM_CHANGED', () => {
measure(
'testAndSetContractStorageChanged',
[NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageChanged(NON_ZERO_ADDRESS, DUMMY_KEY)
}
)
})
})
}) })
}
const setupNonFreshAccount = async () => {
await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, DUMMY_ACCOUNT.data)
}
const putSlot = async (value: string) => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNT.address,
DUMMY_KEY,
value
)
}
describe('incrementTotalUncommittedAccounts', () => { describe('ItemState testAndSetters', () => {
describe('when totalUncommittedAccounts is 0', () => { describe('testAndSetAccountLoaded', () => {
measure('incrementTotalUncommittedAccounts') describe('when account ItemState is ITEM_UNTOUCHED', () => {
measure('testAndSetAccountLoaded', [NON_ZERO_ADDRESS])
})
describe('when account ItemState is ITEM_LOADED', () => {
measure('testAndSetAccountLoaded', [NON_ZERO_ADDRESS], async () => {
await OVM_StateManager.testAndSetAccountLoaded(NON_ZERO_ADDRESS)
}) })
describe('when totalUncommittedAccounts is nonzero', () => { })
const doFirst = async () => { describe('when account ItemState is ITEM_CHANGED', () => {
await OVM_StateManager.incrementTotalUncommittedAccounts() measure('testAndSetAccountLoaded', [NON_ZERO_ADDRESS], async () => {
} await OVM_StateManager.testAndSetAccountChanged(NON_ZERO_ADDRESS)
measure('incrementTotalUncommittedAccounts', [], doFirst)
}) })
})
}) })
describe('incrementTotalUncommittedContractStorage', () => { describe('testAndSetAccountChanged', () => {
describe('when totalUncommittedContractStorage is 0', () => { describe('when account ItemState is ITEM_UNTOUCHED', () => {
measure('incrementTotalUncommittedContractStorage') measure('testAndSetAccountChanged', [NON_ZERO_ADDRESS])
})
describe('when account ItemState is ITEM_LOADED', () => {
measure('testAndSetAccountChanged', [NON_ZERO_ADDRESS], async () => {
await OVM_StateManager.testAndSetAccountLoaded(NON_ZERO_ADDRESS)
}) })
describe('when totalUncommittedContractStorage is nonzero', () => { })
const doFirst = async () => { describe('when account ItemState is ITEM_CHANGED', () => {
await OVM_StateManager.incrementTotalUncommittedContractStorage() measure('testAndSetAccountChanged', [NON_ZERO_ADDRESS], async () => {
} await OVM_StateManager.testAndSetAccountChanged(NON_ZERO_ADDRESS)
measure('incrementTotalUncommittedContractStorage', [], doFirst)
}) })
})
}) })
describe('hasAccount', () => { describe('testAndSetContractStorageLoaded', () => {
describe('when it does have the account', () => { describe('when storage ItemState is ITEM_UNTOUCHED', () => {
const doFirst = async () => { measure('testAndSetContractStorageLoaded', [
await OVM_StateManager.putAccount( NON_ZERO_ADDRESS,
DUMMY_ACCOUNT.address, DUMMY_KEY,
DUMMY_ACCOUNT.data ])
) })
} describe('when storage ItemState is ITEM_LOADED', () => {
measure( measure(
'hasAccount', 'testAndSetContractStorageLoaded',
[DUMMY_ACCOUNT.address], [NON_ZERO_ADDRESS, DUMMY_KEY],
doFirst async () => {
await OVM_StateManager.testAndSetContractStorageLoaded(
NON_ZERO_ADDRESS,
DUMMY_KEY
) )
}) }
)
})
describe('when storage ItemState is ITEM_CHANGED', () => {
measure(
'testAndSetContractStorageLoaded',
[NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageChanged(
NON_ZERO_ADDRESS,
DUMMY_KEY
)
}
)
})
}) })
describe('hasEmptyAccount', () => { describe('testAndSetContractStorageChanged', () => {
describe('when it does have an empty account', () => { describe('when storage ItemState is ITEM_UNTOUCHED', () => {
measure( measure('testAndSetContractStorageChanged', [
'hasEmptyAccount', NON_ZERO_ADDRESS,
[DUMMY_ACCOUNT.address], DUMMY_KEY,
async () => { ])
await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, { })
...DUMMY_ACCOUNT.data, describe('when storage ItemState is ITEM_LOADED', () => {
codeHash: EMPTY_ACCOUNT_CODE_HASH, measure(
}) 'testAndSetContractStorageChanged',
} [NON_ZERO_ADDRESS, DUMMY_KEY],
async () => {
await OVM_StateManager.testAndSetContractStorageLoaded(
NON_ZERO_ADDRESS,
DUMMY_KEY
) )
}) }
describe('when it has an account which is not emtpy', () => { )
measure( })
'hasEmptyAccount', describe('when storage ItemState is ITEM_CHANGED', () => {
[DUMMY_ACCOUNT.address], measure(
async () => { 'testAndSetContractStorageChanged',
await OVM_StateManager.putAccount( [NON_ZERO_ADDRESS, DUMMY_KEY],
DUMMY_ACCOUNT.address, async () => {
DUMMY_ACCOUNT.data await OVM_StateManager.testAndSetContractStorageChanged(
) NON_ZERO_ADDRESS,
} DUMMY_KEY
) )
}
)
})
})
})
describe('incrementTotalUncommittedAccounts', () => {
describe('when totalUncommittedAccounts is 0', () => {
measure('incrementTotalUncommittedAccounts')
})
describe('when totalUncommittedAccounts is nonzero', () => {
const doFirst = async () => {
await OVM_StateManager.incrementTotalUncommittedAccounts()
}
measure('incrementTotalUncommittedAccounts', [], doFirst)
})
})
describe('incrementTotalUncommittedContractStorage', () => {
describe('when totalUncommittedContractStorage is 0', () => {
measure('incrementTotalUncommittedContractStorage')
})
describe('when totalUncommittedContractStorage is nonzero', () => {
const doFirst = async () => {
await OVM_StateManager.incrementTotalUncommittedContractStorage()
}
measure('incrementTotalUncommittedContractStorage', [], doFirst)
})
})
describe('hasAccount', () => {
describe('when it does have the account', () => {
const doFirst = async () => {
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
DUMMY_ACCOUNT.data
)
}
measure('hasAccount', [DUMMY_ACCOUNT.address], doFirst)
})
})
describe('hasEmptyAccount', () => {
describe('when it does have an empty account', () => {
measure('hasEmptyAccount', [DUMMY_ACCOUNT.address], async () => {
await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
...DUMMY_ACCOUNT.data,
codeHash: EMPTY_ACCOUNT_CODE_HASH,
}) })
})
}) })
describe('when it has an account which is not emtpy', () => {
measure('hasEmptyAccount', [DUMMY_ACCOUNT.address], async () => {
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
DUMMY_ACCOUNT.data
)
})
})
})
describe('setAccountNonce', () => { describe('setAccountNonce', () => {
describe('when the nonce is 0 and set to 0', () => { describe('when the nonce is 0 and set to 0', () => {
measure( measure('setAccountNonce', [DUMMY_ACCOUNT.address, 0], async () => {
'setAccountNonce', await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
[DUMMY_ACCOUNT.address, 0], ...DUMMY_ACCOUNT.data,
async () => { nonce: 0,
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
{
...DUMMY_ACCOUNT.data,
nonce: 0
}
)
}
)
}) })
describe('when the nonce is 0 and set to nonzero', () => { })
measure( })
'setAccountNonce', describe('when the nonce is 0 and set to nonzero', () => {
[DUMMY_ACCOUNT.address, 1], measure('setAccountNonce', [DUMMY_ACCOUNT.address, 1], async () => {
async () => { await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
await OVM_StateManager.putAccount( ...DUMMY_ACCOUNT.data,
DUMMY_ACCOUNT.address, nonce: 0,
{
...DUMMY_ACCOUNT.data,
nonce: 0
}
)
}
)
}) })
describe('when the nonce is nonzero and set to 0', () => { })
measure( })
'setAccountNonce', describe('when the nonce is nonzero and set to 0', () => {
[DUMMY_ACCOUNT.address, 0], measure('setAccountNonce', [DUMMY_ACCOUNT.address, 0], async () => {
async () => { await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
await OVM_StateManager.putAccount( ...DUMMY_ACCOUNT.data,
DUMMY_ACCOUNT.address, nonce: 1,
{
...DUMMY_ACCOUNT.data,
nonce: 1
}
)
}
)
}) })
describe('when the nonce is nonzero and set to nonzero', () => { })
measure( })
'setAccountNonce', describe('when the nonce is nonzero and set to nonzero', () => {
[DUMMY_ACCOUNT.address, 2], measure('setAccountNonce', [DUMMY_ACCOUNT.address, 2], async () => {
async () => { await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
await OVM_StateManager.putAccount( ...DUMMY_ACCOUNT.data,
DUMMY_ACCOUNT.address, nonce: 1,
{
...DUMMY_ACCOUNT.data,
nonce: 1
}
)
}
)
}) })
})
}) })
})
describe('getAccountNonce', () => { describe('getAccountNonce', () => {
describe('when the nonce is 0', () => { describe('when the nonce is 0', () => {
measure( measure('getAccountNonce', [DUMMY_ACCOUNT.address])
'getAccountNonce', })
[DUMMY_ACCOUNT.address] describe('when the nonce is nonzero', () => {
) measure('getAccountNonce', [DUMMY_ACCOUNT.address], async () => {
}) await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
describe('when the nonce is nonzero', () => { ...DUMMY_ACCOUNT.data,
measure( nonce: 1,
'getAccountNonce',
[DUMMY_ACCOUNT.address],
async () => {
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
{
...DUMMY_ACCOUNT.data,
nonce: 1
}
)
}
)
}) })
})
}) })
})
describe('getAccountEthAddress', () => { describe('getAccountEthAddress', () => {
describe('when the ethAddress is a random address', () => { describe('when the ethAddress is a random address', () => {
measure( measure('getAccountEthAddress', [DUMMY_ACCOUNT.address], async () => {
'getAccountEthAddress', await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
[DUMMY_ACCOUNT.address], ...DUMMY_ACCOUNT.data,
async () => { ethAddress: NON_ZERO_ADDRESS,
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
{
...DUMMY_ACCOUNT.data,
ethAddress: NON_ZERO_ADDRESS
}
)
}
)
})
describe('when the ethAddress is zero', () => {
measure(
'getAccountEthAddress',
[DUMMY_ACCOUNT.address],
async () => {
await OVM_StateManager.putAccount(
DUMMY_ACCOUNT.address,
{
...DUMMY_ACCOUNT.data,
ethAddress: ZERO_ADDRESS
}
)
}
)
}) })
})
}) })
describe('when the ethAddress is zero', () => {
describe('initPendingAccount', () => { measure('getAccountEthAddress', [DUMMY_ACCOUNT.address], async () => {
// note: this method should only be accessibl if _hasEmptyAccount is true, so it should always be empty nonce etc await OVM_StateManager.putAccount(DUMMY_ACCOUNT.address, {
measure( ...DUMMY_ACCOUNT.data,
'initPendingAccount', ethAddress: ZERO_ADDRESS,
[NON_ZERO_ADDRESS] })
) })
}) })
})
describe('initPendingAccount', () => {
// note: this method should only be accessibl if _hasEmptyAccount is true, so it should always be empty nonce etc
measure('initPendingAccount', [NON_ZERO_ADDRESS])
})
describe('commitPendingAccount', () => {
// this should only set ethAddress and codeHash from ZERO to NONZERO, so one case should be sufficient
measure(
'commitPendingAccount',
[NON_ZERO_ADDRESS, NON_ZERO_ADDRESS, NON_NULL_BYTES32],
async () => {
await OVM_StateManager.initPendingAccount(NON_ZERO_ADDRESS)
}
)
})
describe('commitPendingAccount', () => { describe('getContractStorage', () => {
// this should only set ethAddress and codeHash from ZERO to NONZERO, so one case should be sufficient // confirm with kelvin that this covers all cases
describe('when the account isFresh', () => {
describe('when the storage slot value has not been set', () => {
measure( measure(
'commitPendingAccount', 'getContractStorage',
[ [DUMMY_ACCOUNT.address, DUMMY_KEY],
NON_ZERO_ADDRESS, setupFreshAccount
NON_ZERO_ADDRESS, )
NON_NULL_BYTES32 })
], describe('when the storage slot has already been set', () => {
describe('when the storage slot value is STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => { async () => {
await OVM_StateManager.initPendingAccount(NON_ZERO_ADDRESS) await setupFreshAccount()
await putSlot(STORAGE_XOR_VALUE)
} }
) )
})
describe('getContractStorage', () => {
// confirm with kelvin that this covers all cases
describe('when the account isFresh', () => {
describe('when the storage slot value has not been set', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
setupFreshAccount
)
})
describe('when the storage slot has already been set', () => {
describe('when the storage slot value is STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupFreshAccount()
await putSlot(STORAGE_XOR_VALUE)
}
)
})
describe('when the storage slot value is something other than STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupFreshAccount()
await putSlot(DUMMY_VALUE_1)
}
)
})
})
}) })
describe('when the account is not fresh', () => { describe('when the storage slot value is something other than STORAGE_XOR_VALUE', () => {
describe('when the storage slot value is STORAGE_XOR_VALUE', () => { measure(
measure( 'getContractStorage',
'getContractStorage', [DUMMY_ACCOUNT.address, DUMMY_KEY],
[DUMMY_ACCOUNT.address, DUMMY_KEY], async () => {
async () => { await setupFreshAccount()
await setupNonFreshAccount() await putSlot(DUMMY_VALUE_1)
await putSlot(STORAGE_XOR_VALUE)
}
)
})
describe('when the storage slot value is something other than STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupNonFreshAccount()
await putSlot(DUMMY_VALUE_1)
}
)
})
})
})
describe('putContractStorage', () => {
const relevantValues = [
DUMMY_VALUE_1,
DUMMY_VALUE_2,
STORAGE_XOR_VALUE
]
for (let preValue of relevantValues) {
for (let postValue of relevantValues) {
describe(`when overwriting ${preValue} with ${postValue}`, () => {
measure(
'putContractStorage',
[NON_ZERO_ADDRESS, DUMMY_KEY, postValue],
async () => {
await OVM_StateManager.putContractStorage(
NON_ZERO_ADDRESS,
DUMMY_KEY,
preValue
)
}
)
})
} }
} )
})
})
}) })
describe('when the account is not fresh', () => {
describe('when the storage slot value is STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupNonFreshAccount()
await putSlot(STORAGE_XOR_VALUE)
}
)
})
describe('when the storage slot value is something other than STORAGE_XOR_VALUE', () => {
measure(
'getContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupNonFreshAccount()
await putSlot(DUMMY_VALUE_1)
}
)
})
})
})
describe('hasContractStorage', () => { describe('putContractStorage', () => {
describe('when the account is fresh', () => { const relevantValues = [DUMMY_VALUE_1, DUMMY_VALUE_2, STORAGE_XOR_VALUE]
describe('when the storage slot has not been set', () => { for (let preValue of relevantValues) {
measure( for (let postValue of relevantValues) {
'hasContractStorage', describe(`when overwriting ${preValue} with ${postValue}`, () => {
[DUMMY_ACCOUNT.address, DUMMY_KEY], measure(
setupFreshAccount 'putContractStorage',
) [NON_ZERO_ADDRESS, DUMMY_KEY, postValue],
}) async () => {
describe('when the slot has already been set', () => { await OVM_StateManager.putContractStorage(
measure( NON_ZERO_ADDRESS,
'hasContractStorage', DUMMY_KEY,
[DUMMY_ACCOUNT.address, DUMMY_KEY], preValue
async () => { )
await setupFreshAccount() }
await OVM_StateManager.putContractStorage( )
DUMMY_ACCOUNT.address,
DUMMY_KEY,
DUMMY_VALUE_1
)
}
)
})
}) })
describe('when the account is not fresh', () => { }
measure( }
'hasContractStorage', })
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => { describe('hasContractStorage', () => {
await OVM_StateManager.putContractStorage( describe('when the account is fresh', () => {
DUMMY_ACCOUNT.address, describe('when the storage slot has not been set', () => {
DUMMY_KEY, measure(
DUMMY_VALUE_1 'hasContractStorage',
) [DUMMY_ACCOUNT.address, DUMMY_KEY],
} setupFreshAccount
)
})
describe('when the slot has already been set', () => {
measure(
'hasContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await setupFreshAccount()
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNT.address,
DUMMY_KEY,
DUMMY_VALUE_1
) )
}) }
)
})
})
describe('when the account is not fresh', () => {
measure(
'hasContractStorage',
[DUMMY_ACCOUNT.address, DUMMY_KEY],
async () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNT.address,
DUMMY_KEY,
DUMMY_VALUE_1
)
}
)
}) })
}) })
\ No newline at end of file })
...@@ -6,9 +6,13 @@ import { Contract, ContractFactory, Signer, BigNumber } from 'ethers' ...@@ -6,9 +6,13 @@ import { Contract, ContractFactory, Signer, BigNumber } from 'ethers'
import _ from 'lodash' import _ from 'lodash'
/* Internal Imports */ /* Internal Imports */
import { DUMMY_ACCOUNTS, DUMMY_BYTES32, ZERO_ADDRESS, EMPTY_ACCOUNT_CODE_HASH, KECCAK_256_NULL } from '../../../helpers' import {
DUMMY_ACCOUNTS,
DUMMY_BYTES32,
ZERO_ADDRESS,
EMPTY_ACCOUNT_CODE_HASH,
KECCAK_256_NULL,
} from '../../../helpers'
describe('OVM_StateManager', () => { describe('OVM_StateManager', () => {
let signer1: Signer let signer1: Signer
......
...@@ -192,7 +192,7 @@ describe('OVM_FraudVerifier', () => { ...@@ -192,7 +192,7 @@ describe('OVM_FraudVerifier', () => {
}) })
it('should revert when provided with a incorrect transaction root global index', async () => { it('should revert when provided with a incorrect transaction root global index', async () => {
await expect ( await expect(
OVM_FraudVerifier.initializeFraudVerification( OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32, NULL_BYTES32,
DUMMY_BATCH_HEADERS[0], DUMMY_BATCH_HEADERS[0],
...@@ -202,7 +202,9 @@ describe('OVM_FraudVerifier', () => { ...@@ -202,7 +202,9 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADERS[0], DUMMY_BATCH_HEADERS[0],
DUMMY_BATCH_PROOFS_WITH_INDEX[0] DUMMY_BATCH_PROOFS_WITH_INDEX[0]
) )
).to.be.revertedWith('Pre-state root global index must equal to the transaction root global index.') ).to.be.revertedWith(
'Pre-state root global index must equal to the transaction root global index.'
)
}) })
}) })
}) })
......
...@@ -4,6 +4,7 @@ import { expect } from '../../../setup' ...@@ -4,6 +4,7 @@ import { expect } from '../../../setup'
/* External Imports */ /* External Imports */
import { ethers } from '@nomiclabs/buidler' import { ethers } from '@nomiclabs/buidler'
import { BigNumber, Contract, ContractFactory } from 'ethers' import { BigNumber, Contract, ContractFactory } from 'ethers'
import * as rlp from 'rlp'
/* Internal Imports */ /* Internal Imports */
import { import {
...@@ -234,7 +235,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -234,7 +235,7 @@ describe('OVM_StateTransitioner', () => {
nodes: [ nodes: [
{ {
key, key,
val, val: '0x' + rlp.encode(val).toString('hex'),
}, },
], ],
secure: true, secure: true,
...@@ -268,7 +269,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -268,7 +269,7 @@ describe('OVM_StateTransitioner', () => {
nodes: [ nodes: [
{ {
key, key,
val, val: '0x' + rlp.encode(val).toString('hex'),
}, },
], ],
secure: true, secure: true,
...@@ -452,7 +453,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -452,7 +453,7 @@ describe('OVM_StateTransitioner', () => {
nodes: [ nodes: [
{ {
key, key,
val, val: '0x' + rlp.encode(val).toString('hex'),
}, },
], ],
secure: true, secure: true,
...@@ -460,7 +461,7 @@ describe('OVM_StateTransitioner', () => { ...@@ -460,7 +461,7 @@ describe('OVM_StateTransitioner', () => {
const storageTest = await storageGenerator.makeNodeUpdateTest( const storageTest = await storageGenerator.makeNodeUpdateTest(
key, key,
newVal '0x' + rlp.encode(newVal).toString('hex')
) )
const generator = await TrieTestGenerator.fromAccounts({ const generator = await TrieTestGenerator.fromAccounts({
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment