Skip to content

Commit d79621d

Browse files
authored
Merge 3b24d20 into 0403f95
2 parents 0403f95 + 3b24d20 commit d79621d

File tree

9 files changed

+93
-19
lines changed

9 files changed

+93
-19
lines changed

consensus/cuckoo/consensus.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package cuckoo
1919
import (
2020
"encoding/binary"
2121
// "encoding/hex"
22-
// "bytes"
22+
"bytes"
2323
"errors"
2424
"fmt"
2525
"math/big"
@@ -278,7 +278,8 @@ func (cuckoo *Cuckoo) verifyHeader(chain consensus.ChainHeaderReader, header, pa
278278
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
279279
}
280280

281-
validate := checkGasLimit(parent.GasUsed, parent.GasLimit, header.GasLimit)
281+
//validate := checkGasLimit(parent.GasUsed, parent.GasLimit, header.GasLimit, chain.Config(), header.Number)
282+
validate := gasCheck(chain, parent, header)
282283
if !validate {
283284
return fmt.Errorf("invalid gas limit trend: have %d, want %d used %d", header.GasLimit, parent.GasLimit, parent.GasUsed)
284285
}
@@ -369,7 +370,10 @@ func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Heade
369370
}
370371

371372
// important add gas limit to consensus
372-
func checkGasLimit(gasUsed, gasLimit, currentGasLimit uint64) bool {
373+
func gasCheck(chain consensus.ChainHeaderReader, parent, header *types.Header) bool {
374+
return checkGasLimit(parent.GasUsed, parent.GasLimit, header.GasLimit, chain.Config(), header.Number)
375+
}
376+
func checkGasLimit(gasUsed, gasLimit, currentGasLimit uint64, config *params.ChainConfig, num *big.Int) bool {
373377
contrib := (gasUsed + gasUsed/2) / params.GasLimitBoundDivisor
374378

375379
decay := gasLimit/params.GasLimitBoundDivisor - 1
@@ -391,7 +395,10 @@ func checkGasLimit(gasUsed, gasLimit, currentGasLimit uint64) bool {
391395
}
392396
}
393397

394-
// TODO
398+
if config != nil && config.IsMercury(num) {
399+
return limit <= currentGasLimit
400+
}
401+
395402
return limit == currentGasLimit
396403
}
397404

@@ -677,6 +684,15 @@ func (cuckoo *Cuckoo) VerifySeal(chain consensus.ChainHeaderReader, header *type
677684
return errInvalidDifficulty
678685
}
679686

