Skip to content

Commit

Permalink
miner :: add : check to run worker commitWork (ethereum#828)
Browse files Browse the repository at this point in the history
* add : check to run worker commitWork

* fix : TestJaipurFork + TestOutOfTurnSigning
  • Loading branch information
0xsharma authored Apr 20, 2023
1 parent 2667461 commit 6dee9b5
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 63 deletions.
4 changes: 3 additions & 1 deletion miner/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,9 @@ func (w *worker) mainLoop(ctx context.Context) {
select {
case req := <-w.newWorkCh:
//nolint:contextcheck
w.commitWork(req.ctx, req.interrupt, req.noempty, req.timestamp)
if w.isRunning() {
w.commitWork(req.ctx, req.interrupt, req.noempty, req.timestamp)
}

case req := <-w.getWorkCh:
//nolint:contextcheck
Expand Down
155 changes: 93 additions & 62 deletions tests/bor/bor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,90 +577,112 @@ func TestFetchStateSyncEvents_2(t *testing.T) {
require.Equal(t, uint64(6), lastStateID.Uint64())
}

func TestOutOfTurnSigning(t *testing.T) {
init := buildEthereumInstance(t, rawdb.NewMemoryDatabase())
chain := init.ethereum.BlockChain()
engine := init.ethereum.Engine()
_bor := engine.(*bor.Bor)

defer _bor.Close()

_, heimdallSpan := loadSpanFromFile(t)
proposer := valset.NewValidator(addr, 10)
heimdallSpan.ValidatorSet.Validators = append(heimdallSpan.ValidatorSet.Validators, proposer)
// Abs returns the absolute value of x.
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}

// add the block producer
h, ctrl := getMockedHeimdallClient(t, heimdallSpan)
defer ctrl.Finish()
func TestOutOfTurnSigning(t *testing.T) {
log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
fdlimit.Raise(2048)

h.EXPECT().Close().AnyTimes()
// Generate a batch of accounts to seal and fund with
faucets := make([]*ecdsa.PrivateKey, 128)
for i := 0; i < len(faucets); i++ {
faucets[i], _ = crypto.GenerateKey()
}

spanner := getMockedSpanner(t, heimdallSpan.ValidatorSet.Validators)
_bor.SetSpanner(spanner)
_bor.SetHeimdallClient(h)
// Create an Ethash network based off of the Ropsten config
// Generate a batch of accounts to seal and fund with
genesis := InitGenesis(t, faucets, "./testdata/genesis_2val.json", 8)

db := init.ethereum.ChainDb()
block := init.genesis.ToBlock(db)
var (
stacks []*node.Node
nodes []*eth.Ethereum
enodes []*enode.Node
)
for i := 0; i < 2; i++ {
// Start the node and wait until it's up
stack, ethBackend, err := InitMiner(genesis, keys[i], true)
if err != nil {
panic(err)
}
defer stack.Close()

setDifficulty := func(header *types.Header) {
if IsSprintStart(header.Number.Uint64()) {
header.Difficulty = big.NewInt(int64(len(heimdallSpan.ValidatorSet.Validators)))
for stack.Server().NodeInfo().Ports.Listener == 0 {
time.Sleep(250 * time.Millisecond)
}
// Connect the node to all the previous ones
for _, n := range enodes {
stack.Server().AddPeer(n)
}
// Start tracking the node and its enode
stacks = append(stacks, stack)
nodes = append(nodes, ethBackend)
enodes = append(enodes, stack.Server().Self())
}

for i := uint64(1); i < spanSize; i++ {
block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor, nil, heimdallSpan.ValidatorSet.Validators, setDifficulty)
insertNewBlock(t, chain, block)
// Iterate over all the nodes and start mining
time.Sleep(3 * time.Second)
for _, node := range nodes {
if err := node.StartMining(1); err != nil {
panic(err)
}
}

// insert spanSize-th block
// This account is one the out-of-turn validators for 1st (0-indexed) span
signer := "c8deb0bea5c41afe8e37b4d1bd84e31adff11b09c8c96ff4b605003cce067cd9"
signerKey, _ := hex.DecodeString(signer)
newKey, _ := crypto.HexToECDSA(signer)
newAddr := crypto.PubkeyToAddress(newKey.PublicKey)
expectedSuccessionNumber := 2
for {

parentTime := block.Time()
// for block 1 to 8, the primary validator is node0
blockHeaderVal0 := nodes[0].BlockChain().CurrentHeader()
blockHeaderVal1 := nodes[1].BlockChain().CurrentHeader()

// we remove peer connection between node0 and node1
if blockHeaderVal0.Number.Uint64() == 1 {
stacks[0].Server().RemovePeer(enodes[1])
}

if blockHeaderVal1.Number.Uint64() == 9 {
break
}

setParentTime := func(header *types.Header) {
header.Time = parentTime + 1
}

const turn = 1
// function to get timestamp difference between two nodes of the same blockNumber
timeDiff := func(blockNum int) int {
blockHeaderVal0 := nodes[0].BlockChain().GetHeaderByNumber(uint64(blockNum))
blockHeaderVal1 := nodes[1].BlockChain().GetHeaderByNumber(uint64(blockNum))

setDifficulty = func(header *types.Header) {
header.Difficulty = big.NewInt(int64(len(heimdallSpan.ValidatorSet.Validators)) - turn)
return Abs(int(blockHeaderVal0.Time - blockHeaderVal1.Time))
}

block = buildNextBlock(t, _bor, chain, block, signerKey, init.genesis.Config.Bor, nil, heimdallSpan.ValidatorSet.Validators, setParentTime, setDifficulty)
_, err := chain.InsertChain([]*types.Block{block})
require.Equal(t,
bor.BlockTooSoonError{Number: spanSize, Succession: expectedSuccessionNumber},
*err.(*bor.BlockTooSoonError))
// check block 10 miner ; expected author is node1 signer
blockHeaderVal0 := nodes[0].BlockChain().GetHeaderByNumber(3)
blockHeaderVal1 := nodes[1].BlockChain().GetHeaderByNumber(3)

expectedDifficulty := uint64(len(heimdallSpan.ValidatorSet.Validators) - expectedSuccessionNumber - turn) // len(validators) - succession
header := block.Header()
// check both nodes have the same block 10
assert.Equal(t, blockHeaderVal0.Difficulty, common.Big2)

diff := bor.CalcProducerDelay(header.Number.Uint64(), expectedSuccessionNumber, init.genesis.Config.Bor)
header.Time += diff
// check node0 has block mined by node1
assert.Equal(t, blockHeaderVal1.Difficulty, common.Big1)

sign(t, header, signerKey, init.genesis.Config.Bor)
// node seperated at block 1, so at block 3, node0 should be at 3 seconds, and node1 should be at 5( 1 + 2*2 ) seconds
assert.Equal(t, timeDiff(3), 2)

block = types.NewBlockWithHeader(header)
// check block 10 miner ; expected author is node1 signer
blockHeaderVal0 = nodes[0].BlockChain().GetHeaderByNumber(7)
blockHeaderVal1 = nodes[1].BlockChain().GetHeaderByNumber(7)

_, err = chain.InsertChain([]*types.Block{block})
require.NotNil(t, err)
require.Equal(t,
bor.WrongDifficultyError{Number: spanSize, Expected: expectedDifficulty, Actual: 3, Signer: newAddr.Bytes()},
*err.(*bor.WrongDifficultyError))
// check both nodes have the same block 10
assert.Equal(t, blockHeaderVal0.Difficulty, common.Big2)

header.Difficulty = new(big.Int).SetUint64(expectedDifficulty)
sign(t, header, signerKey, init.genesis.Config.Bor)
block = types.NewBlockWithHeader(header)
// check node0 has block mined by node1
assert.Equal(t, blockHeaderVal1.Difficulty, common.Big1)

_, err = chain.InsertChain([]*types.Block{block})
require.Nil(t, err)
// node seperated at block 1, so at block 7, node0 should be at 7 seconds, and node1 should be at 13( 1 + 2*6 ) seconds
assert.Equal(t, timeDiff(7), 6)
}

func TestSignerNotFound(t *testing.T) {
Expand Down Expand Up @@ -1099,12 +1121,21 @@ func TestJaipurFork(t *testing.T) {

res, _ := loadSpanFromFile(t)

spanner := getMockedSpanner(t, res.Result.ValidatorSet.Validators)
currentValidators := []*valset.Validator{valset.NewValidator(addr, 10)}

spanner := getMockedSpanner(t, currentValidators)
_bor.SetSpanner(spanner)

for i := uint64(1); i < sprintSize; i++ {
block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor, nil, res.Result.ValidatorSet.Validators)
if IsSpanEnd(i) {
currentValidators = res.Result.ValidatorSet.Validators
}

block = buildNextBlock(t, _bor, chain, block, nil, init.genesis.Config.Bor, nil, currentValidators)
fmt.Println("SHIVAM 1")

insertNewBlock(t, chain, block)
fmt.Println("SHIVAM 2")

if block.Number().Uint64() == init.genesis.Config.Bor.JaipurBlock.Uint64()-1 {
require.Equal(t, testSealHash(block.Header(), init.genesis.Config.Bor), bor.SealHash(block.Header(), init.genesis.Config.Bor))
Expand Down

0 comments on commit 6dee9b5

Please sign in to comment.