forked from cgewecke/eth-gas-reporter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
142 lines (116 loc) · 3.63 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const mocha = require('mocha')
const inherits = require('util').inherits
const stats = require('./gasStats.js')
const Base = mocha.reporters.Base
const color = Base.color
const log = console.log
module.exports = Gas
// Based on the 'Spec' reporter
function Gas (runner) {
Base.call(this, runner)
const self = this
let indents = 0
let n = 0
let startBlock
let deployStartBlock
let methodMap
let deployMap
// ------------------------------------ Helpers -------------------------------------------------
const indent = () => Array(indents).join(' ')
const methodAnalytics = (methodMap) => {
let gasUsed = 0
const endBlock = web3.eth.blockNumber
while (startBlock <= endBlock) {
let block = web3.eth.getBlock(startBlock)
if (block) {
// Add to running tally for this test
gasUsed += block.gasUsed
// Compile per method stats
methodMap && block.transactions.forEach(tx => {
const transaction = web3.eth.getTransaction(tx)
const receipt = web3.eth.getTransactionReceipt(tx)
const id = stats.getMethodID(transaction.input)
const threw = receipt.gasUsed === transaction.gas // Change this @ Byzantium
if (methodMap[id] && !threw) {
methodMap[id].gasData.push(receipt.gasUsed)
methodMap[id].numberOfCalls++
}
})
}
startBlock++
}
return gasUsed
}
const deployAnalytics = (deployMap) => {
const endBlock = web3.eth.blockNumber
while (deployStartBlock <= endBlock) {
const block = web3.eth.getBlock(deployStartBlock)
block && block.transactions.forEach(tx => {
const transaction = web3.eth.getTransaction(tx)
const receipt = web3.eth.getTransactionReceipt(tx)
const threw = receipt.gasUsed === transaction.gas // Change this @ Byzantium
if (receipt.contractAddress && !threw) {
const match = deployMap.filter(contract => {
return (transaction.input.indexOf(contract.binary) === 0)
})[0]
match && match.gasData.push(receipt.gasUsed)
}
})
deployStartBlock++
}
}
// ------------------------------------ Runners -------------------------------------------------
runner.on('start', () => {
({ methodMap, deployMap } = stats.mapMethodsToContracts(artifacts))
log()
})
runner.on('suite', suite => {
++indents
log(color('suite', '%s%s'), indent(), suite.title)
})
runner.on('suite end', () => {
--indents
if (indents === 1) {
log()
}
})
runner.on('pending', test => {
let fmt = indent() + color('pending', ' - %s')
log(fmt, test.title)
})
runner.on('test', () => { deployStartBlock = web3.eth.blockNumber })
runner.on('hook end', () => { startBlock = web3.eth.blockNumber + 1 })
runner.on('pass', test => {
let fmt
let gasUsedString
deployAnalytics(deployMap)
let gasUsed = methodAnalytics(methodMap)
if (gasUsed) {
gasUsedString = color('checkmark', ' (%d gas)')
fmt = indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s') +
gasUsedString
log(fmt, test.title, gasUsed)
} else {
fmt = indent() +
color('checkmark', ' ' + Base.symbols.ok) +
color('pass', ' %s')
log(fmt, test.title)
}
})
runner.on('fail', test => {
let fmt = indent() + color('fail', ' %d) %s')
log()
log(fmt, ++n, test.title)
})
runner.on('end', () => {
stats
.generateGasStatsReport(methodMap, deployMap)
.then(() => self.epilogue());
})
}
/**
* Inherit from `Base.prototype`.
*/
inherits(Gas, Base)