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

View file

@ -9,7 +9,7 @@ import (
) )
// Snapshot try to read before blockchain is written // 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) blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
@ -78,22 +78,25 @@ func TestRaceconditionOnBlockchainReadAndWrite(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if blockchain.CurrentHeader().Hash() != block450B.Hash() {
t.Fatalf("the block with higher difficulty should be current header")
}
state, err = blockchain.State() state, err = blockchain.State()
if err != nil { if err != nil {
t.Fatalf("Failed while trying to get blockchain state") t.Fatalf("Failed while trying to get blockchain state")
} }
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000888)) != 0 { 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()) signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Should run the `updateM1` for forked chain as it's now the mainchain, hence account3 NOT exit // Should run the `updateM1` for forked chain as it's now the mainchain, hence account2 should exist
if signers[acc3Addr.Hex()] == true { if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t) 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 //Insert block 451 parent is 451 B