Skip to content

Commit 261b3e2

Browse files
authored
Merge pull request #14336 from obscuren/metropolis-preparation
consensus, core/*, params: metropolis preparation refactor
2 parents 344f25f + 11cf5b7 commit 261b3e2

35 files changed

+2983
-236
lines changed

build/update-license.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,14 @@ var (
4747
// boring stuff
4848
"vendor/", "tests/files/", "build/",
4949
// don't relicense vendored sources
50-
"crypto/sha3/", "crypto/ecies/", "log/",
51-
"crypto/secp256k1/curve.go",
50+
"cmd/internal/browser",
5251
"consensus/ethash/xor.go",
52+
"crypto/bn256/",
53+
"crypto/ecies/",
54+
"crypto/secp256k1/curve.go",
55+
"crypto/sha3/",
5356
"internal/jsre/deps",
54-
"cmd/internal/browser",
57+
"log/",
5558
// don't license generated files
5659
"contracts/chequebook/contract/",
5760
"contracts/ens/contract/",

cmd/evm/main.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ var (
3535
Name: "debug",
3636
Usage: "output full trace logs",
3737
}
38+
MemProfileFlag = cli.StringFlag{
39+
Name: "memprofile",
40+
Usage: "creates a memory profile at the given path",
41+
}
42+
CPUProfileFlag = cli.StringFlag{
43+
Name: "cpuprofile",
44+
Usage: "creates a CPU profile at the given path",
45+
}
46+
StatDumpFlag = cli.BoolFlag{
47+
Name: "statdump",
48+
Usage: "displays stack and heap memory information",
49+
}
3850
CodeFlag = cli.StringFlag{
3951
Name: "code",
4052
Usage: "EVM code",
@@ -93,6 +105,9 @@ func init() {
93105
DumpFlag,
94106
InputFlag,
95107
DisableGasMeteringFlag,
108+
MemProfileFlag,
109+
CPUProfileFlag,
110+
StatDumpFlag,
96111
}
97112
app.Commands = []cli.Command{
98113
compileCommand,

cmd/evm/runner.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"io/ioutil"
2323
"os"
24+
"runtime/pprof"
2425
"time"
2526

2627
goruntime "runtime"
@@ -108,6 +109,19 @@ func runCmd(ctx *cli.Context) error {
108109
},
109110
}
110111

112+
if cpuProfilePath := ctx.GlobalString(CPUProfileFlag.Name); cpuProfilePath != "" {
113+
f, err := os.Create(cpuProfilePath)
114+
if err != nil {
115+
fmt.Println("could not create CPU profile: ", err)
116+
os.Exit(1)
117+
}
118+
if err := pprof.StartCPUProfile(f); err != nil {
119+
fmt.Println("could not start CPU profile: ", err)
120+
os.Exit(1)
121+
}
122+
defer pprof.StopCPUProfile()
123+
}
124+
111125
tstart := time.Now()
112126
if ctx.GlobalBool(CreateFlag.Name) {
113127
input := append(code, common.Hex2Bytes(ctx.GlobalString(InputFlag.Name))...)
@@ -125,12 +139,27 @@ func runCmd(ctx *cli.Context) error {
125139
fmt.Println(string(statedb.Dump()))
126140
}
127141

142+
if memProfilePath := ctx.GlobalString(MemProfileFlag.Name); memProfilePath != "" {
143+
f, err := os.Create(memProfilePath)
144+
if err != nil {
145+
fmt.Println("could not create memory profile: ", err)
146+
os.Exit(1)
147+
}
148+
if err := pprof.WriteHeapProfile(f); err != nil {
149+
fmt.Println("could not write memory profile: ", err)
150+
os.Exit(1)
151+
}
152+
f.Close()
153+
}
154+
128155
if ctx.GlobalBool(DebugFlag.Name) {
129156
fmt.Fprintln(os.Stderr, "#### TRACE ####")
130157
vm.WriteTrace(os.Stderr, logger.StructLogs())
131158
fmt.Fprintln(os.Stderr, "#### LOGS ####")
132159
vm.WriteLogs(os.Stderr, statedb.Logs())
160+
}
133161

162+
if ctx.GlobalBool(StatDumpFlag.Name) {
134163
var mem goruntime.MemStats
135164
goruntime.ReadMemStats(&mem)
136165
fmt.Fprintf(os.Stderr, `evm execution time: %v

common/bytes.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,18 @@ func Hex2BytesFixed(str string, flen int) []byte {
8989
}
9090

9191
func RightPadBytes(slice []byte, l int) []byte {
92-
if l < len(slice) {
92+
if l <= len(slice) {
9393
return slice
9494
}
9595

9696
padded := make([]byte, l)
97-
copy(padded[0:len(slice)], slice)
97+
copy(padded, slice)
9898

9999
return padded
100100
}
101101

102102
func LeftPadBytes(slice []byte, l int) []byte {
103-
if l < len(slice) {
103+
if l <= len(slice) {
104104
return slice
105105
}
106106

consensus/ethash/consensus.go

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
239239
return errZeroBlockTime
240240
}
241241
// Verify the block's difficulty based in it's timestamp and parent's difficulty
242-
expected := CalcDifficulty(chain.Config(), header.Time.Uint64(), parent.Time.Uint64(), parent.Number, parent.Difficulty)
242+
expected := CalcDifficulty(chain.Config(), header.Time.Uint64(), parent)
243243
if expected.Cmp(header.Difficulty) != 0 {
244244
return fmt.Errorf("invalid difficulty: have %v, want %v", header.Difficulty, expected)
245245
}
@@ -283,16 +283,19 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
283283
return nil
284284
}
285285

286-
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
287-
// that a new block should have when created at time given the parent block's time
288-
// and difficulty.
286+
// CalcDifficulty is the difficulty adjustment algorithm. It returns
287+
// the difficulty that a new block should have when created at time
288+
// given the parent block's time and difficulty.
289289
//
290290
// TODO (karalabe): Move the chain maker into this package and make this private!
291-
func CalcDifficulty(config *params.ChainConfig, time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
292-
if config.IsHomestead(new(big.Int).Add(parentNumber, common.Big1)) {
293-
return calcDifficultyHomestead(time, parentTime, parentNumber, parentDiff)
291+
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
292+
next := new(big.Int).Add(parent.Number, common.Big1)
293+
switch {
294+
case config.IsHomestead(next):
295+
return calcDifficultyHomestead(time, parent)
296+
default:
297+
return calcDifficultyFrontier(time, parent)
294298
}
295-
return calcDifficultyFrontier(time, parentTime, parentNumber, parentDiff)
296299
}
297300

298301
// Some weird constants to avoid constant memory allocs for them.
@@ -305,15 +308,15 @@ var (
305308
// calcDifficultyHomestead is the difficulty adjustment algorithm. It returns
306309
// the difficulty that a new block should have when created at time given the
307310
// parent block's time and difficulty. The calculation uses the Homestead rules.
308-
func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
311+
func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
309312
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
310313
// algorithm:
311314
// diff = (parent_diff +
312315
// (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
313316
// ) + 2^(periodCount - 2)
314317

315318
bigTime := new(big.Int).SetUint64(time)
316-
bigParentTime := new(big.Int).SetUint64(parentTime)
319+
bigParentTime := new(big.Int).Set(parent.Time)
317320

318321
// holds intermediate values to make the algo easier to read & audit
319322
x := new(big.Int)
@@ -329,16 +332,16 @@ func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *
329332
x.Set(bigMinus99)
330333
}
331334
// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
332-
y.Div(parentDiff, params.DifficultyBoundDivisor)
335+
y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
333336
x.Mul(y, x)
334-
x.Add(parentDiff, x)
337+
x.Add(parent.Difficulty, x)
335338

336339
// minimum difficulty can ever be (before exponential factor)
337340
if x.Cmp(params.MinimumDifficulty) < 0 {
338341
x.Set(params.MinimumDifficulty)
339342
}
340343
// for the exponential factor
341-
periodCount := new(big.Int).Add(parentNumber, common.Big1)
344+
periodCount := new(big.Int).Add(parent.Number, common.Big1)
342345
periodCount.Div(periodCount, expDiffPeriod)
343346

344347
// the exponential factor, commonly referred to as "the bomb"
@@ -354,25 +357,25 @@ func calcDifficultyHomestead(time, parentTime uint64, parentNumber, parentDiff *
354357
// calcDifficultyFrontier is the difficulty adjustment algorithm. It returns the
355358
// difficulty that a new block should have when created at time given the parent
356359
// block's time and difficulty. The calculation uses the Frontier rules.
357-
func calcDifficultyFrontier(time, parentTime uint64, parentNumber, parentDiff *big.Int) *big.Int {
360+
func calcDifficultyFrontier(time uint64, parent *types.Header) *big.Int {
358361
diff := new(big.Int)
359-
adjust := new(big.Int).Div(parentDiff, params.DifficultyBoundDivisor)
362+
adjust := new(big.Int).Div(parent.Difficulty, params.DifficultyBoundDivisor)
360363
bigTime := new(big.Int)
361364
bigParentTime := new(big.Int)
362365

363366
bigTime.SetUint64(time)
364-
bigParentTime.SetUint64(parentTime)
367+
bigParentTime.Set(parent.Time)
365368

366369
if bigTime.Sub(bigTime, bigParentTime).Cmp(params.DurationLimit) < 0 {
367-
diff.Add(parentDiff, adjust)
370+
diff.Add(parent.Difficulty, adjust)
368371
} else {
369-
diff.Sub(parentDiff, adjust)
372+
diff.Sub(parent.Difficulty, adjust)
370373
}
371374
if diff.Cmp(params.MinimumDifficulty) < 0 {
372375
diff.Set(params.MinimumDifficulty)
373376
}
374377

375-
periodCount := new(big.Int).Add(parentNumber, common.Big1)
378+
periodCount := new(big.Int).Add(parent.Number, common.Big1)
376379
periodCount.Div(periodCount, expDiffPeriod)
377380
if periodCount.Cmp(common.Big1) > 0 {
378381
// diff = diff + 2^(periodCount - 2)
@@ -434,8 +437,7 @@ func (ethash *Ethash) Prepare(chain consensus.ChainReader, header *types.Header)
434437
if parent == nil {
435438
return consensus.ErrUnknownAncestor
436439
}
437-
header.Difficulty = CalcDifficulty(chain.Config(), header.Time.Uint64(),
438-
parent.Time.Uint64(), parent.Number, parent.Difficulty)
440+
header.Difficulty = CalcDifficulty(chain.Config(), header.Time.Uint64(), parent)
439441

440442
return nil
441443
}

consensus/ethash/consensus_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"testing"
2424

2525
"github.com/ethereum/go-ethereum/common/math"
26+
"github.com/ethereum/go-ethereum/core/types"
2627
"github.com/ethereum/go-ethereum/params"
2728
)
2829

@@ -71,7 +72,11 @@ func TestCalcDifficulty(t *testing.T) {
7172
config := &params.ChainConfig{HomesteadBlock: big.NewInt(1150000)}
7273
for name, test := range tests {
7374
number := new(big.Int).Sub(test.CurrentBlocknumber, big.NewInt(1))
74-
diff := CalcDifficulty(config, test.CurrentTimestamp, test.ParentTimestamp, number, test.ParentDifficulty)
75+
diff := CalcDifficulty(config, test.CurrentTimestamp, &types.Header{
76+
Number: number,
77+
Time: new(big.Int).SetUint64(test.ParentTimestamp),
78+
Difficulty: test.ParentDifficulty,
79+
})
7580
if diff.Cmp(test.CurrentDifficulty) != 0 {
7681
t.Error(name, "failed. Expected", test.CurrentDifficulty, "and calculated", diff)
7782
}

core/chain_makers.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (b *BlockGen) AddTx(tx *types.Transaction) {
8484
if b.gasPool == nil {
8585
b.SetCoinbase(common.Address{})
8686
}
87-
b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
87+
b.statedb.Prepare(tx.Hash(), common.Hash{}, len(b.txs))
8888
receipt, _, err := ApplyTransaction(b.config, nil, &b.header.Coinbase, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, vm.Config{})
8989
if err != nil {
9090
panic(err)
@@ -142,7 +142,7 @@ func (b *BlockGen) OffsetTime(seconds int64) {
142142
if b.header.Time.Cmp(b.parent.Header().Time) <= 0 {
143143
panic("block time out of range")
144144
}
145-
b.header.Difficulty = ethash.CalcDifficulty(b.config, b.header.Time.Uint64(), b.parent.Time().Uint64(), b.parent.Number(), b.parent.Difficulty())
145+
b.header.Difficulty = ethash.CalcDifficulty(b.config, b.header.Time.Uint64(), b.parent.Header())
146146
}
147147

148148
// GenerateChain creates a chain of n blocks. The first block's
@@ -209,15 +209,20 @@ func makeHeader(config *params.ChainConfig, parent *types.Block, state *state.St
209209
} else {
210210
time = new(big.Int).Add(parent.Time(), big.NewInt(10)) // block time is fixed at 10 seconds
211211
}
212+
212213
return &types.Header{
213214
Root: state.IntermediateRoot(config.IsEIP158(parent.Number())),
214215
ParentHash: parent.Hash(),
215216
Coinbase: parent.Coinbase(),
216-
Difficulty: ethash.CalcDifficulty(config, time.Uint64(), new(big.Int).Sub(time, big.NewInt(10)).Uint64(), parent.Number(), parent.Difficulty()),
217-
GasLimit: CalcGasLimit(parent),
218-
GasUsed: new(big.Int),
219-
Number: new(big.Int).Add(parent.Number(), common.Big1),
220-
Time: time,
217+
Difficulty: ethash.CalcDifficulty(config, time.Uint64(), &types.Header{
218+
Number: parent.Number(),
219+
Time: new(big.Int).Sub(time, big.NewInt(10)),
220+
Difficulty: parent.Difficulty(),
221+
}),
222+
GasLimit: CalcGasLimit(parent),
223+
GasUsed: new(big.Int),
224+
Number: new(big.Int).Add(parent.Number(), common.Big1),
225+
Time: time,
221226
}
222227
}
223228

core/state/journal.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ type (
7171
hash common.Hash
7272
}
7373
touchChange struct {
74-
account *common.Address
75-
prev bool
74+
account *common.Address
75+
prev bool
7676
prevDirty bool
7777
}
7878
)
@@ -91,6 +91,11 @@ func (ch suicideChange) undo(s *StateDB) {
9191
if obj != nil {
9292
obj.suicided = ch.prev
9393
obj.setBalance(ch.prevbalance)
94+
// if the object wasn't suicided before, remove
95+
// it from the list of destructed objects as well.
96+
if !obj.suicided {
97+
delete(s.stateObjectsDestructed, *ch.account)
98+
}
9499
}
95100
}
96101

0 commit comments

Comments
 (0)