Commit 3e81548f authored by Kelvin Fichter's avatar Kelvin Fichter

Linted files

parent 8575b629
import { usePlugin, BuidlerConfig } from '@nomiclabs/buidler/config'
import {
DEFAULT_ACCOUNTS_BUIDLER,
GAS_LIMIT,
} from './test/helpers/constants'
import { DEFAULT_ACCOUNTS_BUIDLER, GAS_LIMIT } from './test/helpers/constants'
usePlugin('@nomiclabs/buidler-ethers')
usePlugin('@nomiclabs/buidler-waffle')
......@@ -21,7 +18,7 @@ const config: BuidlerConfig = {
timeout: 50000,
},
solc: {
version: "0.7.0",
version: '0.7.0',
optimizer: { enabled: true, runs: 200 },
},
}
......
......@@ -8,13 +8,13 @@
## Test Cases
- CALL-types
- for all: call an undeployed contract and make sure it errors or whatevs (or maybe that's just a unit test)
- ovmCALL
ALL DONE - ovmCALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
- -> SSTORE
- -> CREATE/2
- ovmSTATICCALL
ALL DONE - ovmSTATICCALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
......@@ -22,27 +22,31 @@
- -> CREATE/2 (fail)
- -> ovmCALL -> ovmSSTORE
- -> ovmCALL -> ovmCREATE
- -> ovmSTATICCALL -> RETURN -> SLOAD (fails)
- -> ovmSTATICCALL -> RETURN -> SSTORE (fails)
- ovmDELEGATECALL
- -> ovmCALLER
- -> ovmADDRESS
- -> SLOAD
- -> SSTORE
- -> CREATE/2
- -> ovmDELEGATECALL -> ovmCALLER
- -> ovmDELEGATECALL -> ovmADDRESS
DONE - -> ovmCALLER
DONE - -> ovmADDRESS
DONE - -> SLOAD
DONE - -> SSTORE
DONE - -> CREATE/2
DONE - -> ovmDELEGATECALL -> ovmCALLER
DONE - -> ovmDELEGATECALL -> ovmADDRESS
DONE - -> ovmDELEGATECALL -> ovmCREATE
- Code-related
- TODO: fill this in
- CREATE-types
- do we just duplicate these exactly for CREATE and CREATE2? Probably
- ovmCREATE -> success -> ovmEXTCODE{SIZE,HASH,COPY}
- ovmCREATE -> fail (ovmREVERT, NOT out of gas/invalid jump) -> ovmEXTCODE{SIZE,HASH,COPY}
DONE - ovmCREATE -> success -> ovmEXTCODE{SIZE,HASH,COPY}
DONE - ovmCREATE -> fail (ovmREVERT, NOT out of gas/invalid jump) -> ovmEXTCODE{SIZE,HASH,COPY}
- ovmCREATE -> fail -> ovmCALL what was attempted to be created (fail)
- ovmCREATE -> ovmCREATE (during constructor) -> success -> success (check right address for inner deployment)
- ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
DONE - ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
DONE - ovmCREATE -> INVALID -> returns 0 address
- ovmCREATE -> ovmCREATE (during constructor) -> success -> fail (outer contract)
- "creator" does ovmCREATE -> invalid jumpdest -> creator out-of-gasses (or at least, appears to--really it will revert with no data, so there will be some gas left)
- "creator" does ovmCREATE -> initcode does ovmCREATE -> invalid jumpdest -> creator out-of-gasses (or at least, appears to--really it will revert with no data, so there will be some gas left) AKA same as above but nested CREATEs
- CREATE collisions: TODO fill in what this needs
- OVM gas metering
- do everything for both queue origins/flip flopped roles:
......@@ -52,6 +56,7 @@
- out of gas
- ovmCALL -> [ovmCALL(gas()/2) -> out of gas] -> SSTORE (does not out of gas parent)
- ovmCREATE -> ovmCALL(in constructor) -> ovmSSTORE, return -> ovmREVERT (deployment fails, storage not modified, but state access gas correctly increased)
- State access limiting logic
......@@ -70,9 +75,9 @@
- Explicit invalid state access tests
- CALL -> CALL, ISA
- CALL -> CALL, CALL, ISA
- CREATE -> CREATE, ISA
DONE - CREATE -> CREATE, ISA
- CREATE -> CREATE -> CREATE ISA
- CREATE -> CALL, ISA
- CALL -> CREATE, ISA
DONE - CREATE -> CALL, ISA
DONE - CALL -> CREATE, ISA
- CALL -> CREATE -> CALL, ISA
- CREATE -> CALL -> CREATE, ISA
\ No newline at end of file
......@@ -7,7 +7,9 @@
"build": "yarn run build:contracts",
"build:contracts": "buidler compile",
"test": "yarn run test:contracts",
"test:contracts": "buidler test \"test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts\""
"test:contracts": "buidler test \"test/contracts/OVM/execution/OVM_ExecutionManager/ovmSTATICCALL.spec.ts\"",
"lint": "tslint --format stylish --project .",
"fix": "prettier --config prettier-config.json --write \"buidler.config.ts\" \"{src,test}/**/*.ts\""
},
"devDependencies": {
"@nomiclabs/buidler": "^1.4.4",
......@@ -23,7 +25,12 @@
"fs-extra": "^9.0.1",
"lodash": "^4.17.20",
"mocha": "^8.1.1",
"prettier": "^2.1.2",
"ts-node": "^9.0.0",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tslint-no-focused-test": "^0.5.0",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "^4.0.2"
}
}
{
"$schema": "http://json.schemastore.org/prettierrc",
"trailingComma": "es5",
"tabWidth": 2,
"semi": false,
"singleQuote": true,
"arrowParens": "always"
}
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
describe('OVM_ECDSAContractAccount', () => {
describe('execute', () => {
describe('when provided an invalid signature', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid signature', () => {
describe('when provided an invalid nonce', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid nonce', () => {
describe('when executing ovmCREATE', () => {
it('should return the address of the created contract', async () => {
})
it('should return the address of the created contract', async () => {})
})
describe('when executing ovmCALL', () => {
it('should return the result of the call', async () => {
})
it('should return the result of the call', async () => {})
})
})
})
......
......@@ -12,7 +12,7 @@ import {
setProxyTarget,
NON_NULL_BYTES32,
FORCE_INCLUSION_PERIOD_SECONDS,
ZERO_ADDRESS
ZERO_ADDRESS,
} from '../../../helpers'
const getEthTime = async (): Promise<number> => {
......@@ -85,10 +85,10 @@ describe('OVM_CanonicalTransactionChain', () => {
const timestamp = await getEthTime()
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
await setEthTime(timestamp + FORCE_INCLUSION_PERIOD_SECONDS / 2)
})
......@@ -96,7 +96,9 @@ describe('OVM_CanonicalTransactionChain', () => {
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendQueueBatch()
).to.be.revertedWith('Cannot append until the inclusion delay period has elapsed.')
).to.be.revertedWith(
'Cannot append until the inclusion delay period has elapsed.'
)
})
})
......@@ -105,25 +107,24 @@ describe('OVM_CanonicalTransactionChain', () => {
const timestamp = await getEthTime()
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('dequeue', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
await setEthTime(timestamp + FORCE_INCLUSION_PERIOD_SECONDS)
})
it('should append the top element of the queue and attempt to dequeue', async () => {
await expect(
OVM_CanonicalTransactionChain.appendQueueBatch()
).to.not.be.reverted
await expect(OVM_CanonicalTransactionChain.appendQueueBatch()).to.not
.be.reverted
// TODO: Check that the batch root was inserted.
......@@ -138,28 +139,19 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('appendSequencerBatch()', () => {
describe('when the sender is not the sequencer', () => {
before(async () => {
await Proxy_Manager.setProxy(
'Sequencer',
ZERO_ADDRESS
)
await Proxy_Manager.setProxy('Sequencer', ZERO_ADDRESS)
})
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendSequencerBatch(
[],
0
)
OVM_CanonicalTransactionChain.appendSequencerBatch([], 0)
).to.be.revertedWith('Function can only be called by the Sequencer.')
})
})
describe('when the sender is the sequencer', () => {
before(async () => {
await Proxy_Manager.setProxy(
'Sequencer',
await signer.getAddress()
)
await Proxy_Manager.setProxy('Sequencer', await signer.getAddress())
})
describe('when the given batch is empty', () => {
......@@ -167,10 +159,7 @@ describe('OVM_CanonicalTransactionChain', () => {
it('should revert', async () => {
await expect(
OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
0
)
OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 0)
).to.be.revertedWith('Cannot submit an empty batch.')
})
})
......@@ -179,7 +168,7 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = [NON_NULL_BYTES32]
describe('when the timestamp is not greater than the previous OVM timestamp', () => {
const timestamp = 0;
const timestamp = 0
it('should revert', async () => {
await expect(
......@@ -187,12 +176,14 @@ describe('OVM_CanonicalTransactionChain', () => {
batch,
timestamp
)
).to.be.revertedWith('Batch timestamp must be later than the last OVM timestamp.')
).to.be.revertedWith(
'Batch timestamp must be later than the last OVM timestamp.'
)
})
})
describe('when the timestamp is greater than the previous OVM timestamp', () => {
const timestamp = 1000;
const timestamp = 1000
describe('when the queue is not empty', () => {
before(() => {
......@@ -205,8 +196,8 @@ describe('OVM_CanonicalTransactionChain', () => {
{
timestamp: timestamp / 2,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
})
......@@ -216,7 +207,9 @@ describe('OVM_CanonicalTransactionChain', () => {
batch,
timestamp
)
).to.be.revertedWith('Older queue batches must be processed before a newer sequencer batch.')
).to.be.revertedWith(
'Older queue batches must be processed before a newer sequencer batch.'
)
})
})
......@@ -224,10 +217,10 @@ describe('OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('peek', [
{
timestamp: timestamp,
timestamp,
batchRoot: NON_NULL_BYTES32,
isL1ToL2Batch: true
}
isL1ToL2Batch: true,
},
])
})
......@@ -268,9 +261,9 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('getTotalElements()', () => {
describe('when no batch elements have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(0)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
0
)
})
})
......@@ -284,9 +277,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(1)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
1
)
})
})
......@@ -294,16 +287,13 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = Array(64).fill(NON_NULL_BYTES32)
beforeEach(async () => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('size', [0])
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
1000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 1000)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(64)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
64
)
})
})
......@@ -311,20 +301,14 @@ describe('OVM_CanonicalTransactionChain', () => {
const batch = Array(32).fill(NON_NULL_BYTES32)
beforeEach(async () => {
Mock__OVM_L1ToL2TransactionQueue.setReturnValues('size', [0])
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
1000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(
batch,
2000
)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 1000)
await OVM_CanonicalTransactionChain.appendSequencerBatch(batch, 2000)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalElements()
).to.equal(64)
expect(await OVM_CanonicalTransactionChain.getTotalElements()).to.equal(
64
)
})
})
})
......@@ -332,9 +316,9 @@ describe('OVM_CanonicalTransactionChain', () => {
describe('getTotalBatches()', () => {
describe('when no batches have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(0)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
0
)
})
})
......@@ -348,9 +332,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(1)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
1
)
})
})
......@@ -366,9 +350,9 @@ describe('OVM_CanonicalTransactionChain', () => {
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_CanonicalTransactionChain.getTotalBatches()
).to.equal(8)
expect(await OVM_CanonicalTransactionChain.getTotalBatches()).to.equal(
8
)
})
})
})
......
......@@ -11,7 +11,7 @@ import {
getMockContract,
setProxyTarget,
NON_NULL_BYTES32,
ZERO_ADDRESS
ZERO_ADDRESS,
} from '../../../helpers'
describe('OVM_StateCommitmentChain', () => {
......@@ -55,7 +55,7 @@ describe('OVM_StateCommitmentChain', () => {
describe('appendStateBatch', () => {
describe('when the provided batch is empty', () => {
const batch = []
it('should revert', async () => {
await expect(
OVM_StateCommitmentChain.appendStateBatch(batch)
......@@ -68,25 +68,32 @@ describe('OVM_StateCommitmentChain', () => {
describe('when submitting more elements than present in the OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length - 1])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length - 1]
)
})
it('should revert', async () => {
await expect(
OVM_StateCommitmentChain.appendStateBatch(batch)
).to.be.revertedWith('Number of state roots cannot exceed the number of canonical transactions.')
).to.be.revertedWith(
'Number of state roots cannot exceed the number of canonical transactions.'
)
})
})
describe('when not submitting more elements than present in the OVM_CanonicalTransactionChain', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
})
it('should append the state batch', async () => {
await expect(
OVM_StateCommitmentChain.appendStateBatch(batch)
).to.not.be.reverted
await expect(OVM_StateCommitmentChain.appendStateBatch(batch)).to.not
.be.reverted
// TODO: Check for correct insertion.
})
......@@ -102,26 +109,27 @@ describe('OVM_StateCommitmentChain', () => {
batchRoot: NON_NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: '0x'
extraData: '0x',
}
beforeEach(async () => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [
batch.length,
])
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
describe('when the sender is not the OVM_FraudVerifier', () => {
before(async () => {
await Proxy_Manager.setProxy(
'OVM_FraudVerifier',
ZERO_ADDRESS
)
await Proxy_Manager.setProxy('OVM_FraudVerifier', ZERO_ADDRESS)
})
it('should revert', async () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch(batchHeader)
).to.be.revertedWith('State batches can only be deleted by the OVM_FraudVerifier.')
).to.be.revertedWith(
'State batches can only be deleted by the OVM_FraudVerifier.'
)
})
})
......@@ -138,7 +146,7 @@ describe('OVM_StateCommitmentChain', () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch({
...batchHeader,
batchIndex: 1
batchIndex: 1,
})
).to.be.revertedWith('Invalid batch index.')
})
......@@ -150,7 +158,7 @@ describe('OVM_StateCommitmentChain', () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch({
...batchHeader,
extraData: '0x1234'
extraData: '0x1234',
})
).to.be.revertedWith('Invalid batch header.')
})
......@@ -158,9 +166,8 @@ describe('OVM_StateCommitmentChain', () => {
describe('when the provided batch header is valid', () => {
it('should remove the batch and all following batches', async () => {
await expect(
OVM_StateCommitmentChain.deleteStateBatch(batchHeader)
).to.not.be.reverted
await expect(OVM_StateCommitmentChain.deleteStateBatch(batchHeader))
.to.not.be.reverted
// TODO: Check that it deleted the batches.
})
......@@ -172,52 +179,53 @@ describe('OVM_StateCommitmentChain', () => {
describe('getTotalElements', () => {
describe('when no batch elements have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(0)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(0)
})
})
describe('when one batch element has been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(1)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(1)
})
})
describe('when 64 batch elements have been inserted in one batch', () => {
beforeEach(async () => {
const batch = Array(64).fill(NON_NULL_BYTES32)
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(64)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(64)
})
})
describe('when 32 batch elements have been inserted in each of two batches', () => {
beforeEach(async () => {
const batch = Array(32).fill(NON_NULL_BYTES32)
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length * 2])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length * 2]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalElements()
).to.equal(64)
expect(await OVM_StateCommitmentChain.getTotalElements()).to.equal(64)
})
})
})
......@@ -225,39 +233,39 @@ describe('OVM_StateCommitmentChain', () => {
describe('getTotalBatches()', () => {
describe('when no batches have been inserted', () => {
it('should return zero', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(0)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(0)
})
})
describe('when one batch has been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length]
)
await OVM_StateCommitmentChain.appendStateBatch(batch)
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(1)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(1)
})
})
describe('when 8 batches have been inserted', () => {
beforeEach(async () => {
const batch = [NON_NULL_BYTES32]
Mock__OVM_CanonicalTransactionChain.setReturnValues('getTotalElements', [batch.length * 8])
Mock__OVM_CanonicalTransactionChain.setReturnValues(
'getTotalElements',
[batch.length * 8]
)
for (let i = 0; i < 8; i++) {
await OVM_StateCommitmentChain.appendStateBatch(batch)
}
})
it('should return the number of inserted batch elements', async () => {
expect(
await OVM_StateCommitmentChain.getTotalBatches()
).to.equal(8)
expect(await OVM_StateCommitmentChain.getTotalBatches()).to.equal(8)
})
})
})
......@@ -275,4 +283,4 @@ describe('OVM_StateCommitmentChain', () => {
// TODO
})
})
})
\ No newline at end of file
})
......@@ -6,60 +6,60 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const test_ovmREVERT: TestDefinition = {
name: "basic ovmREVERT unit tests",
name: 'basic ovmREVERT unit tests',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
}
}
},
},
},
parameters: [
{
name: "ovmREVERT inside ovmCALL should cause EM to revert",
name: 'ovmREVERT inside ovmCALL should cause EM to revert',
parameters: [
{
steps: [
{
functionName: "ovmCALL",
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT / 2,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: "ovmREVERT",
functionParams: [ "0xdeadbeef" ],
functionName: 'ovmREVERT',
functionParams: ['0xdeadbeef'],
expectedReturnStatus: false,
expectedReturnValues: [
REVERT_FLAGS.INTENTIONAL_REVERT,
"0xdeadbeef",
'0xdeadbeef',
GAS_LIMIT / 2,
0
]
}
]
0,
],
},
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
},
// TODO: fix this. only way to do it is manually set up and call ovmREVERT directly inside a context which mirrors that during creation.
// {
......@@ -100,7 +100,7 @@ const test_ovmREVERT: TestDefinition = {
// }
// ]
// }
]
],
}
runExecutionManagerTest(test_ovmREVERT)
......@@ -6,37 +6,38 @@ import {
NULL_BYTES32,
NON_NULL_BYTES32,
REVERT_FLAGS,
DUMMY_BYTECODE
DUMMY_BYTECODE,
} from '../../../../helpers'
const test_ovmSLOAD: TestDefinition = {
name: "External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed",
name:
'External storage manipulation during initcode subcalls should correctly NOT be persisted if ovmREVERTed',
preState: {
ExecutionManager: {
ovmStateManager: "$OVM_STATE_MANAGER",
ovmSafetyChecker: "$OVM_SAFETY_CHECKER",
ovmStateManager: '$OVM_STATE_MANAGER',
ovmSafetyChecker: '$OVM_SAFETY_CHECKER',
messageRecord: {
nuisanceGasLeft: GAS_LIMIT
}
nuisanceGasLeft: GAS_LIMIT,
},
},
StateManager: {
owner: "$OVM_EXECUTION_MANAGER",
owner: '$OVM_EXECUTION_MANAGER',
accounts: {
"$DUMMY_OVM_ADDRESS_1": {
$DUMMY_OVM_ADDRESS_1: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
"$DUMMY_OVM_ADDRESS_2": {
$DUMMY_OVM_ADDRESS_2: {
codeHash: NON_NULL_BYTES32,
ethAddress: "$OVM_CALL_HELPER"
ethAddress: '$OVM_CALL_HELPER',
},
},
verifiedContractStorage: {
"$DUMMY_OVM_ADDRESS_1": {
[NON_NULL_BYTES32]: true
}
}
}
$DUMMY_OVM_ADDRESS_1: {
[NON_NULL_BYTES32]: true,
},
},
},
},
parameters: [
{
......@@ -45,22 +46,22 @@ const test_ovmSLOAD: TestDefinition = {
functionName: 'ovmCALL',
functionParams: [
GAS_LIMIT,
"$DUMMY_OVM_ADDRESS_1",
'$DUMMY_OVM_ADDRESS_1',
[
{
functionName: 'ovmSLOAD',
functionParams: [NON_NULL_BYTES32],
expectedReturnStatus: true,
expectedReturnValues: [NULL_BYTES32]
expectedReturnValues: [NULL_BYTES32],
},
]
],
],
expectedReturnStatus: true,
expectedReturnValues: []
}
]
}
]
expectedReturnValues: [],
},
],
},
],
}
runExecutionManagerTest(test_ovmSLOAD)
......@@ -21,9 +21,9 @@ describe('OVM_SafetyChecker', () => {
for (const testName of Object.keys(SAFETY_CHECKER_TEST_JSON)) {
const test = SAFETY_CHECKER_TEST_JSON[testName]
it(`should correctly classify: ${testName}`, async () => {
expect(
await OVM_SafetyChecker.isBytecodeSafe(test.in)
).to.equal(test.out)
expect(await OVM_SafetyChecker.isBytecodeSafe(test.in)).to.equal(
test.out
)
})
}
})
......
......@@ -5,11 +5,7 @@ import { ethers } from '@nomiclabs/buidler'
import { Contract, ContractFactory } from 'ethers'
/* Internal Imports */
import {
DUMMY_ACCOUNTS,
DUMMY_BYTES32,
toOVMAccount
} from '../../../helpers'
import { DUMMY_ACCOUNTS, DUMMY_BYTES32, toOVMAccount } from '../../../helpers'
describe('OVM_StateManager', () => {
let Factory__OVM_StateManager: ContractFactory
......@@ -58,7 +54,9 @@ describe('OVM_StateManager', () => {
expect(
toOVMAccount(
await OVM_StateManager.callStatic.getAccount(DUMMY_ACCOUNTS[0].address)
await OVM_StateManager.callStatic.getAccount(
DUMMY_ACCOUNTS[0].address
)
)
).to.deep.equal(DUMMY_ACCOUNTS[0].data)
})
......@@ -76,7 +74,9 @@ describe('OVM_StateManager', () => {
expect(
toOVMAccount(
await OVM_StateManager.callStatic.getAccount(DUMMY_ACCOUNTS[0].address)
await OVM_StateManager.callStatic.getAccount(
DUMMY_ACCOUNTS[0].address
)
)
).to.deep.equal(DUMMY_ACCOUNTS[1].data)
})
......@@ -107,7 +107,7 @@ describe('OVM_StateManager', () => {
OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
).to.not.be.reverted
})
......@@ -116,14 +116,14 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
await expect(
OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[2],
DUMMY_BYTES32[2]
)
).to.not.be.reverted
})
......@@ -134,7 +134,7 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
expect(
......@@ -149,13 +149,13 @@ describe('OVM_StateManager', () => {
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[1],
DUMMY_BYTES32[1]
)
await OVM_StateManager.putContractStorage(
DUMMY_ACCOUNTS[0].address,
DUMMY_BYTES32[0],
DUMMY_BYTES32[2],
DUMMY_BYTES32[2]
)
expect(
......
......@@ -5,9 +5,7 @@ import { ethers } from '@nomiclabs/buidler'
import { Contract, ContractFactory, Signer } from 'ethers'
/* Internal Imports */
import {
getProxyManager, ZERO_ADDRESS, NULL_BYTES32
} from '../../../helpers'
import { getProxyManager, ZERO_ADDRESS, NULL_BYTES32 } from '../../../helpers'
const parseQueueElement = (result: any[]): any => {
return {
......@@ -57,13 +55,15 @@ describe('OVM_L1ToL2TransactionQueue', () => {
describe('enqueue()', () => {
it('should allow users to enqueue an element', async () => {
const [element] = makeQueueElements(1)
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be.reverted
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be
.reverted
})
it('should allow users to enqueue more than one element', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await expect(OVM_L1ToL2TransactionQueue.enqueue(elements[i])).to.not.be.reverted
for (const element of elements) {
await expect(OVM_L1ToL2TransactionQueue.enqueue(element)).to.not.be
.reverted
}
})
})
......@@ -78,10 +78,12 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert', async () => {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith('Sender is not allowed to enqueue.')
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith(
'Sender is not allowed to enqueue.'
)
})
})
describe('when the sender is the OVM_CanonicalTransactionChain', () => {
before(async () => {
await Proxy_Manager.setProxy(
......@@ -91,7 +93,9 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert if the queue is empty', async () => {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith('Queue is empty.')
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.be.revertedWith(
'Queue is empty.'
)
})
it('should allow users to dequeue an element', async () => {
......@@ -102,10 +106,10 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should allow users to dequeue more than one element', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
}
for (let i = 0; i < elements.length; i++) {
for (const element of elements) {
await expect(OVM_L1ToL2TransactionQueue.dequeue()).to.not.be.reverted
}
})
......@@ -136,8 +140,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should decrease when elements are dequeued', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
}
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.dequeue()
......@@ -156,7 +160,9 @@ describe('OVM_L1ToL2TransactionQueue', () => {
})
it('should revert when the queue is empty', async () => {
await expect(OVM_L1ToL2TransactionQueue.peek()).to.be.revertedWith('Queue is empty.')
await expect(OVM_L1ToL2TransactionQueue.peek()).to.be.revertedWith(
'Queue is empty.'
)
})
it('should return the front element if only one exists', async () => {
......@@ -168,8 +174,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should return the front if more than one exists', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(element)
const front = await OVM_L1ToL2TransactionQueue.peek()
expect(parseQueueElement(front)).to.deep.equal(elements[0])
}
......@@ -177,8 +183,8 @@ describe('OVM_L1ToL2TransactionQueue', () => {
it('should return the new front when elements are dequeued', async () => {
const elements = makeQueueElements(10)
for (let i = 0; i < elements.length; i++) {
await OVM_L1ToL2TransactionQueue.enqueue(elements[i])
for (const element of elements) {
await OVM_L1ToL2TransactionQueue.enqueue(elements)
}
for (let i = 0; i < elements.length - 1; i++) {
const front = await OVM_L1ToL2TransactionQueue.peek()
......
......@@ -5,19 +5,27 @@ import { ethers } from '@nomiclabs/buidler'
import { ContractFactory, Contract, Signer, BigNumber } from 'ethers'
/* Internal Imports */
import { getProxyManager, getMockContract, MockContract, ZERO_ADDRESS, NULL_BYTES32, NON_NULL_BYTES32, setProxyTarget} from '../../../helpers'
import {
getProxyManager,
getMockContract,
MockContract,
ZERO_ADDRESS,
NULL_BYTES32,
NON_NULL_BYTES32,
setProxyTarget,
} from '../../../helpers'
const DUMMY_BATCH_HEADER = {
batchIndex: 0,
batchRoot: NULL_BYTES32,
batchSize: 0,
prevTotalElements: 0,
extraData: NULL_BYTES32
extraData: NULL_BYTES32,
}
const DUMMY_BATCH_PROOF = {
index: 0,
siblings: [NULL_BYTES32]
siblings: [NULL_BYTES32],
}
const DUMMY_OVM_TRANSACTION = {
......@@ -27,7 +35,7 @@ const DUMMY_OVM_TRANSACTION = {
origin: ZERO_ADDRESS,
msgSender: ZERO_ADDRESS,
gasLimit: 0,
data: NULL_BYTES32
data: NULL_BYTES32,
}
describe('OVM_FraudVerifier', () => {
......@@ -44,7 +52,7 @@ describe('OVM_FraudVerifier', () => {
Mock__OVM_StateCommitmentChain = await getMockContract(
await ethers.getContractFactory('OVM_StateCommitmentChain')
)
Mock__OVM_CanonicalTransactionChain = await getMockContract(
await ethers.getContractFactory('OVM_CanonicalTransactionChain')
)
......@@ -82,18 +90,22 @@ describe('OVM_FraudVerifier', () => {
)
Mock__OVM_StateTransitionerFactory.setReturnValues('create', [
Mock__OVM_StateTransitioner.address
Mock__OVM_StateTransitioner.address,
])
})
let Factory__OVM_FraudVerifier: ContractFactory
before(async () => {
Factory__OVM_FraudVerifier = await ethers.getContractFactory('OVM_FraudVerifier')
Factory__OVM_FraudVerifier = await ethers.getContractFactory(
'OVM_FraudVerifier'
)
})
let OVM_FraudVerifier: Contract
beforeEach(async () => {
OVM_FraudVerifier = await Factory__OVM_FraudVerifier.deploy(Proxy_Manager.address)
OVM_FraudVerifier = await Factory__OVM_FraudVerifier.deploy(
Proxy_Manager.address
)
})
describe('initializeFraudVerification', () => {
......@@ -123,7 +135,9 @@ describe('OVM_FraudVerifier', () => {
describe('when provided an invalid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [false])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
false,
])
})
it('should revert', async () => {
......@@ -142,12 +156,14 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid transaction inclusion proof', () => {
before(() => {
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
})
it('should deploy a new state transitioner', async () => {
await expect(
OVM_FraudVerifier.initializeFraudVerification(
OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF,
......@@ -165,11 +181,12 @@ describe('OVM_FraudVerifier', () => {
})
})
describe('finalizeFraudVerification', () => {
beforeEach(async () => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [true])
Mock__OVM_CanonicalTransactionChain.setReturnValues('verifyElement', [
true,
])
await OVM_FraudVerifier.initializeFraudVerification(
NULL_BYTES32,
DUMMY_BATCH_HEADER,
......@@ -195,7 +212,9 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADER,
DUMMY_BATCH_PROOF
)
).to.be.revertedWith('State transition process must be completed prior to finalization.')
).to.be.revertedWith(
'State transition process must be completed prior to finalization.'
)
})
})
......@@ -207,7 +226,7 @@ describe('OVM_FraudVerifier', () => {
describe('when provided an invalid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 2
index: DUMMY_BATCH_PROOF.index + 2,
}
it('should revert', async () => {
......@@ -227,12 +246,14 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root index', () => {
const batchProof = {
...DUMMY_BATCH_PROOF,
index: DUMMY_BATCH_PROOF.index + 1
index: DUMMY_BATCH_PROOF.index + 1,
}
describe('when provided an invalid pre-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [false])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
false,
])
})
it('should revert', async () => {
......@@ -251,14 +272,19 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid pre-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
})
describe('when provided an invalid post-state root inclusion proof', () => {
beforeEach(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', (stateRoot: string, ...args: any) => {
return [stateRoot !== NON_NULL_BYTES32]
})
Mock__OVM_StateCommitmentChain.setReturnValues(
'verifyElement',
(stateRoot: string, ...args: any) => {
return [stateRoot !== NON_NULL_BYTES32]
}
)
})
it('should revert', async () => {
......@@ -277,12 +303,17 @@ describe('OVM_FraudVerifier', () => {
describe('when provided a valid post-state root inclusion proof', () => {
before(() => {
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [true])
Mock__OVM_StateCommitmentChain.setReturnValues('verifyElement', [
true,
])
})
describe('when the provided post-state root does not differ from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('getPostStateRoot', [NON_NULL_BYTES32])
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NON_NULL_BYTES32]
)
})
it('should revert', async () => {
......@@ -295,13 +326,18 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADER,
batchProof
)
).to.be.revertedWith('State transition has not been proven fraudulent.')
).to.be.revertedWith(
'State transition has not been proven fraudulent.'
)
})
})
describe('when the provided post-state root differs from the computed one', () => {
before(() => {
Mock__OVM_StateTransitioner.setReturnValues('getPostStateRoot', [NULL_BYTES32])
Mock__OVM_StateTransitioner.setReturnValues(
'getPostStateRoot',
[NULL_BYTES32]
)
})
it('should succeed and attempt to delete a state batch', async () => {
......@@ -313,12 +349,19 @@ describe('OVM_FraudVerifier', () => {
DUMMY_BATCH_HEADER,
batchProof
)
expect(
Mock__OVM_StateCommitmentChain.getCallData('deleteStateBatch', 0)
).to.deep.equal([Object.values(DUMMY_BATCH_HEADER).map((value) => {
return Number.isInteger(value) ? BigNumber.from(value) : value
})])
Mock__OVM_StateCommitmentChain.getCallData(
'deleteStateBatch',
0
)
).to.deep.equal([
Object.values(DUMMY_BATCH_HEADER).map((value) => {
return Number.isInteger(value)
? BigNumber.from(value)
: value
}),
])
})
})
})
......
/* tslint:disable:no-empty */
import { expect } from '../../../setup'
describe('OVM_StateTransitioner', () => {
describe('proveContractState', () => {
describe('when provided an invalid code hash', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid code hash', () => {
describe('when provided an invalid account inclusion proof', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid account inclusion proof', () => {
})
describe('when provided a valid account inclusion proof', () => {})
})
})
describe('proveStorageSlot', () => {
describe('when the corresponding account is not proven', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the corresponding account is proven', () => {
describe('when provided an invalid slot inclusion proof', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when provided a valid slot inclusion proof', () => {
})
describe('when provided a valid slot inclusion proof', () => {})
})
})
......@@ -47,63 +36,45 @@ describe('OVM_StateTransitioner', () => {
describe('commitContractState', () => {
describe('when the account was not changed', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the account was changed', () => {
describe('when the account has not been committed', () => {
it('should commit the account and update the state', async () => {
})
it('should commit the account and update the state', async () => {})
})
describe('when the account was already committed', () => {
it('should revert', () => {
})
it('should revert', () => {})
})
})
})
describe('commitStorageSlot', () => {
describe('when the slot was not changed', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when the slot was changed', () => {
describe('when the slot has not been committed', () => {
it('should commit the slot and update the state', async () => {
})
it('should commit the slot and update the state', async () => {})
})
describe('when the slot was already committed', () => {
it('should revert', () => {
})
it('should revert', () => {})
})
})
})
describe('completeTransition', () => {
describe('when there are uncommitted accounts', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when there are uncommitted storage slots', () => {
it('should revert', async () => {
})
it('should revert', async () => {})
})
describe('when all state changes are committed', () => {
})
describe('when all state changes are committed', () => {})
})
})
......@@ -2,19 +2,22 @@
import fsExtra from 'fs-extra'
import { internalTask } from '@nomiclabs/buidler/config'
import { pluralize } from '@nomiclabs/buidler/internal/util/strings'
import { getArtifactFromContractOutput, saveArtifact } from '@nomiclabs/buidler/internal/artifacts'
import {
getArtifactFromContractOutput,
saveArtifact,
} from '@nomiclabs/buidler/internal/artifacts'
import {
TASK_COMPILE_GET_COMPILER_INPUT,
TASK_BUILD_ARTIFACTS,
TASK_COMPILE_GET_SOURCE_PATHS,
TASK_COMPILE_CHECK_CACHE,
TASK_COMPILE_COMPILE
TASK_COMPILE_COMPILE,
} from '@nomiclabs/buidler/builtin-tasks/task-names'
internalTask(
TASK_COMPILE_GET_COMPILER_INPUT,
async (_, { config, run }, runSuper) => {
const input = await runSuper();
const input = await runSuper()
// Insert the "storageLayout" input option.
input.settings.outputSelection['*']['*'].push('storageLayout')
......@@ -25,51 +28,51 @@ internalTask(
internalTask(TASK_BUILD_ARTIFACTS).setAction(
async ({ force }, { config, run }) => {
const sources = await run(TASK_COMPILE_GET_SOURCE_PATHS);
const sources = await run(TASK_COMPILE_GET_SOURCE_PATHS)
if (sources.length === 0) {
console.log("No Solidity source file available.");
return;
console.log('No Solidity source file available.')
return
}
const isCached: boolean = await run(TASK_COMPILE_CHECK_CACHE, { force });
const isCached: boolean = await run(TASK_COMPILE_CHECK_CACHE, { force })
if (isCached) {
console.log(
"All contracts have already been compiled, skipping compilation."
);
return;
'All contracts have already been compiled, skipping compilation.'
)
return
}
const compilationOutput = await run(TASK_COMPILE_COMPILE);
const compilationOutput = await run(TASK_COMPILE_COMPILE)
if (compilationOutput === undefined) {
return;
return
}
await fsExtra.ensureDir(config.paths.artifacts);
let numberOfContracts = 0;
await fsExtra.ensureDir(config.paths.artifacts)
let numberOfContracts = 0
for (const file of Object.values<any>(compilationOutput.contracts)) {
for (const [contractName, contractOutput] of Object.entries(file)) {
const artifact: any = getArtifactFromContractOutput(
contractName,
contractOutput
);
numberOfContracts += 1;
)
numberOfContracts += 1
// Only difference here, set the "storageLayout" field of the artifact.
artifact.storageLayout = (contractOutput as any).storageLayout
await saveArtifact(config.paths.artifacts, artifact);
await saveArtifact(config.paths.artifacts, artifact)
}
}
console.log(
"Compiled",
'Compiled',
numberOfContracts,
pluralize(numberOfContracts, "contract"),
"successfully"
);
pluralize(numberOfContracts, 'contract'),
'successfully'
)
}
)
......@@ -8,24 +8,31 @@ export const encodeRevertData = (
ovmGasRefund: number = 0
): string => {
const abiEncoded: string = ethers.utils.defaultAbiCoder.encode(
['uint256','uint256','uint256','bytes'],
['uint256', 'uint256', 'uint256', 'bytes'],
[flag, nuisanceGasLeft, ovmGasRefund, data]
)
return abiEncoded
}
export const decodeRevertData = (
revertData: string
): any => {
export const decodeRevertData = (revertData: string): any => {
// const length: number = revertData.length/2 - 1
// const reencodedRevertData = '0x' + hexZeroPad('0x' + length.toString(16), 32) + revertData.slice(2)
const decoded = ethers.utils.defaultAbiCoder.decode(
['uint256','uint256','uint256','bytes'],
['uint256', 'uint256', 'uint256', 'bytes'],
revertData
)
console.log(`flag is: ${decoded[0].toNumber()}`)
return '[revertFlag:' + Object.keys(REVERT_FLAGS)[decoded[0]] + ', nuisanceGasLeft:' + decoded[1] + ', ovmGasRefund: ' + decoded[2] + ', data: ' + decoded[3] + ']'
return (
'[revertFlag:' +
Object.keys(REVERT_FLAGS)[decoded[0]] +
', nuisanceGasLeft:' +
decoded[1] +
', ovmGasRefund: ' +
decoded[2] +
', data: ' +
decoded[3] +
']'
)
}
export const REVERT_FLAGS = {
......@@ -37,5 +44,5 @@ export const REVERT_FLAGS = {
UNSAFE_BYTECODE: 5,
CREATE_COLLISION: 6,
STATIC_VIOLATION: 7,
CREATE_EXCEPTION: 8
CREATE_EXCEPTION: 8,
}
......@@ -4,4 +4,4 @@ import { safetyCheckerTests } from './json/safety-checker.test.json'
export const RLP_TEST_JSON = rlpTests
export const CREATE2_TEST_JSON = create2Tests
export const SAFETY_CHECKER_TEST_JSON = safetyCheckerTests
\ No newline at end of file
export const SAFETY_CHECKER_TEST_JSON = safetyCheckerTests
......@@ -5,7 +5,7 @@ import { makeAddress } from '../byte-utils'
import { OVMAccount } from '../types/ovm-types'
export const DUMMY_ACCOUNTS: Array<{
address: string,
address: string
data: OVMAccount
}> = [
{
......@@ -27,5 +27,5 @@ export const DUMMY_ACCOUNTS: Array<{
codeHash: DUMMY_BYTES32[3],
ethAddress: NON_ZERO_ADDRESS,
},
}
},
]
......@@ -3,7 +3,7 @@ import { NON_ZERO_ADDRESS } from '../constants'
export const DUMMY_CONTEXT = {
GLOBAL: {
ovmCHAINID: 11
ovmCHAINID: 11,
},
TRANSACTION: {
ovmORIGIN: NON_ZERO_ADDRESS,
......@@ -15,6 +15,6 @@ export const DUMMY_CONTEXT = {
MESSAGE: {
ovmCALLER: NON_ZERO_ADDRESS,
ovmADDRESS: NON_ZERO_ADDRESS,
ovmSTATICCTX: true
}
ovmSTATICCTX: true,
},
}
......@@ -24,7 +24,7 @@ export const bindMockWatcherToVM = (): void => {
// Set up some things we'll need for later.
let txid: string
let messages: Array<{
const messages: Array<{
address: string
sighash: string
calldata: string
......@@ -34,7 +34,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the vm.runTx function to capture an ID for each transaction.
const originalRunTx = vm.runTx.bind(vm)
const modifiedRunTx = async (opts: any): Promise<any> => {
function modifiedRunTx(opts: any): Promise<any> {
// Buidler runs transactions multiple times (e.g., for gas estimation).
// Here we're computing a unique ID for each transaction (based on sender,
// nonce, and transaction data) so that we don't log calls multiple times.
......@@ -54,7 +54,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the pre-message handler to capture calldata.
const originalBeforeMessageHandler = vmTracer['_beforeMessageHandler' as any]
const modifiedBeforeMessageHandler = async (message: any, next: any) => {
function modifiedBeforeMessageHandler(message: any, next: any) {
// We only care about capturing if we're sending to one of our mocks.
const address = message.to
? toHexString(message.to).toLowerCase()
......@@ -93,7 +93,7 @@ export const bindMockWatcherToVM = (): void => {
// Modify the post-message handler to insert the correct return data.
const originalAfterMessageHandler = vmTracer['_afterMessageHandler' as any]
const modifiedAfterMessageHandler = async (result: any, next: any) => {
function modifiedAfterMessageHandler(result: any, next: any) {
// We don't need to do anything if we haven't stored any mock messages.
if (messages.length > 0) {
// We need to look at the messages backwards since the first result will
......@@ -106,13 +106,11 @@ export const bindMockWatcherToVM = (): void => {
// Compute our return values.
const inputParams = contract.__spec
? contract.__spec.interface.decodeFunctionData(
fn.functionName,
contract.__spec.interface.getSighash(fn.functionName) + message.calldata.slice(2)
)
: ethers.utils.defaultAbiCoder.decode(
fn.inputTypes,
message.calldata
)
fn.functionName,
contract.__spec.interface.getSighash(fn.functionName) +
message.calldata.slice(2)
)
: ethers.utils.defaultAbiCoder.decode(fn.inputTypes, message.calldata)
const returnValues = Array.isArray(fn.returnValues)
? fn.returnValues
......@@ -120,9 +118,9 @@ export const bindMockWatcherToVM = (): void => {
const returnBuffer = fromHexString(
contract.__spec
? contract.__spec.interface.encodeFunctionResult(
fn.functionName,
returnValues
)
fn.functionName,
returnValues
)
: ethers.utils.defaultAbiCoder.encode(fn.outputTypes, returnValues)
)
......@@ -175,18 +173,20 @@ export const bindMockContractToVM = (
}
}
const sighash = mock.interface.getSighash(functionName)
return calls[sighash] || []
const sig = mock.interface.getSighash(functionName)
return calls[sig] || []
}
if (!Array.isArray(spec)) {
;(mock as any).__spec = spec
;(mock as any).__sigmap = Object.keys(mock.interface.functions).reduce((sigmap, fn) => {
fn = fn.split('(')[0]
sigmap[spec.interface.getSighash(fn)] = mock.interface.getSighash(fn)
return sigmap
}, {})
;(mock as any).__sigmap = Object.keys(mock.interface.functions).reduce(
(sigmap, fn) => {
fn = fn.split('(')[0]
sigmap[spec.interface.getSighash(fn)] = mock.interface.getSighash(fn)
return sigmap
},
{}
)
}
;(mock as any).getCallCount = (functionName: string): number => {
......@@ -204,11 +204,9 @@ export const bindMockContractToVM = (
const iface = mock.__spec ? mock.__spec.interface : mock.interface
const calldata = iface.getSighash(functionName) + calls[callIndex].slice(10)
return iface
.decodeFunctionData(functionName, calldata)
.map((element) => {
return element
})
return iface.decodeFunctionData(functionName, calldata).map((element) => {
return element
})
}
;(mock as any).setReturnValues = (
functionName: string,
......
......@@ -6,11 +6,7 @@ import { FunctionFragment, ParamType } from 'ethers/lib/utils'
/* Internal Imports */
import { MockContract, MockContractFunction } from './mock-contract.types'
import { bindMockContractToVM, bindMockWatcherToVM } from './mock-binding'
import {
SolidityCompiler,
getDefaultCompiler,
compile,
} from '../compilation'
import { SolidityCompiler, getDefaultCompiler, compile } from '../compilation'
/**
* Generates contract code for a mock contract.
......@@ -210,12 +206,12 @@ export const getMockContract = async (
originalDefinePropertyFn(object, name, props)
}
const MockContract = (await MockContractFactory.deploy()) as MockContract
const mock = (await MockContractFactory.deploy()) as MockContract
Object.defineProperty = originalDefinePropertyFn
bindMockWatcherToVM()
bindMockContractToVM(MockContract, fns, spec)
bindMockContractToVM(mock, fns, spec)
return MockContract
return mock
}
......@@ -19,10 +19,7 @@ export const makeProxies = async (
Proxy_Manager.address
)
await Proxy_Manager.setProxy(
name,
Proxy_Forwarder.address
)
await Proxy_Manager.setProxy(name, Proxy_Forwarder.address)
}
}
......@@ -32,15 +29,10 @@ export const setProxyTarget = async (
target: Contract
): Promise<void> => {
await makeProxies(Proxy_Manager, [name])
await Proxy_Manager.setTarget(
name,
target.address
)
await Proxy_Manager.setTarget(name, target.address)
}
export const getProxyManager = async (): Promise<Contract> => {
return (await ethers.getContractFactory(
'Proxy_Manager'
)).deploy()
return (await ethers.getContractFactory('Proxy_Manager')).deploy()
}
import bre, { ethers } from '@nomiclabs/buidler'
import { Contract, BigNumber, ContractFactory } from "ethers";
import { keccak256, defaultAbiCoder } from "ethers/lib/utils";
import { Contract, BigNumber, ContractFactory } from 'ethers'
import { keccak256, defaultAbiCoder } from 'ethers/lib/utils'
import { remove0x } from '../byte-utils'
import { readArtifact } from '@nomiclabs/buidler/internal/artifacts';
import { readArtifact } from '@nomiclabs/buidler/internal/artifacts'
const getFlattenedKeys = (
depth: number,
value: any,
): string[] => {
const getFlattenedKeys = (depth: number, value: any): string[] => {
if (depth === 0) {
return []
}
let keys = Object.keys(value)
if (depth > 1) {
keys = keys.concat(
getFlattenedKeys(
depth - 1,
Object.values(value)[0]
)
)
keys = keys.concat(getFlattenedKeys(depth - 1, Object.values(value)[0]))
}
return keys
......@@ -38,29 +30,25 @@ const toHexString32 = (
}
}
const getFlattenedValues = (
depth: number,
value: any
): any[] => {
const getFlattenedValues = (depth: number, value: any): any[] => {
if (depth > 0) {
return getFlattenedValues(
depth - 1,
Object.values(value)[0]
)
return getFlattenedValues(depth - 1, Object.values(value)[0])
}
if (typeof value === 'object' && value !== null) {
return Object.keys(value).map((key) => {
return {
label: key,
value: toHexString32(value[key])
value: toHexString32(value[key]),
}
})
} else {
return [{
label: "default",
value: toHexString32(value)
}]
return [
{
label: 'default',
value: toHexString32(value),
},
]
}
}
......@@ -68,33 +56,24 @@ const getStorageSlotHash = (
slot: number,
depth: number,
value: any
): string =>{
): string => {
let keys = []
if (typeof value === 'object' && value !== null) {
keys = getFlattenedKeys(depth, value)
}
if (keys.length === 0) {
return defaultAbiCoder.encode(
['uint256'],
[slot]
)
return defaultAbiCoder.encode(['uint256'], [slot])
} else {
let slotHash = toHexString32(slot)
for (const key of keys) {
slotHash = keccak256(
toHexString32(key) +
remove0x(slotHash)
)
slotHash = keccak256(toHexString32(key) + remove0x(slotHash))
}
return slotHash
}
}
const parseInputSlots = (
layout: any,
inputTypeName: string
): any[] => {
const parseInputSlots = (layout: any, inputTypeName: string): any[] => {
const inputType = layout.types[inputTypeName]
if (inputType.encoding === 'mapping') {
......@@ -104,14 +83,16 @@ const parseInputSlots = (
return inputType.members.map((member: any) => {
return {
label: member.label,
slot: member.slot
slot: member.slot,
}
})
} else {
return [{
label: "default",
slot: 0
}]
return [
{
label: 'default',
slot: 0,
},
]
}
} else {
throw new Error('Encoding type not supported.')
......@@ -122,17 +103,23 @@ export const getModifiableStorageFactory = async (
name: string
): Promise<ContractFactory> => {
const contractFactory = await ethers.getContractFactory(name)
const proxyFactory = await ethers.getContractFactory('Helper_ModifiableStorage')
const proxyFactory = await ethers.getContractFactory(
'Helper_ModifiableStorage'
)
const originalDeploy = contractFactory.deploy.bind(contractFactory)
contractFactory.deploy = async (...args: any[]): Promise<Contract> => {
const originalDefinePropertyFn = Object.defineProperty
Object.defineProperty = (object: any, name: string, props: any): void => {
Object.defineProperty = (
object: any,
propName: string,
props: any
): void => {
if (props.writable === false) {
props.writable = true
}
originalDefinePropertyFn(object, name, props)
originalDefinePropertyFn(object, propName, props)
}
const contract = await originalDeploy(...args)
......@@ -144,14 +131,16 @@ export const getModifiableStorageFactory = async (
;(contract as any).__setContractStorage = async (value: any) => {
await setContractStorage(
contract,
(await readArtifact(bre.config.paths.artifacts, name) as any).storageLayout,
((await readArtifact(bre.config.paths.artifacts, name)) as any)
.storageLayout,
value
)
}
;(contract as any).__checkContractStorage = async (value: any) => {
await checkContractStorage(
contract,
(await readArtifact(bre.config.paths.artifacts, name) as any).storageLayout,
((await readArtifact(bre.config.paths.artifacts, name)) as any)
.storageLayout,
value
)
}
......@@ -171,40 +160,35 @@ export const setContractStorage = async (
storage = storage || {}
for (const [key, value] of Object.entries(storage)) {
const layoutMap = layout.storage.find((layoutMap: any) => {
return layoutMap.label === key
const layoutMap = layout.storage.find((lmap: any) => {
return lmap.label === key
})
const inputSlots = parseInputSlots(layout, layoutMap.type)
const slot = parseInt(layoutMap.slot)
const slot = parseInt(layoutMap.slot, 10)
const depth = (layoutMap.type.match(/t_mapping/g) || []).length
if (typeof value !== 'object') {
const slotHash = getStorageSlotHash(slot, depth, value)
await contract.__setStorageSlot(
slotHash,
toHexString32(value as string)
)
await contract.__setStorageSlot(slotHash, toHexString32(value as string))
} else {
for (const [subKey, subValue] of Object.entries(value)) {
const baseSlotHash = getStorageSlotHash(slot, depth, {
[subKey]: subValue
[subKey]: subValue,
})
const slotValues = getFlattenedValues(depth, {
[subKey]: subValue
[subKey]: subValue,
})
for (let i = 0; i < slotValues.length; i++) {
const slotValue = slotValues[i]
for (const slotValue of slotValues) {
const slotIndex = inputSlots.find((inputSlot) => {
return inputSlot.label === slotValue.label
}).slot
const slotHash = toHexString32(BigNumber.from(baseSlotHash).add(slotIndex))
await contract.__setStorageSlot(
slotHash,
slotValue.value
const slotHash = toHexString32(
BigNumber.from(baseSlotHash).add(slotIndex)
)
await contract.__setStorageSlot(slotHash, slotValue.value)
}
}
}
......@@ -219,45 +203,48 @@ export const checkContractStorage = async (
storage = storage || {}
for (const [key, value] of Object.entries(storage)) {
const layoutMap = layout.storage.find((layoutMap: any) => {
return layoutMap.label === key
const layoutMap = layout.storage.find((lmap: any) => {
return lmap.label === key
})
const inputSlots = parseInputSlots(layout, layoutMap.type)
const slot = parseInt(layoutMap.slot)
const slot = parseInt(layoutMap.slot, 10)
const depth = (layoutMap.type.match(/t_mapping/g) || []).length
if (typeof value !== 'object') {
const slotHash = getStorageSlotHash(slot, depth, value)
const retSlotValue = await contract.__getStorageSlot(
slotHash
)
const retSlotValue = await contract.__getStorageSlot(slotHash)
if (retSlotValue !== toHexString32(value as string)) {
throw new Error(`Resulting state of ${key} (${retSlotValue}) did not match expected state (${toHexString32(value as string)})`)
throw new Error(
`Resulting state of ${key} (${retSlotValue}) did not match expected state (${toHexString32(
value as string
)})`
)
}
} else {
for (const [subKey, subValue] of Object.entries(value)) {
const baseSlotHash = getStorageSlotHash(slot, depth, {
[subKey]: subValue
[subKey]: subValue,
})
const slotValues = getFlattenedValues(depth, {
[subKey]: subValue
[subKey]: subValue,
})
for (let i = 0; i < slotValues.length; i++) {
const slotValue = slotValues[i]
for (const slotValue of slotValues) {
const slotIndex = inputSlots.find((inputSlot) => {
return inputSlot.label === slotValue.label
}).slot
const slotHash = toHexString32(BigNumber.from(baseSlotHash).add(slotIndex))
const retSlotValue = await contract.__getStorageSlot(
slotHash
const slotHash = toHexString32(
BigNumber.from(baseSlotHash).add(slotIndex)
)
const retSlotValue = await contract.__getStorageSlot(slotHash)
if (retSlotValue !== slotValue.value) {
throw new Error(`Resulting state of ${slotValue.label} (${retSlotValue}) did not match expected state (${slotValue.value}).`)
throw new Error(
`Resulting state of ${slotValue.label} (${retSlotValue}) did not match expected state (${slotValue.value}).`
)
}
}
}
......
......@@ -22,11 +22,9 @@ const setPlaceholderStrings = (
ovmStateManager: Contract,
ovmSafetyChecker: Contract,
ovmCallHelper: Contract,
ovmRevertHelper: Contract,
ovmRevertHelper: Contract
): any => {
const setPlaceholder = (
kv: string
): string => {
const setPlaceholder = (kv: string): string => {
if (kv === '$OVM_EXECUTION_MANAGER') {
return ovmExecutionManager.address
} else if (kv === '$OVM_STATE_MANAGER') {
......@@ -82,13 +80,13 @@ const setPlaceholderStrings = (
return test
}
const fixtureDeployContracts = async (): Promise <{
OVM_SafetyChecker: Contract,
OVM_StateManager: Contract,
OVM_ExecutionManager: Contract,
OVM_CallHelper: Contract,
OVM_RevertHelper: Contract,
OVM_CreateStorer: Contract,
const fixtureDeployContracts = async (): Promise<{
OVM_SafetyChecker: Contract
OVM_StateManager: Contract
OVM_ExecutionManager: Contract
OVM_CallHelper: Contract
OVM_RevertHelper: Contract
OVM_CreateStorer: Contract
OVM_InvalidHelper: Contract
}> => {
const Factory__OVM_SafetyChecker = await ethers.getContractFactory(
......@@ -115,8 +113,12 @@ const fixtureDeployContracts = async (): Promise <{
)
const OVM_SafetyChecker = await Factory__OVM_SafetyChecker.deploy()
const OVM_ExecutionManager = await Factory__OVM_ExecutionManager.deploy(OVM_SafetyChecker.address)
const OVM_StateManager = await Factory__OVM_StateManager.deploy(OVM_ExecutionManager.address)
const OVM_ExecutionManager = await Factory__OVM_ExecutionManager.deploy(
OVM_SafetyChecker.address
)
const OVM_StateManager = await Factory__OVM_StateManager.deploy(
OVM_ExecutionManager.address
)
const OVM_CallHelper = await Factory__Helper_CodeContractForCalls.deploy()
const OVM_RevertHelper = await Factory__Helper_CodeContractForReverts.deploy()
const OVM_CreateStorer = await Factory__Helper_CreateEMResponsesStorer.deploy()
......@@ -129,32 +131,28 @@ const fixtureDeployContracts = async (): Promise <{
OVM_CallHelper,
OVM_RevertHelper,
OVM_CreateStorer,
OVM_InvalidHelper
OVM_InvalidHelper,
}
}
export const runExecutionManagerTest = (
test: TestDefinition
): void => {
export const runExecutionManagerTest = (test: TestDefinition): void => {
test.preState = test.preState || {}
test.postState = test.postState || {}
describe(`Standard test: ${test.name}`, () => {
test.parameters.map((parameters) => {
if (isTestDefinition(parameters)) {
runExecutionManagerTest(
{
...parameters,
preState: {
...test.preState,
...parameters.preState
},
postState: {
...test.postState,
...parameters.postState
}
}
)
runExecutionManagerTest({
...parameters,
preState: {
...test.preState,
...parameters.preState,
},
postState: {
...test.postState,
...parameters.postState,
},
})
} else {
let OVM_SafetyChecker: Contract
let OVM_StateManager: Contract
......@@ -196,28 +194,33 @@ export const runExecutionManagerTest = (
})
beforeEach(async () => {
await OVM_ExecutionManager.__setContractStorage(replacedTest.preState.ExecutionManager)
await OVM_StateManager.__setContractStorage(replacedTest.preState.StateManager)
await OVM_ExecutionManager.__setContractStorage(
replacedTest.preState.ExecutionManager
)
await OVM_StateManager.__setContractStorage(
replacedTest.preState.StateManager
)
})
afterEach(async () => {
await OVM_ExecutionManager.__checkContractStorage({
...replacedTest.postState.ExecutionManager
...replacedTest.postState.ExecutionManager,
})
await OVM_StateManager.__checkContractStorage({
...replacedTest.postState.StateManager
...replacedTest.postState.StateManager,
})
})
parameters.steps.map((step, idx) => {
const scopedFunction = (!!test.focus) ? it.only : it
const scopedFunction = !!test.focus ? it.only : it
scopedFunction(`should run test: ${test.name} ${idx}`, async () => {
const testGenerator = getTestGenerator(
replacedParams.steps[idx],
OVM_ExecutionManager,
OVM_CallHelper,
OVM_CreateStorer,
(await ethers.getContractFactory('Helper_CodeContractForCreates')).interface,
(await ethers.getContractFactory('Helper_CodeContractForCreates'))
.interface,
OVM_RevertHelper,
OVM_InvalidHelper
)
......@@ -225,21 +228,28 @@ export const runExecutionManagerTest = (
const callResult = await OVM_ExecutionManager.provider.call({
to: OVM_ExecutionManager.address,
data: testGenerator.getCalldata(),
gasLimit: GAS_LIMIT
gasLimit: GAS_LIMIT,
})
await OVM_ExecutionManager.signer.sendTransaction({
to: OVM_ExecutionManager.address,
data: testGenerator.getCalldata(),
gasLimit: GAS_LIMIT
gasLimit: GAS_LIMIT,
})
const interpretation = testGenerator.interpretActualReturnData(callResult, true)
const interpretation = testGenerator.interpretActualReturnData(
callResult,
true
)
console.log('interpretation of actual results:\n' + interpretation) // in future we can add conditional here but for now always assume succeed
const interpretationOfExpected = testGenerator.interpretActualReturnData(testGenerator.getReturnData(), true)
console.log('interpretation of expected: \n' + interpretationOfExpected)
const interpretationOfExpected = testGenerator.interpretActualReturnData(
testGenerator.getReturnData(),
true
)
console.log(
'interpretation of expected: \n' + interpretationOfExpected
)
expect(callResult).to.equal(testGenerator.getReturnData()) //, 'got bad response, looks like it did:\n' + testGenerator.interpretActualReturnData(callResult))
})
......
......@@ -5,7 +5,12 @@ export type SolidityFunctionParameter = string | number | BigNumber
export interface TestStep {
functionName: string
functionParams: Array<SolidityFunctionParameter | SolidityFunctionParameter[] | TestStep[] | boolean>
functionParams: Array<
| SolidityFunctionParameter
| SolidityFunctionParameter[]
| TestStep[]
| boolean
>
expectedReturnStatus: boolean
expectedReturnValues: any[]
}
......@@ -18,14 +23,14 @@ export interface TestDefinition {
name: string
focus?: boolean
preState?: {
ExecutionManager?: any,
ExecutionManager?: any
StateManager?: any
},
parameters: Array<TestParameters | TestDefinition>,
}
parameters: Array<TestParameters | TestDefinition>
postState?: {
ExecutionManager?: any,
ExecutionManager?: any
StateManager?: any
},
}
}
export const isTestDefinition = (
......
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"declaration": true,
"noImplicitAny": false,
"removeComments": true,
"noLib": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"outDir": "./build",
"baseUrl": "./",
"resolveJsonModule": true,
"esModuleInterop": true
"esModuleInterop": true,
"lib": [
"es7"
],
"typeRoots": [
"node_modules/@types"
]
},
"include": ["*.ts", "**/*.ts", "artifacts/*.json"],
"exclude": ["./build", "node_modules"],
......
{
"extends": [
"tslint:latest",
"tslint-config-prettier",
"tslint-plugin-prettier"
],
"rulesDirectory": [
"tslint-no-focused-test"
],
"rules": {
"ban-types": false,
"comment-format": false,
"interface-name": false,
"max-classes-per-file": false,
"member-ordering": false,
"no-bitwise": false,
"no-empty-interface": false,
"no-implicit-dependencies": [true, "dev"],
"no-string-literal": false,
"no-submodule-imports": false,
"no-unused-expression": false,
"object-literal-sort-keys": false,
"ordered-imports": false,
"prettier": [true, "prettier-config.json"],
"semicolon": false,
"variable-name": false,
"no-focused-test": true,
"no-console": false,
"array-type": false,
"class-name": false
},
"linterOptions": {
"exclude": [
"**/node_modules/**/*"
]
}
}
This diff is collapsed.
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