refine race condition solution

This commit is contained in:
Gerui Wang 2021-12-21 10:19:17 +08:00
parent d901d1df6e
commit db58081b8d
2 changed files with 15 additions and 12 deletions

View file

@ -249,7 +249,7 @@ func (x *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *ty
when it happens we get the signers list by requesting smart contract
*/
// Retrieve the snapshot needed to verify this header and cache it
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents, header)
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents, nil)
if err != nil {
return err
}
@ -435,7 +435,7 @@ func (x *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, s
}
// snapshot retrieves the authorization snapshot at a given point in time.
func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header, currentHeader *types.Header) (*SnapshotV1, error) {
func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header, selfHeader *types.Header) (*SnapshotV1, error) {
// Search for a SnapshotV1 in memory or on disk for checkpoints
var (
headers []*types.Header
@ -482,8 +482,8 @@ func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
return nil, consensus.ErrUnknownAncestor
}
parents = parents[:len(parents)-1]
} else if currentHeader != nil && currentHeader.Hash() == hash {
header = currentHeader
} else if selfHeader != nil && selfHeader.Hash() == hash {
header = selfHeader
} else {
// No explicit parents (or no more left), reach out to the database
header = chain.GetHeader(hash, number)
@ -542,7 +542,7 @@ func (x *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
return utils.ErrUnknownBlock
}
// Retrieve the snapshot needed to verify this header and cache it
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents, header)
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents, nil)
if err != nil {
return err
}
@ -658,7 +658,7 @@ func (x *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
number := header.Number.Uint64()
// Assemble the voting snapshot to check which votes make sense
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil, header)
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil, nil)
if err != nil {
return err
}
@ -834,7 +834,7 @@ func (x *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
x.lock.RUnlock()
// Bail out if we're unauthorized to sign a block
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil, block.Header())
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil, nil)
if err != nil {
return nil, err
}

View file

@ -9,7 +9,7 @@ import (
)
// Snapshot try to read before blockchain is written
func TestRaceconditionOnBlockchainReadAndWrite(t *testing.T) {
func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
@ -78,22 +78,25 @@ func TestRaceconditionOnBlockchainReadAndWrite(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if blockchain.CurrentHeader().Hash() != block450B.Hash() {
t.Fatalf("the block with higher difficulty should be current header")
}
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
}
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000888)) != 0 {
t.Fatalf("account 1 should NOT have 10000000999 in balance as the block is forked, not on the main chain")
t.Fatalf("account 1 should have 10000000888 in balance as the block replace previous head block at number 450")
}
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil {
t.Fatal(err)
}
// Should run the `updateM1` for forked chain as it's now the mainchain, hence account3 NOT exit
if signers[acc3Addr.Hex()] == true {
// Should run the `updateM1` for forked chain as it's now the mainchain, hence account2 should exist
if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("account 3 should NOT sit in the signer list as previos block result")
t.Fatalf("account 2 should sit in the signer list")
}
//Insert block 451 parent is 451 B