process forensics (#84)

* process forensics

* Found common signers at same round for forensics

* find attackers

* add test for forensics

* run setCommittedQCs after processForensics
This commit is contained in:
Jerome 2022-05-03 21:18:28 +10:00 committed by GitHub
parent 5a15c45102
commit ba144d898f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 638 additions and 122 deletions

View file

@ -933,7 +933,7 @@ func (x *XDPoS_v2) commitBlocks(blockChainReader consensus.ChainReader, proposed
// Perform forensics related operation
var headerQcToBeCommitted []types.Header
headerQcToBeCommitted = append(headerQcToBeCommitted, *parentBlock, *proposedBlockHeader)
go x.forensics.SetCommittedQCs(headerQcToBeCommitted, *incomingQc)
go x.forensics.ForensicsMonitoring(blockChainReader, headerQcToBeCommitted, *incomingQc)
return true, nil
}
// Everything else, fail to commit

View file

@ -2,27 +2,29 @@ package engine_v2
import (
"fmt"
"math/big"
"reflect"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/log"
)
const (
NUM_OF_FORENSICS_PARENTS = 2
NUM_OF_FORENSICS_QC = 3
)
type ForensicProof struct {
QcWithSmallerRound utils.QuorumCert
QcWithLargerRound utils.QuorumCert
DivergingHash common.Hash
HashesTillSmallerRoundQc []common.Hash
HashesTillLargerRoundQc []common.Hash
AcrossEpochs bool
QcWithSmallerRoundAddresses []common.Address
QcWithLargerRoundAddresses []common.Address
QcWithSmallerRound utils.QuorumCert
QcWithLargerRound utils.QuorumCert
DivergingHash common.Hash
HashesTillSmallerRoundQc []common.Hash
HashesTillLargerRoundQc []common.Hash
AcrossEpochs bool
Attackers []common.Address
}
// Forensics instance. Placeholder for future properties to be added
@ -35,20 +37,15 @@ func NewForensics() *Forensics {
return &Forensics{}
}
/*
Entry point for processing forensics.
Triggered once processQC is successfully.
Forensics runs in a seperate go routine as its no system critical
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
*/
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, incomingQC utils.QuorumCert) {
log.Info("Received a QC in forensics", "QC", incomingQC)
func (f *Forensics) ForensicsMonitoring(chain consensus.ChainReader, headerQcToBeCommitted []types.Header, incomingQC utils.QuorumCert) error {
f.ProcessForensics(chain, incomingQC)
return f.SetCommittedQCs(headerQcToBeCommitted, incomingQC)
}
// Set the forensics committed QCs list. The order is from grandparent to current header. i.e it shall follow the QC in its header as follow [hcqc1, hcqc2, hcqc3]
func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC utils.QuorumCert) error {
// highestCommitQCs is an array, assign the parentBlockQc and its child as well as its grandchild QC into this array for forensics purposes.
if len(headers) != NUM_OF_FORENSICS_PARENTS {
if len(headers) != NUM_OF_FORENSICS_QC-1 {
log.Error("[SetCommittedQcs] Received input length not equal to 2", len(headers))
return fmt.Errorf("Received headers length not equal to 2 ")
}
@ -80,13 +77,197 @@ func (f *Forensics) SetCommittedQCs(headers []types.Header, incomingQC utils.Quo
return nil
}
/*
Entry point for processing forensics.
Triggered once processQC is successfully.
Forensics runs in a seperate go routine as its no system critical
Link to the flow diagram: https://hashlabs.atlassian.net/wiki/spaces/HASHLABS/pages/97878029/Forensics+Diagram+flow
*/
func (f *Forensics) ProcessForensics(chain consensus.ChainReader, incomingQC utils.QuorumCert) error {
log.Debug("Received a QC in forensics", "QC", incomingQC)
// Clone the values to a temporary variable
highestCommittedQCs := f.HighestCommittedQCs
if len(highestCommittedQCs) != NUM_OF_FORENSICS_QC {
log.Error("[ProcessForensics] HighestCommittedQCs value not set", "incomingQcProposedBlockHash", incomingQC.ProposedBlockInfo.Hash, "incomingQcProposedBlockNumber", incomingQC.ProposedBlockInfo.Number.Uint64(), "incomingQcProposedBlockRound", incomingQC.ProposedBlockInfo.Round)
return fmt.Errorf("HighestCommittedQCs value not set")
}
// Find the QC1 and QC2. We only care 2 parents in front of the incomingQC. The returned value contains QC1, QC2 and QC3(the incomingQC)
incomingQuorunCerts, err := f.findAncestorQCs(chain, incomingQC, 2)
if err != nil {
return err
}
isOnTheChain, err := f.checkQCsOnTheSameChain(chain, highestCommittedQCs, incomingQuorunCerts)
if err != nil {
return err
}
if isOnTheChain {
// Passed the checking, nothing suspecious.
log.Debug("[ProcessForensics] Passed forensics checking, nothing suspecious need to be reported", "incomingQcProposedBlockHash", incomingQC.ProposedBlockInfo.Hash, "incomingQcProposedBlockNumber", incomingQC.ProposedBlockInfo.Number.Uint64(), "incomingQcProposedBlockRound", incomingQC.ProposedBlockInfo.Round)
return nil
}
// Trigger the safety Alarm if failed
// First, find the QC in the two sets that have the same round
foundSameRoundQC, sameRoundHCQC, sameRoundQC := f.findQCsInSameRound(highestCommittedQCs, incomingQuorunCerts)
if foundSameRoundQC {
attackersAddress := f.findCommonSigners(sameRoundHCQC, sameRoundQC)
f.SendForensicProof(attackersAddress, sameRoundHCQC, sameRoundQC)
} else {
// Not found, need a more complex approach to find the two QC
ancestorQC, lowerRoundQCs, _, err := f.findAncestorQcThroughRound(chain, highestCommittedQCs, incomingQuorunCerts)
if err != nil {
log.Error("[ProcessForensics] Error while trying to find ancestor QC through round number", "Error", err)
}
// Find the common signers within ancestorQC and lowerRoundQCs[NUM_OF_FORENSICS_QC-1]
attackersAddress := f.findCommonSigners(ancestorQC, lowerRoundQCs[NUM_OF_FORENSICS_QC-1])
f.SendForensicProof(attackersAddress, ancestorQC, lowerRoundQCs[NUM_OF_FORENSICS_QC-1])
}
return nil
}
// Last step of forensics which sends out detailed proof to report service.
func (f *Forensics) SendForensicProof() {
func (f *Forensics) SendForensicProof(attackersAddress []common.Address, lqc utils.QuorumCert, hqc utils.QuorumCert) {
}
// Find the blockInfo of the block -2 distance away from the QC. Note: We using block number which means not necessary on the same chain as QC received
func (f *Forensics) findParentsQc(chain consensus.ChainReader, currentQc utils.QuorumCert, distanceFromCurrrentQc int64) {
// Utils function to help find the n-th previous QC. It returns an array of QC in ascending order including the currentQc as the last item in the array
func (f *Forensics) findAncestorQCs(chain consensus.ChainReader, currentQc utils.QuorumCert, distanceFromCurrrentQc int) ([]utils.QuorumCert, error) {
var quorumCerts []utils.QuorumCert
quorumCertificate := currentQc
// Append the initial value
quorumCerts = append(quorumCerts, quorumCertificate)
// Append the parents
for i := 0; i < distanceFromCurrrentQc; i++ {
parentHash := quorumCertificate.ProposedBlockInfo.Hash
parentHeader := chain.GetHeaderByHash(parentHash)
if parentHeader == nil {
log.Error("[findAncestorQCs] Forensics findAncestorQCs unable to find its parent block header", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
return nil, fmt.Errorf("Unable to find parent block header in forensics")
}
var decodedExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
if err != nil {
log.Error("[findAncestorQCs] Error while trying to decode from parent block extra", "BlockNum", parentHeader.Number.Int64(), "ParentHash", parentHash.Hex())
}
quorumCertificate = *decodedExtraField.QuorumCert
quorumCerts = append(quorumCerts, quorumCertificate)
}
// The quorumCerts is in the reverse order, we need to flip it
var quorumCertsInAscendingOrder []utils.QuorumCert
for i := len(quorumCerts) - 1; i >= 0; i-- {
quorumCertsInAscendingOrder = append(quorumCertsInAscendingOrder, quorumCerts[i])
}
return quorumCertsInAscendingOrder, nil
}
func (f *Forensics) findCommonSigners(currentQc utils.QuorumCert, higherQc utils.QuorumCert) {
// Check whether two provided QC set are on the same chain
func (f *Forensics) checkQCsOnTheSameChain(chain consensus.ChainReader, highestCommittedQCs []utils.QuorumCert, incomingQCandItsParents []utils.QuorumCert) (bool, error) {
// Re-order two sets of QCs by block Number
lowerBlockNumQCs := highestCommittedQCs
higherBlockNumQCs := incomingQCandItsParents
if incomingQCandItsParents[0].ProposedBlockInfo.Number.Cmp(highestCommittedQCs[0].ProposedBlockInfo.Number) == -1 {
lowerBlockNumQCs = incomingQCandItsParents
higherBlockNumQCs = highestCommittedQCs
}
proposedBlockInfo := higherBlockNumQCs[0].ProposedBlockInfo
for i := 0; i < int((big.NewInt(0).Sub(higherBlockNumQCs[0].ProposedBlockInfo.Number, lowerBlockNumQCs[0].ProposedBlockInfo.Number)).Int64()); i++ {
parentHeader := chain.GetHeaderByHash(proposedBlockInfo.Hash)
var decodedExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(parentHeader.Extra, &decodedExtraField)
if err != nil {
log.Error("[ProcessForensics] Fail to decode extra when checking the two QCs set on the same chain", "Error", err)
return false, err
}
proposedBlockInfo = decodedExtraField.QuorumCert.ProposedBlockInfo
}
// Check the final proposed blockInfo is the same as what we have from lowerBlockNumQCs[0]
if reflect.DeepEqual(proposedBlockInfo, lowerBlockNumQCs[0].ProposedBlockInfo) {
return true, nil
}
return false, nil
}
// Given the two QCs set, find if there are any QC that have the same round
func (f *Forensics) findQCsInSameRound(quorumCerts1 []utils.QuorumCert, quorumCerts2 []utils.QuorumCert) (bool, utils.QuorumCert, utils.QuorumCert) {
for _, quorumCert1 := range quorumCerts1 {
for _, quorumCert2 := range quorumCerts2 {
if quorumCert1.ProposedBlockInfo.Round == quorumCert2.ProposedBlockInfo.Round {
return true, quorumCert1, quorumCert2
}
}
}
return false, utils.QuorumCert{}, utils.QuorumCert{}
}
// Find the common address that have signed both QCs
func (f *Forensics) findCommonSigners(quorumCert1 utils.QuorumCert, quorumCert2 utils.QuorumCert) []common.Address {
var commonSigners []common.Address
quorumCert1SignersMap := make(map[string]bool)
// The QC signatures are signed by votes special struct VoteForSign
quorumCert1SignedHash := utils.VoteSigHash(&utils.VoteForSign{
ProposedBlockInfo: quorumCert1.ProposedBlockInfo,
GapNumber: quorumCert1.GapNumber,
})
for _, signature := range quorumCert1.Signatures {
var signerAddress common.Address
pubkey, err := crypto.Ecrecover(quorumCert1SignedHash.Bytes(), signature)
if err != nil {
log.Error("[findCommonSigners] Fail to Ecrecover signer from the quorumCert1SignedHash", "quorumCert1.GapNumber", quorumCert1.GapNumber, "quorumCert1.ProposedBlockInfo", quorumCert1.ProposedBlockInfo)
}
copy(signerAddress[:], crypto.Keccak256(pubkey[1:])[12:])
quorumCert1SignersMap[signerAddress.Hex()] = true
}
// Now, Let's check if quorumCert2 have any signers that have in common with quorumCert1SignersMap(from quorumCert1)
quorumCert2SignedHash := utils.VoteSigHash(&utils.VoteForSign{
ProposedBlockInfo: quorumCert2.ProposedBlockInfo,
GapNumber: quorumCert2.GapNumber,
})
for _, signature := range quorumCert2.Signatures {
var signerAddress common.Address
pubkey, err := crypto.Ecrecover(quorumCert2SignedHash.Bytes(), signature)
if err != nil {
log.Error("[findCommonSigners] Fail to Ecrecover signer from the quorumCert2SignedHash", "quorumCert2.GapNumber", quorumCert2.GapNumber, "quorumCert2.ProposedBlockInfo", quorumCert2.ProposedBlockInfo)
}
copy(signerAddress[:], crypto.Keccak256(pubkey[1:])[12:])
if quorumCert1SignersMap[signerAddress.Hex()] {
commonSigners = append(commonSigners, signerAddress)
}
}
return commonSigners
}
// Check whether the given QCs are on the same chain as the stored committed QCs(f.HighestCommittedQCs) regardless their orders
func (f *Forensics) findAncestorQcThroughRound(chain consensus.ChainReader, highestCommittedQCs []utils.QuorumCert, incomingQCandItsParents []utils.QuorumCert) (utils.QuorumCert, []utils.QuorumCert, []utils.QuorumCert, error) {
/*
Re-order two sets of QCs by Round number
*/
lowerRoundQCs := highestCommittedQCs
higherRoundQCs := incomingQCandItsParents
if incomingQCandItsParents[0].ProposedBlockInfo.Round < highestCommittedQCs[0].ProposedBlockInfo.Round {
lowerRoundQCs = incomingQCandItsParents
higherRoundQCs = highestCommittedQCs
}
// Find the ancestorFromIncomingQC1 that matches round number < lowerRoundQCs3
ancestorQC := higherRoundQCs[0]
for ancestorQC.ProposedBlockInfo.Round >= lowerRoundQCs[NUM_OF_FORENSICS_QC-1].ProposedBlockInfo.Round {
proposedBlock := chain.GetHeaderByHash(ancestorQC.ProposedBlockInfo.Hash)
var decodedExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(proposedBlock.Extra, &decodedExtraField)
if err != nil {
log.Error("[findAncestorQcThroughRound] Error while trying to decode extra field", "ProposedBlockInfo.Hash", ancestorQC.ProposedBlockInfo.Hash)
return ancestorQC, lowerRoundQCs, higherRoundQCs, err
}
// Found the ancestor QC
if decodedExtraField.QuorumCert.ProposedBlockInfo.Round < lowerRoundQCs[NUM_OF_FORENSICS_QC-1].ProposedBlockInfo.Round {
return ancestorQC, lowerRoundQCs, higherRoundQCs, nil
}
ancestorQC = *decodedExtraField.QuorumCert
}
return ancestorQC, lowerRoundQCs, higherRoundQCs, fmt.Errorf("[findAncestorQcThroughRound] Could not find ancestor QC")
}

View file

@ -0,0 +1,218 @@
package engine_v2
import (
"crypto/ecdsa"
"fmt"
"io/ioutil"
"math/big"
"math/rand"
"os"
"testing"
"github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/accounts/keystore"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/stretchr/testify/assert"
)
// Utils to help mocking the signing of signatures
var (
signer1, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
signer2, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
signer3, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
)
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
func SignHashByPK(pk *ecdsa.PrivateKey, itemToSign []byte) []byte {
signer, signFn, err := getSignerAndSignFn(pk)
if err != nil {
panic(err)
}
signedHash, err := signFn(accounts.Account{Address: signer}, itemToSign)
if err != nil {
panic(err)
}
return signedHash
}
func RandStringBytes(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}
func getSignerAndSignFn(pk *ecdsa.PrivateKey) (common.Address, func(account accounts.Account, hash []byte) ([]byte, error), error) {
veryLightScryptN := 2
veryLightScryptP := 1
dir, _ := ioutil.TempDir("", fmt.Sprintf("eth-getSignerAndSignFn-test-%v", RandStringBytes(5)))
new := func(kd string) *keystore.KeyStore {
return keystore.NewKeyStore(kd, veryLightScryptN, veryLightScryptP)
}
defer os.RemoveAll(dir)
ks := new(dir)
pass := "" // not used but required by API
a1, err := ks.ImportECDSA(pk, pass)
if err != nil {
return common.Address{}, nil, fmt.Errorf(err.Error())
}
if err := ks.Unlock(a1, ""); err != nil {
return a1.Address, nil, fmt.Errorf(err.Error())
}
return a1.Address, ks.SignHash, nil
}
func TestFindCommonSigners(t *testing.T) {
forensics := &Forensics{}
proposedBlockInfo := &utils.BlockInfo{
Hash: common.StringToHash("123"),
Round: utils.Round(10),
Number: big.NewInt(910),
}
gapNumber := 450
voteForSign := &utils.VoteForSign{
ProposedBlockInfo: proposedBlockInfo,
GapNumber: uint64(gapNumber),
}
signatureFromSigner1 := SignHashByPK(signer1, utils.VoteSigHash(voteForSign).Bytes())
signatureFromSigner2 := SignHashByPK(signer2, utils.VoteSigHash(voteForSign).Bytes())
signatureFromSigner3 := SignHashByPK(signer3, utils.VoteSigHash(voteForSign).Bytes())
// If ONE in common
var signaturesForQC1 []utils.Signature
qc1 := &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC1, signatureFromSigner1, signatureFromSigner2),
GapNumber: uint64(gapNumber),
}
var signaturesForQC2 []utils.Signature
qc2 := &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC2, signatureFromSigner2, signatureFromSigner3),
GapNumber: uint64(gapNumber),
}
commonSigners := forensics.findCommonSigners(*qc1, *qc2)
assert.Equal(t, 1, len(commonSigners))
assert.Equal(t, crypto.PubkeyToAddress(signer2.PublicKey), commonSigners[0])
// If none in common
var signaturesForQC1NoneInCommon []utils.Signature
qc1 = &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC1NoneInCommon, signatureFromSigner1),
GapNumber: uint64(gapNumber),
}
var signaturesForQC2NoneInCommon []utils.Signature
qc2 = &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC2NoneInCommon, signatureFromSigner2, signatureFromSigner3),
GapNumber: uint64(gapNumber),
}
commonSigners = forensics.findCommonSigners(*qc1, *qc2)
assert.Equal(t, 0, len(commonSigners))
// All in common
var signaturesForQC1AllInCommon []utils.Signature
qc1 = &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC1AllInCommon, signatureFromSigner1, signatureFromSigner2, signatureFromSigner3),
GapNumber: uint64(gapNumber),
}
var signaturesForQC2AllInCommon []utils.Signature
qc2 = &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: append(signaturesForQC2AllInCommon, signatureFromSigner1, signatureFromSigner2, signatureFromSigner3),
GapNumber: uint64(gapNumber),
}
commonSigners = forensics.findCommonSigners(*qc1, *qc2)
assert.Equal(t, 3, len(commonSigners))
assert.Equal(t, crypto.PubkeyToAddress(signer1.PublicKey), commonSigners[0])
assert.Equal(t, crypto.PubkeyToAddress(signer2.PublicKey), commonSigners[1])
assert.Equal(t, crypto.PubkeyToAddress(signer3.PublicKey), commonSigners[2])
}
func TestFindQCsInSameRound(t *testing.T) {
forensics := &Forensics{}
gapNumber := 450
// If ONE in common
var sig []utils.Signature
qc1 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc1"),
Round: utils.Round(10),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
qc2 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc2"),
Round: utils.Round(12),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
qc3 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc3"),
Round: utils.Round(13),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
qc4 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc4"),
Round: utils.Round(12),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
qc5 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc5"),
Round: utils.Round(13),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
qc6 := &utils.QuorumCert{
ProposedBlockInfo: &utils.BlockInfo{
Hash: common.StringToHash("qc6"),
Round: utils.Round(15),
Number: big.NewInt(910),
},
Signatures: sig,
GapNumber: uint64(gapNumber),
}
var qcSet1 []utils.QuorumCert
var qcSet2 []utils.QuorumCert
found, first, second := forensics.findQCsInSameRound(append(qcSet1, *qc1, *qc2, *qc3), append(qcSet2, *qc4, *qc5, *qc6))
assert.True(t, found)
assert.Equal(t, *qc2, first)
assert.Equal(t, *qc4, second)
}

View file

@ -14,7 +14,7 @@ import (
)
func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
addressFromAdaptor, errorAdaptor := adaptor.Author(currentBlock.Header())
@ -39,7 +39,7 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
Coinbase: signer,
}
header.Extra = generateV2Extra(1, currentBlock, signer, signFn)
header.Extra = generateV2Extra(1, currentBlock, signer, signFn, nil)
block901, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, blockchain.Config())
if err != nil {
@ -61,7 +61,7 @@ func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
}
func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
headerV1 := currentBlock.Header()
headerV1.Extra = common.Hex2Bytes("d7830100018358444388676f312e31352e38856c696e757800000000000000000278c350152e15fa6ffc712a5a73d704ce73e2e103d9e17ae3ff2c6712e44e25b09ac5ee91f6c9ff065551f0dcac6f00cae11192d462db709be3758ccef312ee5eea8d7bad5374c6a652150515d744508b61c1a4deb4e4e7bf057e4e3824c11fd2569bcb77a52905cda63b5a58507910bed335e4c9d87ae0ecdfafd400")
@ -73,7 +73,7 @@ func TestAdaptorGetMasternodesFromCheckpointHeader(t *testing.T) {
assert.True(t, reflect.DeepEqual(masternodesV1, masternodesV2), "GetMasternodesFromCheckpointHeader in adaptor for v1 v2 not equal", "v1", masternodesV1, "v2", masternodesV2)
}
func TestAdaptorIsEpochSwitch(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
header := currentBlock.Header()
// v1
@ -96,7 +96,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
quorumCert := &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
extra := utils.ExtraFields_v2{
Round: 1,
@ -117,7 +117,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
extra = utils.ExtraFields_v2{
Round: 2,
@ -138,7 +138,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
extra = utils.ExtraFields_v2{
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 1,
@ -159,7 +159,7 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
quorumCert = &utils.QuorumCert{
ProposedBlockInfo: parentBlockInfo,
Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
extra = utils.ExtraFields_v2{
Round: utils.Round(blockchain.Config().XDPoS.Epoch) + 2,
@ -176,11 +176,11 @@ func TestAdaptorIsEpochSwitch(t *testing.T) {
func TestAdaptorGetMasternodesV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
// block 901 is the first v2 block, and is treated as epoch switch block
err := blockchain.InsertBlock(currentBlock)
@ -190,7 +190,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) {
masternodes1ByNumber := adaptor.GetMasternodesByNumber(blockchain, currentBlock.NumberU64())
assert.True(t, reflect.DeepEqual(masternodes1, masternodes1ByNumber), "at block number", blockNum)
for blockNum = 902; blockNum < 915; blockNum++ {
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
masternodes2 := adaptor.GetMasternodes(blockchain, currentBlock.Header())
@ -201,7 +201,7 @@ func TestAdaptorGetMasternodesV2(t *testing.T) {
}
func TestGetCurrentEpochSwitchBlock(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// V1
@ -213,7 +213,7 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) {
// V2
blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
currentCheckpointNumber, epochNum, err = adaptor.GetCurrentEpochSwitchBlock(blockchain, currentBlock.Number())
@ -222,7 +222,7 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) {
assert.Equal(t, uint64(1), epochNum)
for blockNum = 902; blockNum < 915; blockNum++ {
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
@ -234,7 +234,7 @@ func TestGetCurrentEpochSwitchBlock(t *testing.T) {
}
func TestGetParentBlock(t *testing.T) {
blockchain, _, block900, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, block900, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// V1
@ -248,13 +248,13 @@ func TestGetParentBlock(t *testing.T) {
// V2
blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123"
block901 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block900, blockNum, 1, blockCoinBase, signer, signFn, nil)
block901 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block900, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block901)
assert.Nil(t, err)
// let's inject another one, but the highestedQC has not been updated, so it shall still point to 900
blockNum = 902
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil)
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block901, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block902)
assert.Nil(t, err)
block = adaptor.FindParentBlockToAssign(blockchain, block902)

View file

@ -12,11 +12,11 @@ import (
func TestIsAuthorisedMNForConsensusV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
err := blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
// As long as the address is in the master node list, they are all valid
@ -32,12 +32,12 @@ func TestIsAuthorisedMNForConsensusV2(t *testing.T) {
func TestIsYourTurnConsensusV2(t *testing.T) {
// we skip test for v1 since it's hard to make a real genesis block
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
minePeriod := params.TestXDPoSV2Config.MinePeriod
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockNum := 901
blockCoinBase := "0x111000000000000000000000000000000123"
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 1, blockCoinBase, signer, signFn, nil, nil)
err := blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
// Less then Mine Period
@ -61,7 +61,7 @@ func TestIsYourTurnConsensusV2(t *testing.T) {
// We continue to grow the chain which will increase the round number
blockNum = 902
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
time.Sleep(time.Duration(minePeriod) * time.Second)

View file

@ -1,6 +1,7 @@
package engine_v2_tests
import (
"crypto/ecdsa"
"math/big"
"testing"
"time"
@ -15,7 +16,7 @@ import (
)
func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Assuming we are getting block 906 which have QC pointing at block 905
@ -81,7 +82,7 @@ func TestProcessQcShallSetForensicsCommittedQc(t *testing.T) {
}
func TestSetCommittedQCsInOrder(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
var headers []types.Header
@ -96,4 +97,100 @@ func TestSetCommittedQCsInOrder(t *testing.T) {
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(904)), *decodedExtraField.QuorumCert)
assert.Nil(t, err)
assert.Equal(t, 3, len(forensics.HighestCommittedQCs))
// Test previous blocks
err = utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(904).Extra, &decodedExtraField)
assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(902), *blockchain.GetHeaderByNumber(903)), *decodedExtraField.QuorumCert)
assert.Nil(t, err)
assert.Equal(t, 3, len(forensics.HighestCommittedQCs))
}
// Happty path
func TestForensicsMonitoring(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
var decodedCurrentblockExtraField utils.ExtraFields_v2
// Decode the QC from latest block
err := utils.DecodeBytesExtraFields(currentBlock.Header().Extra, &decodedCurrentblockExtraField)
assert.Nil(t, err)
incomingQC := decodedCurrentblockExtraField.QuorumCert
// Now, let's try set committed blocks, where the highestedCommitted blocks are 905, 906 and 907
var headers []types.Header
var decodedBlock905ExtraField utils.ExtraFields_v2
err = utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(905).Extra, &decodedBlock905ExtraField)
assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(903), *blockchain.GetHeaderByNumber(904)), *decodedBlock905ExtraField.QuorumCert)
assert.Nil(t, err)
var newIncomingQcHeaders []types.Header
newIncomingQcHeaders = append(newIncomingQcHeaders, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914))
err = forensics.ForensicsMonitoring(blockchain, newIncomingQcHeaders, *incomingQC)
assert.Nil(t, err)
}
func TestForensicsMonitoringNotOnSameChainButHaveSameRoundQC(t *testing.T) {
var numOfForks = new(int)
*numOfForks = 10
var forkRoundDifference = new(int)
*forkRoundDifference = 1
blockchain, _, _, _, _, currentForkBlock := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks, forkedRoundDifference: forkRoundDifference})
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
// Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915
var headers []types.Header
var decodedBlock915ExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
assert.Nil(t, err)
var decodedExtraField utils.ExtraFields_v2
// Decode the QC from forking chain
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
assert.Nil(t, err)
incomingQC := decodedExtraField.QuorumCert
var forkedHeaders []types.Header
parentOfForkedHeader := blockchain.GetBlockByHash(currentForkBlock.ParentHash()).Header()
grandParentOfForkedHeader := blockchain.GetBlockByHash(parentOfForkedHeader.ParentHash).Header()
forkedHeaders = append(forkedHeaders, *grandParentOfForkedHeader, *parentOfForkedHeader)
err = forensics.ForensicsMonitoring(blockchain, forkedHeaders, *incomingQC)
assert.Nil(t, err)
// TODO: Check SendForensicProof triggered
}
func TestForensicsMonitoringNotOnSameChainDoNotHaveSameRoundQC(t *testing.T) {
var numOfForks = new(int)
*numOfForks = 10
var forkRoundDifference = new(int)
*forkRoundDifference = 10
var forkedChainSignersKey []*ecdsa.PrivateKey
forkedChainSignersKey = append(forkedChainSignersKey, acc1Key)
blockchain, _, _, _, _, currentForkBlock := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks, forkedRoundDifference: forkRoundDifference, signersKey: forkedChainSignersKey})
forensics := blockchain.Engine().(*XDPoS.XDPoS).EngineV2.GetForensicsFaker()
// Now, let's try set committed blocks, where the highestedCommitted blocks are 913, 914 and 915
var headers []types.Header
var decodedBlock915ExtraField utils.ExtraFields_v2
err := utils.DecodeBytesExtraFields(blockchain.GetHeaderByNumber(915).Extra, &decodedBlock915ExtraField)
assert.Nil(t, err)
err = forensics.SetCommittedQCs(append(headers, *blockchain.GetHeaderByNumber(913), *blockchain.GetHeaderByNumber(914)), *decodedBlock915ExtraField.QuorumCert)
assert.Nil(t, err)
var decodedExtraField utils.ExtraFields_v2
// Decode the QC from forking chain
err = utils.DecodeBytesExtraFields(currentForkBlock.Header().Extra, &decodedExtraField)
assert.Nil(t, err)
incomingQC := decodedExtraField.QuorumCert
var forkedHeaders []types.Header
parentOfForkedHeader := blockchain.GetBlockByHash(currentForkBlock.ParentHash()).Header()
grandParentOfForkedHeader := blockchain.GetBlockByHash(parentOfForkedHeader.ParentHash).Header()
forkedHeaders = append(forkedHeaders, *grandParentOfForkedHeader, *parentOfForkedHeader)
err = forensics.ForensicsMonitoring(blockchain, forkedHeaders, *incomingQC)
assert.Nil(t, err)
// TODO: Check SendForensicProof triggered
}

View file

@ -272,8 +272,14 @@ func GetCandidateFromCurrentSmartContract(backend bind.ContractBackend, t *testi
return ms
}
type ForkedBlockOptions struct {
numOfForkedBlocks *int
forkedRoundDifference *int // Minimum is 1
signersKey []*ecdsa.PrivateKey
}
// V2 concensus engine
func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, numOfForkedBlocks int) (*BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error), *types.Block) {
func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig, forkedBlockOptions *ForkedBlockOptions) (*BlockChain, *backends.SimulatedBackend, *types.Block, common.Address, func(account accounts.Account, hash []byte) ([]byte, error), *types.Block) {
// Preparation
var err error
signer, signFn, err := backends.SimulateWalletAddressAndSignFn()
@ -308,22 +314,29 @@ func PrepareXDCTestBlockChainForV2Engine(t *testing.T, numOfBlocks int, chainCon
blockCoinBase = signer.Hex()
}
roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64()
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, nil)
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block)
if err != nil {
t.Fatal(err)
}
// Produce forked block for the last numOfForkedBlocks'th blocks
if numOfForkedBlocks != 0 && i > numOfBlocks-numOfForkedBlocks {
if forkedBlockOptions != nil && forkedBlockOptions.numOfForkedBlocks != nil && i > numOfBlocks-*forkedBlockOptions.numOfForkedBlocks {
if currentForkBlock == nil {
currentForkBlock = currentBlock
}
forkedBlockCoinBase := fmt.Sprintf("0x222000000000000000000000000000000%03d", i)
var forkedBlockRoundNumber int64
if forkedBlockOptions.forkedRoundDifference != nil {
if *forkedBlockOptions.forkedRoundDifference == 0 {
t.Fatal("forkedRoundDifference minimum is 1")
}
forkedBlockRoundNumber = roundNumber + int64(*forkedBlockOptions.forkedRoundDifference)
} else {
forkedBlockRoundNumber = roundNumber + int64(*forkedBlockOptions.numOfForkedBlocks)
}
forkedBlockRoundNumber := roundNumber + int64(numOfForkedBlocks)
forkedBlock := CreateBlock(blockchain, chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn, nil)
forkedBlock := CreateBlock(blockchain, chainConfig, currentForkBlock, i, forkedBlockRoundNumber, forkedBlockCoinBase, signer, signFn, nil, forkedBlockOptions.signersKey)
err = blockchain.InsertBlock(forkedBlock)
if err != nil {
@ -388,7 +401,7 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in
}
roundNumber := int64(i) - chainConfig.XDPoS.V2.SwitchBlock.Int64()
// use signer itself as penalty
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, signer[:])
block := CreateBlock(blockchain, chainConfig, currentBlock, i, roundNumber, blockCoinBase, signer, signFn, signer[:], nil)
err = blockchain.InsertBlock(block)
if err != nil {
@ -406,13 +419,13 @@ func PrepareXDCTestBlockChainWithPenaltyForV2Engine(t *testing.T, numOfBlocks in
return blockchain, backend, currentBlock, signer, signFn
}
func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), penalties []byte) *types.Block {
func CreateBlock(blockchain *BlockChain, chainConfig *params.ChainConfig, startingBlock *types.Block, blockNumber int, roundNumber int64, blockCoinBase string, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), penalties []byte, signersKey []*ecdsa.PrivateKey) *types.Block {
currentBlock := startingBlock
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
var header *types.Header
if big.NewInt(int64(blockNumber)).Cmp(chainConfig.XDPoS.V2.SwitchBlock) == 1 { // Build engine v2 compatible extra data field
extraInBytes := generateV2Extra(roundNumber, currentBlock, signer, signFn)
extraInBytes := generateV2Extra(roundNumber, currentBlock, signer, signFn, signersKey)
header = &types.Header{
Root: common.HexToHash(merkleRoot),
@ -618,7 +631,7 @@ func getMasternodesList(signer common.Address) []common.Address {
return masternodes
}
func generateV2Extra(roundNumber int64, currentBlock *types.Block, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error)) []byte {
func generateV2Extra(roundNumber int64, currentBlock *types.Block, signer common.Address, signFn func(account accounts.Account, hash []byte) ([]byte, error), accKeys []*ecdsa.PrivateKey) []byte {
var extraField utils.ExtraFields_v2
var round utils.Round
err := utils.DecodeBytesExtraFields(currentBlock.Extra(), &extraField)
@ -643,12 +656,17 @@ func generateV2Extra(roundNumber int64, currentBlock *types.Block, signer common
if err != nil {
panic(fmt.Errorf("Error generate QC by creating signedHash: %v", err))
}
// Sign from acc 1, 2, 3
acc1SignedHash := SignHashByPK(acc1Key, utils.VoteSigHash(voteForSign).Bytes())
acc2SignedHash := SignHashByPK(acc2Key, utils.VoteSigHash(voteForSign).Bytes())
acc3SignedHash := SignHashByPK(acc3Key, utils.VoteSigHash(voteForSign).Bytes())
var signatures []utils.Signature
signatures = append(signatures, acc1SignedHash, acc2SignedHash, acc3SignedHash, signedHash)
if len(accKeys) == 0 {
// Sign from acc 1, 2, 3 by default
accKeys = append(accKeys, acc1Key, acc2Key, acc3Key)
}
for _, acc := range accKeys {
h := SignHashByPK(acc, utils.VoteSigHash(voteForSign).Bytes())
signatures = append(signatures, h)
}
signatures = append(signatures, signedHash)
quorumCert := &utils.QuorumCert{
ProposedBlockInfo: proposedBlockInfo,
Signatures: signatures,

View file

@ -13,7 +13,7 @@ import (
)
func TestInitialFirstV2Blcok(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
header := currentBlock.Header()
@ -33,7 +33,7 @@ func TestInitialFirstV2Blcok(t *testing.T) {
expectedQuorumCert := &utils.QuorumCert{
ProposedBlockInfo: blockInfo,
Signatures: nil,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
assert.Equal(t, utils.Round(1), round)
assert.Equal(t, expectedQuorumCert, highQC)
@ -55,12 +55,12 @@ func TestInitialFirstV2Blcok(t *testing.T) {
func TestInitialOtherV2Block(t *testing.T) {
// insert new block with new extra fields
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 900, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
blockCoinBase := "0x111000000000000000000000000000000123"
for blockNum := 901; blockNum <= 910; blockNum++ {
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil)
currentBlock = CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, int64(blockNum-900), blockCoinBase, signer, signFn, nil, nil)
err := blockchain.InsertBlock(currentBlock)
assert.Nil(t, err)
}
@ -74,7 +74,7 @@ func TestInitialOtherV2Block(t *testing.T) {
quorumCert := &utils.QuorumCert{
ProposedBlockInfo: blockInfo,
Signatures: nil, // after decode it got default value []utils.Signature{}
GapNumber: 450,
GapNumber: 450,
}
extra := utils.ExtraFields_v2{
Round: 11,
@ -105,7 +105,7 @@ func TestInitialOtherV2Block(t *testing.T) {
expectedQuorumCert := &utils.QuorumCert{
ProposedBlockInfo: blockInfo,
Signatures: []utils.Signature{},
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64()-blockchain.Config().XDPoS.Gap,
GapNumber: blockchain.Config().XDPoS.V2.SwitchBlock.Uint64() - blockchain.Config().XDPoS.Gap,
}
assert.Equal(t, utils.Round(11), round)
assert.Equal(t, expectedQuorumCert, highQC)
@ -118,7 +118,7 @@ func TestInitialOtherV2Block(t *testing.T) {
func TestSnapshotShouldAlreadyCreatedByUpdateM1(t *testing.T) {
// insert new block with new extra fields
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1800, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 1800, params.TestXDPoSMockChainConfig, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
snap, err := adaptor.EngineV2.GetSnapshot(blockchain, currentBlock.Header())

View file

@ -17,7 +17,7 @@ import (
func TestYourTurnInitialV2(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, parentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)-1, config, 0)
blockchain, _, parentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)-1, config, nil)
minePeriod := config.XDPoS.V2.MinePeriod
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
@ -62,7 +62,7 @@ func TestYourTurnInitialV2(t *testing.T) {
func TestShouldMineOncePerRound(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, block910, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, config, 0)
blockchain, _, block910, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
minePeriod := config.XDPoS.V2.MinePeriod
@ -77,7 +77,7 @@ func TestShouldMineOncePerRound(t *testing.T) {
func TestUpdateMasterNodes(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch+config.XDPoS.Gap)-1, config, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch+config.XDPoS.Gap)-1, config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
x := adaptor.EngineV2
snap, err := x.GetSnapshot(blockchain, currentBlock.Header())
@ -102,7 +102,7 @@ func TestUpdateMasterNodes(t *testing.T) {
Coinbase: common.HexToAddress(blockCoinbaseA),
}
header.Extra = generateV2Extra(450, currentBlock, signer, signFn)
header.Extra = generateV2Extra(450, currentBlock, signer, signFn, nil)
parentBlock, err := createBlockFromHeader(blockchain, header, []*types.Transaction{tx}, signer, signFn, config)
assert.Nil(t, err)
@ -122,7 +122,7 @@ func TestUpdateMasterNodes(t *testing.T) {
Coinbase: common.HexToAddress(blockCoinbase),
}
header.Extra = generateV2Extra(int64(i), currentBlock, signer, signFn)
header.Extra = generateV2Extra(int64(i), currentBlock, signer, signFn, nil)
block, err := createBlockFromHeader(blockchain, header, nil, signer, signFn, config)
if err != nil {
@ -142,7 +142,7 @@ func TestUpdateMasterNodes(t *testing.T) {
func TestPrepareFail(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, 0)
blockchain, _, currentBlock, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
tstamp := time.Now().Unix()
@ -185,7 +185,7 @@ func TestPrepareFail(t *testing.T) {
func TestPrepareHappyPath(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, currentBlock, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, 0)
blockchain, _, currentBlock, signer, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch), config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// trigger initial
_, err := adaptor.YourTurn(blockchain, currentBlock.Header(), signer)

View file

@ -15,7 +15,7 @@ import (
func TestHookPenaltyV2Mining(t *testing.T) {
config := params.TestXDPoSMockChainConfig
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*7, config, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*7, config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, config)
assert.NotNil(t, adaptor.EngineV2.HookPenalty)

View file

@ -14,7 +14,7 @@ import (
func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2
@ -44,7 +44,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert another Block, but it won't trigger commit
blockNum := 902
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil)
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block902)
assert.Nil(t, err)
err = engineV2.ProposedBlockHandler(blockchain, block902.Header())
@ -62,7 +62,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert one more Block, but still won't trigger commit
blockNum = 903
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block903 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block902, blockNum, 3, blockCoinBase, signer, signFn, nil)
block903 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block902, blockNum, 3, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block903)
assert.Nil(t, err)
err = engineV2.ProposedBlockHandler(blockchain, block903.Header())
@ -81,7 +81,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
// Insert one more Block, this time will trigger commit
blockNum = 904
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block904 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block903, blockNum, 4, blockCoinBase, signer, signFn, nil)
block904 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block903, blockNum, 4, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block904)
assert.Nil(t, err)
err = engineV2.ProposedBlockHandler(blockchain, block904.Header())
@ -102,7 +102,7 @@ func TestShouldSendVoteMsgAndCommitGrandGrandParentBlock(t *testing.T) {
func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
// Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2
@ -133,7 +133,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
// Injecting new block which have gaps in the round number (Round 7 instead of 6)
blockNum := 906
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block906 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 7, blockCoinBase, signer, signFn, nil)
block906 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 7, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block906)
assert.Nil(t, err)
err = engineV2.ProposedBlockHandler(blockchain, block906.Header())
@ -155,7 +155,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
blockNum = 907
blockCoinBase = fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block907 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block906, blockNum, 8, blockCoinBase, signer, signFn, nil)
block907 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, block906, blockNum, 8, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block907)
assert.Nil(t, err)
err = engineV2.ProposedBlockHandler(blockchain, block907.Header())
@ -177,7 +177,7 @@ func TestShouldNotCommitIfRoundsNotContinousFor3Rounds(t *testing.T) {
}
func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5
@ -207,7 +207,7 @@ func TestProposedBlockMessageHandlerSuccessfullyGenerateVote(t *testing.T) {
// Should not set new round if proposedBlockInfo round is less than currentRound.
// NOTE: This shall not even happen because we have `verifyQC` before being passed into ProposedBlockHandler
func TestShouldNotSetNewRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 6
@ -231,7 +231,7 @@ func TestShouldNotSetNewRound(t *testing.T) {
}
func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 5
@ -269,7 +269,7 @@ func TestShouldNotSendVoteMessageIfAlreadyVoteForThisRound(t *testing.T) {
}
func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set current round to 8
@ -303,7 +303,9 @@ func TestShouldNotSendVoteMsgIfBlockInfoRoundNotEqualCurrentRound(t *testing.T)
*/
func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
// Block number 905, 906 have forks and forkedBlock is the 906th
blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 3)
var numOfForks = new(int)
*numOfForks = 3
blockchain, _, currentBlock, _, _, forkedBlock := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, &ForkedBlockOptions{numOfForkedBlocks: numOfForks})
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2
@ -340,7 +342,7 @@ func TestShouldNotSendVoteMsgIfBlockNotExtendedFromAncestor(t *testing.T) {
func TestShouldSendVoteMsg(t *testing.T) {
// Block number 15, 16 have forks and forkedBlock is the 16th
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 903, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 903, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Block 901 is first v2 block
@ -358,7 +360,7 @@ func TestShouldSendVoteMsg(t *testing.T) {
}
func TestProposedBlockMessageHandlerNotGenerateVoteIfSignerNotInMNlist(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 906, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
differentSigner, differentSignFn, err := backends.SimulateWalletAddressAndSignFn()
assert.Nil(t, err)

View file

@ -25,7 +25,7 @@ func TestHookRewardV2(t *testing.T) {
// set switch to 1800, so that it covers 901-1799, 1800-2700 two epochs
config.XDPoS.V2.SwitchBlock.SetUint64(1800)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*5, &config, 0)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*5, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, &config)
@ -106,7 +106,7 @@ func TestHookRewardV2SplitReward(t *testing.T) {
// set switch to 1800, so that it covers 901-1799, 1800-2700 two epochs
config.XDPoS.V2.SwitchBlock.SetUint64(1800)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*3, &config, 0)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, int(config.XDPoS.Epoch)*3, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
hooks.AttachConsensusV2Hooks(adaptor, blockchain, &config)

View file

@ -12,7 +12,7 @@ import (
func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
// Block 901 is the first v2 block with starting round of 0
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2
@ -43,7 +43,7 @@ func TestSyncInfoShouldSuccessfullyUpdateByQC(t *testing.T) {
func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
// Block 901 is the first v2 block with starting round of 0
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
var extraField utils.ExtraFields_v2
@ -72,7 +72,7 @@ func TestSyncInfoShouldSuccessfullyUpdateByTC(t *testing.T) {
}
func TestSkipVerifySyncInfoIfBothQcTcNotQualified(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Make the Highest QC in syncInfo point to an old block to simulate it's no longer qualified

View file

@ -16,7 +16,7 @@ import (
)
func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
timeoutMsg := <-engineV2.BroadcastCh
@ -28,7 +28,7 @@ func TestCountdownTimeoutToSendTimeoutMessage(t *testing.T) {
}
func TestCountdownTimeoutNotToSendTimeoutMessageIfNotInMasternodeList(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
differentSigner, differentSignFn, err := backends.SimulateWalletAddressAndSignFn()
@ -46,7 +46,7 @@ func TestCountdownTimeoutNotToSendTimeoutMessageIfNotInMasternodeList(t *testing
}
func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
engineV2.SetNewRoundFaker(blockchain, 1, true)
@ -85,7 +85,7 @@ func TestSyncInfoAfterReachTimeoutSnycThreadhold(t *testing.T) {
// Timeout handler
func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 1
@ -153,7 +153,7 @@ func TestTimeoutMessageHandlerSuccessfullyGenerateTCandSyncInfo(t *testing.T) {
}
func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 11, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 3
@ -177,7 +177,7 @@ func TestThrowErrorIfTimeoutMsgRoundNotEqualToCurrentRound(t *testing.T) {
}
func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
signedHash, err := signFn(accounts.Account{Address: signer}, utils.TimeoutSigHash(&utils.TimeoutForSign{
@ -212,7 +212,7 @@ func TestShouldVerifyTimeoutMessageForFirstV2Block(t *testing.T) {
}
func TestShouldVerifyTimeoutMessage(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 2251, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
signedHash := SignHashByPK(acc1Key, utils.TimeoutSigHash(&utils.TimeoutForSign{
@ -231,7 +231,7 @@ func TestShouldVerifyTimeoutMessage(t *testing.T) {
}
func TestTimeoutPoolKeeyGoodHygiene(t *testing.T) {
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5

View file

@ -12,7 +12,7 @@ import (
func TestShouldVerifyBlockInfo(t *testing.T) {
// Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -26,7 +26,7 @@ func TestShouldVerifyBlockInfo(t *testing.T) {
// Insert another Block, but it won't trigger commit
blockNum := 902
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil)
block902 := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 2, blockCoinBase, signer, signFn, nil, nil)
err = blockchain.InsertBlock(block902)
assert.Nil(t, err)

View file

@ -30,7 +30,7 @@ func TestShouldVerifyBlock(t *testing.T) {
// Skip the mining time validation by set mine time to 0
config.XDPoS.V2.MinePeriod = 0
// Block 901 is the first v2 block with round of 1
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, 0)
blockchain, _, _, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// Happy path
@ -177,7 +177,7 @@ func TestShouldFailIfNotEnoughQCSignatures(t *testing.T) {
// Skip the mining time validation by set mine time to 0
config.XDPoS.V2.MinePeriod = 0
// Block 901 is the first v2 block with round of 1
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 902, &config, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 902, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
parentBlock := blockchain.GetBlockByNumber(901)
@ -230,7 +230,7 @@ func TestShouldVerifyHeaders(t *testing.T) {
// Skip the mining time validation by set mine time to 0
config.XDPoS.V2.MinePeriod = 0
// Block 901 is the first v2 block with round of 1
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
// Happy path
@ -271,7 +271,7 @@ func TestShouldVerifyHeadersEvenIfParentsNotYetWrittenIntoDB(t *testing.T) {
// Skip the mining time validation by set mine time to 0
config.XDPoS.V2.MinePeriod = 0
// Block 901 is the first v2 block with round of 1
blockchain, _, block910, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, 0)
blockchain, _, block910, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 910, &config, nil)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
var headersTobeVerified []*types.Header
@ -279,12 +279,12 @@ func TestShouldVerifyHeadersEvenIfParentsNotYetWrittenIntoDB(t *testing.T) {
// Create block 911 but don't write into DB
blockNumber := 911
roundNumber := int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64()
block911 := CreateBlock(blockchain, &config, block910, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil)
block911 := CreateBlock(blockchain, &config, block910, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil)
// Create block 912 and not write into DB as well
blockNumber = 912
roundNumber = int64(blockNumber) - config.XDPoS.V2.SwitchBlock.Int64()
block912 := CreateBlock(blockchain, &config, block911, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil)
block912 := CreateBlock(blockchain, &config, block911, blockNumber, roundNumber, signer.Hex(), signer, signFn, nil, nil)
headersTobeVerified = append(headersTobeVerified, block910.Header(), block911.Header(), block912.Header())
// Randomly set full verify

View file

@ -19,7 +19,7 @@ import (
// VoteHandler
func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 901, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -88,7 +88,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQCForFistV2Round(t *te
}
func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -176,7 +176,7 @@ func TestVoteMessageHandlerSuccessfullyGeneratedAndProcessQC(t *testing.T) {
}
func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testing.T) {
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, _, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -211,7 +211,7 @@ func TestThrowErrorIfVoteMsgRoundIsMoreThanOneRoundAwayFromCurrentRound(t *testi
}
func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5
@ -331,13 +331,13 @@ func TestProcessVoteMsgThenTimeoutMsg(t *testing.T) {
}
func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Create a new block but don't inject it into the chain yet
blockNum := 906
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", blockNum)
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil)
block := CreateBlock(blockchain, params.TestXDPoSMockChainConfig, currentBlock, blockNum, 6, blockCoinBase, signer, signFn, nil, nil)
blockInfo := &utils.BlockInfo{
Hash: block.Header().Hash(),
@ -411,7 +411,7 @@ func TestVoteMessageShallNotThrowErrorIfBlockNotYetExist(t *testing.T) {
}
func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, _, _, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
// Set round to 5
@ -467,7 +467,7 @@ func TestProcessVoteMsgFailIfVerifyBlockInfoFail(t *testing.T) {
}
func TestVerifyVoteMsg(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 915, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -511,7 +511,7 @@ func TestVerifyVoteMsg(t *testing.T) {
}
func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{
@ -562,7 +562,7 @@ func TestVoteMessageHandlerWrongGapNumber(t *testing.T) {
}
func TestVotePoolKeepGoodHygiene(t *testing.T) {
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, 0)
blockchain, _, currentBlock, signer, signFn, _ := PrepareXDCTestBlockChainForV2Engine(t, 905, params.TestXDPoSMockChainConfig, nil)
engineV2 := blockchain.Engine().(*XDPoS.XDPoS).EngineV2
blockInfo := &utils.BlockInfo{