go-ethereum/consensus/tests/blockchain_race_condition_test.go
Liam 6c5fe34615 v2 miner function implementation and happy path (#22)
* New struct in consensus/XDPoS/utils/types.go, util functions, and test. (#14)

* define vote, timeout, sync info, qc, tc, extra fields in types.go, add test in types_test.go

* add json tag in types.go, refine encoder decoder of extra fields

* refactor types.go utils.go

* re-write types, comments

* add Hash SigHash for types, and tests

* define Round type

* remove unnecessary logs

* add v2 engine functions placeholder

* typo fix on the consensus v2 function placeholders

* add countdown timer

* make initilised private to countdown

* add v2 specific config struct

* rename some config variables

* Implement BFT Message receiver (#13)

* fix or skip tests due to PR-136 changes

* add bft receiver functions

* add bft receiver functions

* rename tc to TimeoutCert

* implement more functions

* New struct in consensus/XDPoS/utils/types.go, util functions, and test. (#14)

* define vote, timeout, sync info, qc, tc, extra fields in types.go, add test in types_test.go

* add json tag in types.go, refine encoder decoder of extra fields

* refactor types.go utils.go

* re-write types, comments

* add Hash SigHash for types, and tests

* define Round type

* remove unnecessary logs

* add temp functions

* add v2 engine functions placeholder

* typo fix on the consensus v2 function placeholders

* add countdown timer

* make initilised private to countdown

* push verify function

* add test on receiving vote

* revert type change

* add async on broadcast function

* add quit initial

* fix test

Co-authored-by: Jianrong <wjrjerome@gmail.com>
Co-authored-by: wgr523 <wgr523@gmail.com>

* generate and verify timeout message

* Consensus V2 variable, timeout pool (#19)

* fill in XDPoS_v2 variables and processQC/TC

* add timeout pool, refine engine variables

* refactor type functions

* solve a small pointer bug

* create general pool and its test, refine engine

* refine pool, add xdpos v2 config cert threshold

* refine config

* vote and timeout handlers

* fix pool test

* bft miner preparation

* review comment improvement

* update

* relocate tests

* add and remove comment

* fix the syntax error

* update network layer and add handler functions (#23)

* update network layer and add handler functions

* fix test syntax error

* add ProcessQC implementation

* add ProcessQC tests

* add snapshot test

* add wait qc process

* remove testing files

* add route snapshot

* fix merge issue

* add default v2 behaviour (#24)

* add v2 ecrecover functions and refactor test

* fix all the tests

* put minimun lock variable

* debugging prepare and seal v2 blocks

* Trigger proposeBlockHandler after v2 block received and verified in fetcher

* skip snapshot apply related tests

* update test check

* rename bfter to bft handler and ignore normal behviour

* fix bugs during local 4 node run

* fix test

* fix sync info test

* fix bugs during local 4 node run

* rebase and fix bug

* remove hook validators function"

Co-authored-by: wgr523 <wgr523@gmail.com>
Co-authored-by: Jianrong <wjrjerome@gmail.com>
2021-12-30 11:45:18 +11:00

173 lines
5.2 KiB
Go

package tests
import (
"math/big"
"testing"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/params"
)
// Snapshot try to read before blockchain is written
func TestRaceConditionOnBlockchainReadAndWrite(t *testing.T) {
blockchain, backend, parentBlock, _ := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
state, err := blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
}
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
// Check initial signer
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
if err != nil {
t.Fatal(err)
}
if signers[acc3Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("acc3Addr should sit in the signer list")
}
// Insert first Block 450 A
t.Logf("Inserting block with propose and transfer at 450 A...")
blockCoinbaseA := "0xaaa0000000000000000000000000000000000450"
tx, err := voteTX(58117, 0, acc1Addr.String())
if err != nil {
t.Fatal(err)
}
transferTransaction := transferTx(t, acc1Addr, 999)
merkleRoot := "ea465415b60d88429f181fec9fae67c0f19cbf5a4fa10971d96d4faa57d96ffa"
header := &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(450)),
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinbaseA),
}
blockA, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
if err != nil {
t.Fatal(err)
}
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
}
t.Log("After transfer transaction at block 450 A, Account 1 have balance of: ", state.GetBalance(acc1Addr))
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000999)) != 0 {
t.Fatalf("account 1 should have 10000000999 in balance")
}
signers, err = GetSnapshotSigner(blockchain, blockA.Header())
if err != nil {
t.Fatal(err)
}
if signers[acc1Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("account 1 should sit in the signer list")
}
// Insert forked Block 450 B
t.Logf("Inserting block with propose at 450 B...")
blockCoinBase450B := "0xbbb0000000000000000000000000000000000450"
tx, err = voteTX(37117, 0, acc2Addr.String())
if err != nil {
t.Fatal(err)
}
transferTransaction = transferTx(t, acc1Addr, 888)
merkleRoot = "184edaddeafc2404248f896ae46be503ae68949896c8eb6b6ad43695581e5022"
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(450)),
ParentHash: parentBlock.Hash(),
Coinbase: common.HexToAddress(blockCoinBase450B),
Difficulty: big.NewInt(2),
}
block450B, err := insertBlockTxs(blockchain, header, []*types.Transaction{tx, transferTransaction})
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 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 account2 should exist
if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("account 2 should sit in the signer list")
}
//Insert block 451 parent is 451 B
t.Logf("Inserting block with propose at 451 B...")
blockCoinBase451B := "0xbbb0000000000000000000000000000000000451"
merkleRoot = "184edaddeafc2404248f896ae46be503ae68949896c8eb6b6ad43695581e5022"
header = &types.Header{
Root: common.HexToHash(merkleRoot),
Number: big.NewInt(int64(451)),
ParentHash: block450B.Hash(),
Coinbase: common.HexToAddress(blockCoinBase451B),
Difficulty: big.NewInt(3),
}
block451B, err := insertBlock(blockchain, header)
if err != nil {
t.Fatal(err)
}
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
if err != nil {
t.Fatal(err)
}
if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("account 2 should sit in the signer list")
}
signers, err = GetSnapshotSigner(blockchain, block451B.Header())
if err != nil {
t.Fatal(err)
}
if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("account 2 should sit in the signer list")
}
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
if err != nil {
t.Fatal(err)
}
if signers[acc2Addr.Hex()] != true {
debugMessage(backend, signers, t)
t.Fatalf("acc2Addr should sit in the signer list")
}
state, err = blockchain.State()
if err != nil {
t.Fatalf("Failed while trying to get blockchain state")
}
t.Log("After transfer transaction at block 450 B and the B fork has been merged into main chain, Account 1 have balance of: ", state.GetBalance(acc1Addr))
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000888)) != 0 {
t.Fatalf("account 1 should have 10000000888 in balance")
}
}