687+
// Verify the calculated values against the ones provided in the header
688+
if chain.Config().IsMercury(header.Number) {
689+
log.Trace("Mix digest verify", "number", header.Number, "mix", header.Solution.Hash(), "header", header.MixDigest)
690+
digest := header.Solution.Hash().Bytes()
691+
if !bytes.Equal(header.MixDigest[:], digest) {
692+
return errInvalidMixDigest
693+
}
694+
}
695+
680696
var (
681697
result = header.Solution
682698
nonce uint64 = uint64(header.Nonce.Uint64())

consensus/cuckoo/consensus_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cuckoo
22

33
import (
4+
"bytes"
45
"encoding/binary"
56
"math/big"
67
"math/rand"
@@ -71,23 +72,33 @@ func randSlice(min, max uint32) []byte {
7172
}
7273

7374
func TestGasLimitCheck(t *testing.T) {
74-
if validate := checkGasLimit(0, 7992189, 8000000); !validate {
75+
if validate := checkGasLimit(0, 7992189, 8000000, nil, nil); !validate {
7576
t.Fatalf("failed")
7677
}
7778

78-
if validate := checkGasLimit(7992189, 7992189, 8000000); !validate {
79+
if validate := checkGasLimit(7992189, 7992189, 8000000, nil, nil); !validate {
7980
t.Fatalf("failed")
8081
}
8182

82-
if validate := checkGasLimit(0, 8000000, 7992189); validate {
83+
if validate := checkGasLimit(0, 8000000, 7992189, nil, nil); validate {
8384
t.Fatalf("failed")
8485
}
8586

86-
if validate := checkGasLimit(7980000, 8000000, 8003878); !validate {
87+
if validate := checkGasLimit(7980000, 8000000, 8003878, nil, nil); !validate {
8788
t.Fatalf("failed")
8889
}
8990

90-
if validate := checkGasLimit(7980000, 8000000, 8003879); validate {
91+
if validate := checkGasLimit(7980000, 8000000, 8003879, nil, nil); validate {
92+
t.Fatalf("failed")
93+
}
94+
}
95+
96+
func TestMixDigest(t *testing.T) {
97+
sol := &types.BlockSolution{36552774, 57703112, 69439022, 71282429, 117293109, 186862362, 271815245, 283711993, 301666096, 321610391, 345111432, 376920806, 469608283, 480776867, 488279241, 490162501, 496690146, 516943318, 548320772, 575755973, 584516346, 590932588, 594672482, 596315856, 611820183, 626014278, 668956240, 724642732, 737723908, 761956873, 772529653, 781328833, 782613854, 804339063, 838293864, 852149620, 875286932, 888462575, 905024013, 993378264, 1039286741, 1068794681}
98+
mix := sol.Hash()
99+
100+
t.Log("sol:", sol, "mix:", mix)
101+
if !bytes.Equal(mix[:], sol.Hash().Bytes()) {
91102
t.Fatalf("failed")
92103
}
93104
}

consensus/cuckoo/sealer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ func (cuckoo *Cuckoo) remote() {
207207
// Verify the correctness of submitted result.
208208
header := block.Header()
209209
header.Nonce = nonce
210-
//header.MixDigest = mixDigest
210+
header.MixDigest = sol.Hash()
211211
header.Solution = sol
212212
if err := cuckoo.VerifySeal(nil, header); err != nil {
213213
log.Warn("Invalid proof-of-work submitted", "hash", hash, "err", err)

core/cvm.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/CortexFoundation/CortexTheseus/core/types"
2525
"github.com/CortexFoundation/CortexTheseus/core/vm"
2626
"github.com/CortexFoundation/CortexTheseus/log"
27+
"github.com/CortexFoundation/CortexTheseus/params"
2728
)
2829

2930
// ChainContext supports retrieving headers and consensus parameters from the
@@ -48,9 +49,19 @@ func NewCVMBlockContext(header *types.Header, chain ChainContext, author *common
4849
} else {
4950
beneficiary = *author
5051
}
52+
53+
log.Trace("Random", "number", header.Number, "mix", header.MixDigest, "parent", header.ParentHash, "mercury", params.MERCURY_MAINNET)
54+
55+
// TODO auto invoked by PoS (IsMerge Version) op random, set when mining work commit, it will not happen by PoW
5156
if header.Difficulty.Cmp(common.Big0) == 0 {
5257
random = &header.MixDigest
58+
} else {
59+
// TODO fake random only for random op pass, used carefully, check block number
60+
if params.MERCURY_MAINNET != nil && header.Number.Cmp(params.MERCURY_MAINNET) >= 0 {
61+
random = &header.ParentHash
62+
}
5363
}
64+
5465
return vm.BlockContext{
5566
CanTransfer: CanTransfer,
5667
Transfer: Transfer,

core/types/block.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@ func (n *BlockNonce) UnmarshalText(input []byte) error {
6363
return hexutil.UnmarshalFixedText("BlockNonce", input, n[:])
6464
}
6565

66+
func (s *BlockSolution) Hash() common.Hash {
67+
b, e := s.MarshalText()
68+
if e != nil {
69+
return common.EmptyHash
70+
}
71+
return common.BytesToHash(b)
72+
}
73+
6674
func (s *BlockSolution) Uint32() []uint32 { return s[:] }
6775

6876
func (s *BlockSolution) MarshalText() ([]byte, error) {

core/vm/interpreter.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ func NewCVMInterpreter(cvm *CVM) *CVMInterpreter {
8989
// If jump table was not initialised we set the default one.
9090
var table *JumpTable
9191
switch {
92+
case cvm.chainRules.IsMercury:
93+
table = &mercuryInstructionSet
9294
case cvm.chainRules.IsMerge:
9395
table = &mergeInstructionSet
9496
case cvm.chainRules.IsNeo:

core/vm/jump_table.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ var (
5353
neoInstructionSet = newNeoInstructionSet()
5454

5555
mergeInstructionSet = newMergeInstructionSet()
56+
57+
mercuryInstructionSet = newMercuryInstructionSet()
5658
)
5759

5860
// JumpTable contains the CVM opcodes supported at a given fork.
@@ -67,14 +69,20 @@ func validate(jt JumpTable) JumpTable {
6769
return jt
6870
}
6971

72+
func newMercuryInstructionSet() JumpTable {
73+
instructionSet := newMergeInstructionSet()
74+
enable5656(&instructionSet) // EIP-5656 (MCOPY opcode)
75+
76+
return validate(instructionSet)
77+
}
78+
7079
func newMergeInstructionSet() JumpTable {
7180
instructionSet := newNeoInstructionSet()
7281
instructionSet[RANDOM] = &operation{
7382
execute: opRandom,
7483
gasCost: constGasFunc(GasQuickStep),
7584
validateStack: makeStackFunc(0, 1),
7685
}
77-
enable5656(&instructionSet) // EIP-5656 (MCOPY opcode)
7886
return validate(instructionSet)
7987
}
8088

params/config.go

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ var (
131131
PetersburgBlock: big.NewInt(0),
132132
IstanbulBlock: big.NewInt(3_230_000),
133133
NeoBlock: big.NewInt(4_650_000),
134+
MercuryBlock: MERCURY_MAINNET,
134135
TerminalTotalDifficulty: nil,
135136
TerminalTotalDifficultyPassed: false,
136137
Cuckoo: new(CuckooConfig),
@@ -151,6 +152,7 @@ var (
151152
PetersburgBlock: big.NewInt(0),
152153
IstanbulBlock: big.NewInt(0),
153154
NeoBlock: big.NewInt(5_000_000),
155+
MercuryBlock: nil,
154156
TerminalTotalDifficulty: nil,
155157
TerminalTotalDifficultyPassed: false,
156158
Clique: &CliqueConfig{
@@ -174,6 +176,7 @@ var (
174176
PetersburgBlock: big.NewInt(0),
175177
IstanbulBlock: big.NewInt(0),
176178
NeoBlock: big.NewInt(0),
179+
MercuryBlock: nil,
177180
TerminalTotalDifficulty: nil,
178181
TerminalTotalDifficultyPassed: false,
179182
Cuckoo: new(CuckooConfig),
@@ -194,6 +197,7 @@ var (
194197
PetersburgBlock: big.NewInt(0),
195198
IstanbulBlock: big.NewInt(0),
196199
NeoBlock: big.NewInt(0),
200+
MercuryBlock: nil,
197201
TerminalTotalDifficulty: nil,
198202
TerminalTotalDifficultyPassed: false,
199203
Clique: &CliqueConfig{
@@ -221,6 +225,7 @@ var (
221225
PetersburgBlock: big.NewInt(0),
222226
IstanbulBlock: nil,
223227
NeoBlock: nil,
228+
MercuryBlock: nil,
224229
TerminalTotalDifficulty: nil,
225230
TerminalTotalDifficultyPassed: false,
226231
Cuckoo: new(CuckooConfig),
@@ -231,9 +236,9 @@ var (
231236
//
232237
// This configuration is intentionally not using keyed fields to force anyone
233238
// adding flags to the config to also have to set these fields.
234-
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
239+
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
235240

236-
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(CuckooConfig), nil}
241+
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, false, new(CuckooConfig), nil}
237242
TestRules = TestChainConfig.Rules(new(big.Int), false, 0)
238243
)
239244

@@ -269,6 +274,7 @@ type ChainConfig struct {
269274
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
270275
IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul)
271276
NeoBlock *big.Int `json:"neoBlock,omitempty"`
277+
MercuryBlock *big.Int `json:"mercuryBlock,omitempty"`
272278
// TerminalTotalDifficulty is the amount of total difficulty reached by
273279
// the network that triggers the consensus upgrade.
274280
TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"`
@@ -311,7 +317,7 @@ func (c *ChainConfig) String() string {
311317
default:
312318
engine = "unknown"
313319
}
314-
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v TangerineWhistle(EIP150): %v SpuriousDragon(EIP155): %v SpuriousDragon(EIP158): %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v Neo:%v Engine: %v}",
320+
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v TangerineWhistle(EIP150): %v SpuriousDragon(EIP155): %v SpuriousDragon(EIP158): %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v Neo:%v Mercury:%v Engine: %v}",
315321
c.ChainID,
316322
c.HomesteadBlock,
317323
c.DAOForkBlock,
@@ -324,6 +330,7 @@ func (c *ChainConfig) String() string {
324330
c.PetersburgBlock,
325331
c.IstanbulBlock,
326332
c.NeoBlock,
333+
c.MercuryBlock,
327334
engine,
328335
)
329336
}
@@ -378,6 +385,10 @@ func (c *ChainConfig) IsNeo(num *big.Int) bool {
378385
return isForked(c.NeoBlock, num)
379386
}
380387

388+
func (c *ChainConfig) IsMercury(num *big.Int) bool {
389+
return isForked(c.MercuryBlock, num)
390+
}
391+
381392
// IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
382393
func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
383394
if c.TerminalTotalDifficulty == nil {
@@ -442,6 +453,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error {
442453
{name: "petersburgBlock", block: c.PetersburgBlock},
443454
{name: "istanbulBlock", block: c.IstanbulBlock},
444455
{name: "neoBlock", block: c.NeoBlock},
456+
{name: "mercuryBlock", block: c.MercuryBlock},
445457
} {
446458
if lastFork.name != "" {
447459
// Next one must be higher number
@@ -505,6 +517,10 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi
505517
if isForkIncompatible(c.NeoBlock, newcfg.NeoBlock, head) {
506518
return newCompatError("Neo fork block", c.NeoBlock, newcfg.NeoBlock)
507519
}
520+
521+
if isForkIncompatible(c.MercuryBlock, newcfg.MercuryBlock, head) {
522+
return newCompatError("Mercury fork block", c.MercuryBlock, newcfg.MercuryBlock)
523+
}
508524
return nil
509525
}
510526

@@ -622,10 +638,10 @@ func (err *ConfigCompatError) Error() string {
622638
// Rules is a one time interface meaning that it shouldn't be used in between transition
623639
// phases.
624640
type Rules struct {
625-
ChainID *big.Int
626-
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
627-
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul, IsNeo bool
628-
IsMerge bool
641+
ChainID *big.Int
642+
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool
643+
IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul, IsNeo, IsMercury bool
644+
IsMerge bool
629645
}
630646

631647
// Rules ensures c's ChainID is not nil.
@@ -634,7 +650,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules
634650
if chainID == nil {
635651
chainID = new(big.Int)
636652
}
637-
return Rules{ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsByzantium: c.IsByzantium(num), IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsNeo: c.IsNeo(num), IsMerge: isMerge}
653+
return Rules{ChainID: new(big.Int).Set(chainID), IsHomestead: c.IsHomestead(num), IsEIP150: c.IsEIP150(num), IsEIP155: c.IsEIP155(num), IsEIP158: c.IsEIP158(num), IsByzantium: c.IsByzantium(num), IsPetersburg: c.IsPetersburg(num), IsIstanbul: c.IsIstanbul(num), IsNeo: c.IsNeo(num), IsMercury: c.IsMercury(num), IsMerge: isMerge}
638654
}
639655

640656
// Get Mature Block

params/protocol_params.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ var (
190190

191191
CTXC_F1 = big.NewInt(0).Mul(big.NewInt(20_486_540), big.NewInt(1000000000000000000))
192192
CTXC_F2 = big.NewInt(0).Mul(big.NewInt(21_285_544), big.NewInt(1000000000000000000))
193+
194+
MERCURY_MAINNET *big.Int = nil //big.NewInt(0)
193195
)
194196

195197
const (

0 commit comments

Comments
 (0)