mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
refine race condition solution
This commit is contained in:
parent
d901d1df6e
commit
db58081b8d
2 changed files with 15 additions and 12 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue