Add 1 test for adaptor to switch from v1 to v2

This commit is contained in:
Jianrong 2021-10-16 23:35:51 +11:00
parent c8ee8e1936
commit 0eb2504db3
21 changed files with 679 additions and 31032 deletions

View file

@ -70,18 +70,18 @@ type SimulatedBackend struct {
} }
// XDC simulated backend for testing purpose. // XDC simulated backend for testing purpose.
func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend { func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64, chainConfig *params.ChainConfig) *SimulatedBackend {
// database := ethdb.NewMemDatabase() // database := ethdb.NewMemDatabase()
database := rawdb.NewMemoryDatabase() database := rawdb.NewMemoryDatabase()
genesis := core.Genesis{ genesis := core.Genesis{
GasLimit: gasLimit, // need this big, support initial smart contract GasLimit: gasLimit, // need this big, support initial smart contract
Config: params.TestXDPoSMockChainConfig, Config: chainConfig,
Alloc: alloc, Alloc: alloc,
ExtraData: append(make([]byte, 32), make([]byte, 65)...), ExtraData: append(make([]byte, 32), make([]byte, 65)...),
} }
genesis.MustCommit(database) genesis.MustCommit(database)
consensus := XDPoS.NewFaker(database) consensus := XDPoS.NewFaker(database, chainConfig)
// Attach mock trading and lending service // Attach mock trading and lending service
var DefaultConfig = XDCx.Config{ var DefaultConfig = XDCx.Config{

View file

@ -27,6 +27,7 @@ import (
"testing" "testing"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/params"
"golang.org/x/tools/imports" "golang.org/x/tools/imports"
) )
@ -229,7 +230,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy an interaction tester contract and call a transaction on it // Deploy an interaction tester contract and call a transaction on it
_, _, interactor, err := DeployInteractor(auth, sim, "Deploy string") _, _, interactor, err := DeployInteractor(auth, sim, "Deploy string")
@ -270,7 +271,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a tuple tester contract and execute a structured call on it // Deploy a tuple tester contract and execute a structured call on it
_, _, getter, err := DeployGetter(auth, sim) _, _, getter, err := DeployGetter(auth, sim)
@ -302,7 +303,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a tuple tester contract and execute a structured call on it // Deploy a tuple tester contract and execute a structured call on it
_, _, tupler, err := DeployTupler(auth, sim) _, _, tupler, err := DeployTupler(auth, sim)
@ -344,7 +345,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a slice tester contract and execute a n array call on it // Deploy a slice tester contract and execute a n array call on it
_, _, slicer, err := DeploySlicer(auth, sim) _, _, slicer, err := DeploySlicer(auth, sim)
@ -378,7 +379,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a default method invoker contract and execute its default method // Deploy a default method invoker contract and execute its default method
_, _, defaulter, err := DeployDefaulter(auth, sim) _, _, defaulter, err := DeployDefaulter(auth, sim)
@ -411,7 +412,7 @@ var bindTests = []struct {
`[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`, `[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`,
` `
// Create a simulator and wrap a non-deployed contract // Create a simulator and wrap a non-deployed contract
sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000)) sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000), params.TestXDPoSMockChainConfig)
nonexistent, err := NewNonExistent(common.Address{}, sim) nonexistent, err := NewNonExistent(common.Address{}, sim)
if err != nil { if err != nil {
@ -447,7 +448,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a funky gas pattern contract // Deploy a funky gas pattern contract
_, _, limiter, err := DeployFunkyGasPattern(auth, sim) _, _, limiter, err := DeployFunkyGasPattern(auth, sim)
@ -482,7 +483,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a sender tester contract and execute a structured call on it // Deploy a sender tester contract and execute a structured call on it
_, _, callfrom, err := DeployCallFrom(auth, sim) _, _, callfrom, err := DeployCallFrom(auth, sim)
@ -542,7 +543,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy a underscorer tester contract and execute a structured call on it // Deploy a underscorer tester contract and execute a structured call on it
_, _, underscorer, err := DeployUnderscorer(auth, sim) _, _, underscorer, err := DeployUnderscorer(auth, sim)
@ -612,7 +613,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
// Deploy an eventer contract // Deploy an eventer contract
_, _, eventer, err := DeployEventer(auth, sim) _, _, eventer, err := DeployEventer(auth, sim)
@ -761,7 +762,7 @@ var bindTests = []struct {
// Generate a new random account and a funded simulator // Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey() key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key) auth := bind.NewKeyedTransactor(key)
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000) sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
//deploy the test contract //deploy the test contract
_, _, testContract, err := DeployDeeplyNestedArray(auth, sim) _, _, testContract, err := DeployDeeplyNestedArray(auth, sim)
@ -819,6 +820,7 @@ func TestBindings(t *testing.T) {
if !common.FileExist(gocmd) { if !common.FileExist(gocmd) {
t.Skip("go sdk not found for testing") t.Skip("go sdk not found for testing")
} }
t.Log("Using config", params.TestXDPoSMockChainConfig)
// Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845) // Skip the test if the go-ethereum sources are symlinked (https://github.com/golang/go/issues/14845)
linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}") linkTestCode := fmt.Sprintf("package linktest\nfunc CheckSymlinks(){\nfmt.Println(backends.NewSimulatedBackend(nil))\n}")
linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil) linkTestDeps, err := imports.Process(os.TempDir(), []byte(linkTestCode), nil)

View file

@ -28,6 +28,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
@ -56,7 +57,7 @@ func TestWaitDeployed(t *testing.T) {
backend := backends.NewXDCSimulatedBackend( backend := backends.NewXDCSimulatedBackend(
core.GenesisAlloc{ core.GenesisAlloc{
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)}, crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
}, 10000000, }, 10000000, params.TestXDPoSMockChainConfig,
) )
// Create the transaction. // Create the transaction.

View file

@ -177,7 +177,7 @@ func (w *wizard) makeGenesis() {
// Validator Smart Contract Code // Validator Smart Contract Code
pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
addr := crypto.PubkeyToAddress(pKey.PublicKey) addr := crypto.PubkeyToAddress(pKey.PublicKey)
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
transactOpts := bind.NewKeyedTransactor(pKey) transactOpts := bind.NewKeyedTransactor(pKey)
validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner) validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner)

View file

@ -22,7 +22,9 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v1" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v1"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/engines/engine_v2"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/consensus/clique" "github.com/XinFinOrg/XDPoSChain/consensus/clique"
"github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
@ -34,11 +36,7 @@ import (
) )
func SigHash(header *types.Header) (hash common.Hash) { func SigHash(header *types.Header) (hash common.Hash) {
switch params.BlockConsensusVersion(header.Number) { return utils.SigHash(header)
// TODO: Add switch case for 2.0 later
default: // Default "1.0"
return engine_v1.SigHash(header)
}
} }
// XDPoS is the delegated-proof-of-stake consensus engine proposed to support the // XDPoS is the delegated-proof-of-stake consensus engine proposed to support the
@ -56,6 +54,7 @@ type XDPoS struct {
// The exact consensus engine with different versions // The exact consensus engine with different versions
EngineV1 engine_v1.XDPoS_v1 EngineV1 engine_v1.XDPoS_v1
EngineV2 engine_v2.XDPoS_v2
} }
// New creates a XDPoS delegated-proof-of-stake consensus engine with the initial // New creates a XDPoS delegated-proof-of-stake consensus engine with the initial
@ -76,15 +75,20 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
signingTxsCache: signingTxsCache, signingTxsCache: signingTxsCache,
EngineV1: *engine_v1.New(&conf, db), EngineV1: *engine_v1.New(&conf, db),
EngineV2: *engine_v2.New(&conf, db),
} }
} }
// NewFullFaker creates an ethash consensus engine with a full fake scheme that // NewFullFaker creates an ethash consensus engine with a full fake scheme that
// accepts all blocks as valid, without checking any consensus rules whatsoever. // accepts all blocks as valid, without checking any consensus rules whatsoever.
func NewFaker(db ethdb.Database) *XDPoS { func NewFaker(db ethdb.Database, chainConfig *params.ChainConfig) *XDPoS {
var fakeEngine *XDPoS var fakeEngine *XDPoS
// Set any missing consensus parameters to their defaults // Set any missing consensus parameters to their defaults
conf := params.TestXDPoSMockChainConfig.XDPoS conf := params.TestXDPoSMockChainConfig.XDPoS
if chainConfig != nil {
conf = chainConfig.XDPoS
}
// Allocate the snapshot caches and create the engine // Allocate the snapshot caches and create the engine
signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit) signingTxsCache, _ := lru.New(utils.BlockSignersCacheLimit)
@ -93,7 +97,8 @@ func NewFaker(db ethdb.Database) *XDPoS {
db: db, db: db,
signingTxsCache: signingTxsCache, signingTxsCache: signingTxsCache,
EngineV1: *engine_v1.NewFaker(db), EngineV1: *engine_v1.NewFaker(db, conf),
EngineV2: *engine_v2.NewFaker(db, conf),
} }
return fakeEngine return fakeEngine
} }
@ -115,7 +120,9 @@ func (c *XDPoS) APIs(chain consensus.ChainReader) []rpc.API {
// Author implements consensus.Engine, returning the Ethereum address recovered // Author implements consensus.Engine, returning the Ethereum address recovered
// from the signature in the header's extra-data section. // from the signature in the header's extra-data section.
func (c *XDPoS) Author(header *types.Header) (common.Address, error) { func (c *XDPoS) Author(header *types.Header) (common.Address, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
case 2:
return c.EngineV2.Author(header)
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.Author(header) return c.EngineV1.Author(header)
} }
@ -123,7 +130,7 @@ func (c *XDPoS) Author(header *types.Header) (common.Address, error) {
// VerifyHeader checks whether a header conforms to the consensus rules. // VerifyHeader checks whether a header conforms to the consensus rules.
func (c *XDPoS) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error { func (c *XDPoS) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.VerifyHeader(chain, header, fullVerify) return c.EngineV1.VerifyHeader(chain, header, fullVerify)
} }
@ -140,7 +147,7 @@ func (c *XDPoS) VerifyHeaders(chain consensus.ChainReader, headers []*types.Head
// VerifyUncles implements consensus.Engine, always returning an error for any // VerifyUncles implements consensus.Engine, always returning an error for any
// uncles as this consensus mechanism doesn't permit uncles. // uncles as this consensus mechanism doesn't permit uncles.
func (c *XDPoS) VerifyUncles(chain consensus.ChainReader, block *types.Block) error { func (c *XDPoS) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
switch params.BlockConsensusVersion(block.Number()) { switch c.config.BlockConsensusVersion(block.Number()) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.VerifyUncles(chain, block) return c.EngineV1.VerifyUncles(chain, block)
} }
@ -149,7 +156,7 @@ func (c *XDPoS) VerifyUncles(chain consensus.ChainReader, block *types.Block) er
// VerifySeal implements consensus.Engine, checking whether the signature contained // VerifySeal implements consensus.Engine, checking whether the signature contained
// in the header satisfies the consensus protocol requirements. // in the header satisfies the consensus protocol requirements.
func (c *XDPoS) VerifySeal(chain consensus.ChainReader, header *types.Header) error { func (c *XDPoS) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.VerifySeal(chain, header) return c.EngineV1.VerifySeal(chain, header)
} }
@ -158,7 +165,7 @@ func (c *XDPoS) VerifySeal(chain consensus.ChainReader, header *types.Header) er
// Prepare implements consensus.Engine, preparing all the consensus fields of the // Prepare implements consensus.Engine, preparing all the consensus fields of the
// header for running the transactions on top. // header for running the transactions on top.
func (c *XDPoS) Prepare(chain consensus.ChainReader, header *types.Header) error { func (c *XDPoS) Prepare(chain consensus.ChainReader, header *types.Header) error {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.Prepare(chain, header) return c.EngineV1.Prepare(chain, header)
} }
@ -167,7 +174,7 @@ func (c *XDPoS) Prepare(chain consensus.ChainReader, header *types.Header) error
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block. // rewards given, and returns the final block.
func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, parentState *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.Finalize(chain, header, state, parentState, txs, uncles, receipts) return c.EngineV1.Finalize(chain, header, state, parentState, txs, uncles, receipts)
} }
@ -176,7 +183,7 @@ func (c *XDPoS) Finalize(chain consensus.ChainReader, header *types.Header, stat
// Seal implements consensus.Engine, attempting to create a sealed block using // Seal implements consensus.Engine, attempting to create a sealed block using
// the local signing credentials. // the local signing credentials.
func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) { func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
switch params.BlockConsensusVersion(block.Number()) { switch c.config.BlockConsensusVersion(block.Number()) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.Seal(chain, block, stop) return c.EngineV1.Seal(chain, block, stop)
} }
@ -186,7 +193,7 @@ func (c *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-cha
// that a new block should have based on the previous blocks in the chain and the // that a new block should have based on the previous blocks in the chain and the
// current signer. // current signer.
func (c *XDPoS) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int { func (c *XDPoS) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
switch params.BlockConsensusVersion(parent.Number) { switch c.config.BlockConsensusVersion(parent.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.CalcDifficulty(chain, time, parent) return c.EngineV1.CalcDifficulty(chain, time, parent)
} }
@ -208,49 +215,49 @@ func (c *XDPoS) GetPeriod() uint64 {
} }
func (c *XDPoS) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool { func (c *XDPoS) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.IsAuthorisedAddress(header, chain, address) return c.EngineV1.IsAuthorisedAddress(header, chain, address)
} }
} }
func (c *XDPoS) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address { func (c *XDPoS) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.GetMasternodes(chain, header) return c.EngineV1.GetMasternodes(chain, header)
} }
} }
func (c *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) { func (c *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
switch params.BlockConsensusVersion(parent.Number) { switch c.config.BlockConsensusVersion(parent.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.YourTurn(chain, parent, signer) return c.EngineV1.YourTurn(chain, parent, signer)
} }
} }
func (c *XDPoS) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) { func (c *XDPoS) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.GetValidator(creator, chain, header) return c.EngineV1.GetValidator(creator, chain, header)
} }
} }
func (c *XDPoS) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error { func (c *XDPoS) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.UpdateMasternodes(chain, header, ms) return c.EngineV1.UpdateMasternodes(chain, header, ms)
} }
} }
func (c *XDPoS) RecoverSigner(header *types.Header) (common.Address, error) { func (c *XDPoS) RecoverSigner(header *types.Header) (common.Address, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.RecoverSigner(header) return c.EngineV1.RecoverSigner(header)
} }
} }
func (c *XDPoS) RecoverValidator(header *types.Header) (common.Address, error) { func (c *XDPoS) RecoverValidator(header *types.Header) (common.Address, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.RecoverValidator(header) return c.EngineV1.RecoverValidator(header)
} }
@ -258,7 +265,7 @@ func (c *XDPoS) RecoverValidator(header *types.Header) (common.Address, error) {
// Get master nodes over extra data of previous checkpoint block. // Get master nodes over extra data of previous checkpoint block.
func (c *XDPoS) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address { func (c *XDPoS) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
switch params.BlockConsensusVersion(preCheckpointHeader.Number) { switch c.config.BlockConsensusVersion(preCheckpointHeader.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.GetMasternodesFromCheckpointHeader(preCheckpointHeader, n, e) return c.EngineV1.GetMasternodesFromCheckpointHeader(preCheckpointHeader, n, e)
} }
@ -270,7 +277,7 @@ func (c *XDPoS) GetDb() ethdb.Database {
} }
func (c *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiSnapshot, error) { func (c *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiSnapshot, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
sp, err := c.EngineV1.GetSnapshot(chain, header) sp, err := c.EngineV1.GetSnapshot(chain, header)
// Convert to a standard PublicApiSnapshot type, otherwise it's a breaking change to API // Convert to a standard PublicApiSnapshot type, otherwise it's a breaking change to API
@ -286,7 +293,7 @@ func (c *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
} }
func (c *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) { func (c *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
switch params.BlockConsensusVersion(header.Number) { switch c.config.BlockConsensusVersion(header.Number) {
default: // Default "1.0" default: // Default "1.0"
return c.EngineV1.GetAuthorisedSignersFromSnapshot(chain, header) return c.EngineV1.GetAuthorisedSignersFromSnapshot(chain, header)
} }

View file

@ -15,62 +15,19 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus" "github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils" "github.com/XinFinOrg/XDPoSChain/consensus/XDPoS/utils"
"github.com/XinFinOrg/XDPoSChain/consensus/clique" "github.com/XinFinOrg/XDPoSChain/consensus/clique"
"github.com/XinFinOrg/XDPoSChain/consensus/misc" "github.com/XinFinOrg/XDPoSChain/consensus/misc"
"github.com/XinFinOrg/XDPoSChain/core/state" "github.com/XinFinOrg/XDPoSChain/core/state"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/crypto/sha3"
"github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/rlp"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
) )
// SignerFn is a signer callback function to request a hash to be signed by a
// backing account.
//type SignerFn func(accounts.Account, []byte) ([]byte, error)
// sigHash returns the hash which is used as input for the delegated-proof-of-stake
// signing. It is the hash of the entire header apart from the 65 byte signature
// contained at the end of the extra data.
//
// Note, the method requires the extra data to be at least 65 bytes, otherwise it
// panics. This is done to avoid accidentally using both forms (signature present
// or not), which could be abused to produce different hashes for the same header.
func sigHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewKeccak256()
err := rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
header.MixDigest,
header.Nonce,
})
if err != nil {
log.Debug("Fail to encode", err)
}
hasher.Sum(hash[:0])
return hash
}
func SigHash(header *types.Header) (hash common.Hash) {
return sigHash(header)
}
// ecrecover extracts the Ethereum account address from a signed header. // ecrecover extracts the Ethereum account address from a signed header.
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) { func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
// If the signature's already cached, return that // If the signature's already cached, return that
@ -85,7 +42,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er
signature := header.Extra[len(header.Extra)-utils.ExtraSeal:] signature := header.Extra[len(header.Extra)-utils.ExtraSeal:]
// Recover the public key and the Ethereum address // Recover the public key and the Ethereum address
pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), signature) pubkey, err := crypto.Ecrecover(utils.SigHash(header).Bytes(), signature)
if err != nil { if err != nil {
return common.Address{}, err return common.Address{}, err
} }
@ -916,7 +873,7 @@ func (c *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
default: default:
} }
// Sign all the things! // Sign all the things!
sighash, err := signFn(accounts.Account{Address: signer}, sigHash(header).Bytes()) sighash, err := signFn(accounts.Account{Address: signer}, utils.SigHash(header).Bytes())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -966,7 +923,7 @@ func (c *XDPoS_v1) RecoverValidator(header *types.Header) (common.Address, error
return common.Address{}, consensus.ErrFailValidatorSignature return common.Address{}, consensus.ErrFailValidatorSignature
} }
// Recover the public key and the Ethereum address // Recover the public key and the Ethereum address
pubkey, err := crypto.Ecrecover(sigHash(header).Bytes(), header.Validator) pubkey, err := crypto.Ecrecover(utils.SigHash(header).Bytes(), header.Validator)
if err != nil { if err != nil {
return common.Address{}, err return common.Address{}, err
} }
@ -1047,10 +1004,10 @@ func (c *XDPoS_v1) getSignersFromContract(chain consensus.ChainReader, checkpoin
return signers, nil return signers, nil
} }
func NewFaker(db ethdb.Database) *XDPoS_v1 { func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v1 {
var fakeEngine *XDPoS_v1 var fakeEngine *XDPoS_v1
// Set any missing consensus parameters to their defaults // Set any missing consensus parameters to their defaults
conf := params.TestXDPoSMockChainConfig.XDPoS conf := config
// Allocate the snapshot caches and create the engine // Allocate the snapshot caches and create the engine
recents, _ := lru.NewARC(utils.InmemorySnapshots) recents, _ := lru.NewARC(utils.InmemorySnapshots)

View file

@ -1 +1,42 @@
package engine_v2 package engine_v2
import (
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/params"
)
type XDPoS_v2 struct {
config *params.XDPoSConfig // Consensus engine configuration parameters
db ethdb.Database // Database to store and retrieve snapshot checkpoints
}
func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v2 {
return &XDPoS_v2{
config: config,
db: db,
}
}
func NewFaker(db ethdb.Database, config *params.XDPoSConfig) *XDPoS_v2 {
var fakeEngine *XDPoS_v2
// Set any missing consensus parameters to their defaults
conf := config
// Allocate the snapshot caches and create the engine
fakeEngine = &XDPoS_v2{
config: conf,
db: db,
}
return fakeEngine
}
func (consensus *XDPoS_v2) Author(header *types.Header) (common.Address, error) {
return common.Address{}, nil
}
func (consensus *XDPoS_v2) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
return nil
}

View file

@ -9,8 +9,10 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto/sha3"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/rlp"
) )
func Position(list []common.Address, x common.Address) int { func Position(list []common.Address, x common.Address) int {
@ -109,3 +111,41 @@ func CompareSignersLists(list1 []common.Address, list2 []common.Address) bool {
}) })
return reflect.DeepEqual(list1, list2) return reflect.DeepEqual(list1, list2)
} }
// SignerFn is a signer callback function to request a hash to be signed by a
// backing account.
//type SignerFn func(accounts.Account, []byte) ([]byte, error)
// sigHash returns the hash which is used as input for the delegated-proof-of-stake
// signing. It is the hash of the entire header apart from the 65 byte signature
// contained at the end of the extra data.
//
// Note, the method requires the extra data to be at least 65 bytes, otherwise it
// panics. This is done to avoid accidentally using both forms (signature present
// or not), which could be abused to produce different hashes for the same header.
func SigHash(header *types.Header) (hash common.Hash) {
hasher := sha3.NewKeccak256()
err := rlp.Encode(hasher, []interface{}{
header.ParentHash,
header.UncleHash,
header.Coinbase,
header.Root,
header.TxHash,
header.ReceiptHash,
header.Bloom,
header.Difficulty,
header.Number,
header.GasLimit,
header.GasUsed,
header.Time,
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
header.MixDigest,
header.Nonce,
})
if err != nil {
log.Debug("Fail to encode", err)
}
hasher.Sum(hash[:0])
return hash
}

View file

@ -28,6 +28,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -36,7 +37,7 @@ var (
) )
func TestBlockSigner(t *testing.T) { func TestBlockSigner(t *testing.T) {
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
transactOpts := bind.NewKeyedTransactor(key) transactOpts := bind.NewKeyedTransactor(key)
blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99)) blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99))

View file

@ -30,6 +30,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/contracts/chequebook/contract" "github.com/XinFinOrg/XDPoSChain/contracts/chequebook/contract"
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -46,7 +47,7 @@ func newTestBackend() *backends.SimulatedBackend {
addr0: {Balance: big.NewInt(1000000000)}, addr0: {Balance: big.NewInt(1000000000)},
addr1: {Balance: big.NewInt(1000000000)}, addr1: {Balance: big.NewInt(1000000000)},
addr2: {Balance: big.NewInt(1000000000)}, addr2: {Balance: big.NewInt(1000000000)},
}, 10000000) }, 10000000, params.TestXDPoSMockChainConfig)
} }
func deploy(prvKey *ecdsa.PrivateKey, amount *big.Int, backend *backends.SimulatedBackend) (common.Address, error) { func deploy(prvKey *ecdsa.PrivateKey, amount *big.Int, backend *backends.SimulatedBackend) (common.Address, error) {

View file

@ -25,6 +25,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/contracts/ens/contract" "github.com/XinFinOrg/XDPoSChain/contracts/ens/contract"
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -35,7 +36,7 @@ var (
) )
func TestENS(t *testing.T) { func TestENS(t *testing.T) {
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
transactOpts := bind.NewKeyedTransactor(key) transactOpts := bind.NewKeyedTransactor(key)
ensAddr, ens, err := DeployENS(transactOpts, contractBackend) ensAddr, ens, err := DeployENS(transactOpts, contractBackend)

View file

@ -28,6 +28,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -40,7 +41,7 @@ var (
) )
func TestRandomize(t *testing.T) { func TestRandomize(t *testing.T) {
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}}, 10000000) contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
transactOpts := bind.NewKeyedTransactor(key) transactOpts := bind.NewKeyedTransactor(key)
transactOpts.GasLimit = 1000000 transactOpts.GasLimit = 1000000

View file

@ -32,6 +32,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -47,7 +48,7 @@ var (
func getCommonBackend() *backends.SimulatedBackend { func getCommonBackend() *backends.SimulatedBackend {
genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}} genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}}
backend := backends.NewXDCSimulatedBackend(genesis, 10000000) backend := backends.NewXDCSimulatedBackend(genesis, 10000000, params.TestXDPoSMockChainConfig)
backend.Commit() backend.Commit()
return backend return backend

View file

@ -30,6 +30,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/crypto" "github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/log" "github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params"
) )
var ( var (
@ -46,7 +47,7 @@ var (
) )
func TestValidator(t *testing.T) { func TestValidator(t *testing.T) {
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000) contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000, params.TestXDPoSMockChainConfig)
transactOpts := bind.NewKeyedTransactor(key) transactOpts := bind.NewKeyedTransactor(key)
validatorCap := new(big.Int) validatorCap := new(big.Int)
@ -86,7 +87,7 @@ func TestRewardBalance(t *testing.T) {
acc1Addr: {Balance: new(big.Int).SetUint64(10000000)}, acc1Addr: {Balance: new(big.Int).SetUint64(10000000)},
acc2Addr: {Balance: new(big.Int).SetUint64(10000000)}, acc2Addr: {Balance: new(big.Int).SetUint64(10000000)},
acc4Addr: {Balance: new(big.Int).SetUint64(10000000)}, acc4Addr: {Balance: new(big.Int).SetUint64(10000000)},
}, 42000000) }, 42000000, params.TestXDPoSMockChainConfig)
acc1Opts := bind.NewKeyedTransactor(acc1Key) acc1Opts := bind.NewKeyedTransactor(acc1Key)
acc2Opts := bind.NewKeyedTransactor(acc2Key) acc2Opts := bind.NewKeyedTransactor(acc2Key)
accounts := []*bind.TransactOpts{acc1Opts, acc2Opts} accounts := []*bind.TransactOpts{acc1Opts, acc2Opts}

30631
coverage.txt

File diff suppressed because it is too large Load diff

2
go.mod
View file

@ -51,7 +51,7 @@ require (
github.com/rs/cors v1.6.0 github.com/rs/cors v1.6.0
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d
golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59 golang.org/x/crypto v0.0.0-20191105034135-c7e5f84aec59
golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2 golang.org/x/net v0.0.0-20190912160710-24e19bdeb0f2

5
go.sum
View file

@ -87,6 +87,7 @@ github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59j
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/ethereum/go-ethereum v1.9.9 h1:jnoBvjH8aMH++iH14XmiJdAsnRcmZUM+B5fsnEZBVE0= github.com/ethereum/go-ethereum v1.9.9 h1:jnoBvjH8aMH++iH14XmiJdAsnRcmZUM+B5fsnEZBVE0=
github.com/ethereum/go-ethereum v1.9.9/go.mod h1:a9TqabFudpDu1nucId+k9S8R9whYaHnGBLKFouA5EAo= github.com/ethereum/go-ethereum v1.9.9/go.mod h1:a9TqabFudpDu1nucId+k9S8R9whYaHnGBLKFouA5EAo=
github.com/ethereum/go-ethereum v1.10.10 h1:Ft2GcLQrr2M89l49g9NoqgNtJZ9AahzMb7N6VXKZy5U=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.6.0 h1:66qjqZk8kalYAvDRtM1AdAJQI0tj4Wrue3Eq3B3pmFU= github.com/fatih/color v1.6.0 h1:66qjqZk8kalYAvDRtM1AdAJQI0tj4Wrue3Eq3B3pmFU=
github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.6.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@ -261,6 +262,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d h1:gZZadD8H+fF+n9CmNhYL1Y0dJB+kLOmKd7FbPJLeGHs=
github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/syndtr/goleveldb v1.0.1-0.20190923125748-758128399b1d/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
@ -348,5 +351,7 @@ gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHO
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -111,10 +111,13 @@ var (
// adding flags to the config to also have to set these fields. // adding flags to the config to also have to set these fields.
AllXDPoSProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}} AllXDPoSProtocolChanges = &ChainConfig{big.NewInt(89), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 0, Epoch: 30000}}
AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil}
TestXDPoSChanConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 2, Epoch: 900, Reward: 250, RewardCheckpoint: 900, Gap: 890, FoudationWalletAddr: common.HexToAddress("0x0000000000000000000000000000000000000068")}}
// XDPoS config in use for v1 engine only
TestXDPoSMockChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true}} TestXDPoSMockChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true}}
TestXDPoSChanConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, &XDPoSConfig{Period: 2, Epoch: 900, Reward: 250, RewardCheckpoint: 900, Gap: 890, FoudationWalletAddr: common.HexToAddress("0x0000000000000000000000000000000000000068")}} // XDPoS config with v2 engine after block 10
// TestXDPoSMockChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &XDPoSConfig{Epoch: 900, Gap: 890, SkipValidation: true}} TestXDPoSMockChainConfigWithV2Engine = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, &XDPoSConfig{Epoch: 900, Gap: 450, SkipValidation: true, V2ConsensusBlockNumber: big.NewInt(10)}}
// TestXDPoSChainConfig = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, &XDPoSConfig{Period: 2, Epoch: 900, Reward: 250, RewardCheckpoint: 900, Gap: 890, FoudationWalletAddr: common.HexToAddress("0x0000000000000000000000000000000000000068")}}
TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil} TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil, nil}
TestRules = TestChainConfig.Rules(new(big.Int)) TestRules = TestChainConfig.Rules(new(big.Int))
) )
@ -169,13 +172,14 @@ func (c *CliqueConfig) String() string {
// XDPoSConfig is the consensus engine configs for delegated-proof-of-stake based sealing. // XDPoSConfig is the consensus engine configs for delegated-proof-of-stake based sealing.
type XDPoSConfig struct { type XDPoSConfig struct {
Period uint64 `json:"period"` // Number of seconds between blocks to enforce Period uint64 `json:"period"` // Number of seconds between blocks to enforce
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
Reward uint64 `json:"reward"` // Block reward - unit Ether Reward uint64 `json:"reward"` // Block reward - unit Ether
RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards. RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards.
Gap uint64 `json:"gap"` // Gap time preparing for the next epoch Gap uint64 `json:"gap"` // Gap time preparing for the next epoch
FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet
SkipValidation bool //Skip Block Validation for testing purpose SkipValidation bool //Skip Block Validation for testing purpose
V2ConsensusBlockNumber *big.Int
} }
// String implements the stringer interface, returning the consensus engine details. // String implements the stringer interface, returning the consensus engine details.
@ -187,7 +191,10 @@ func (c *XDPoSConfig) String() string {
ConsensusVersion will return the consensus version to use for the provided block number. The returned int represent its version ConsensusVersion will return the consensus version to use for the provided block number. The returned int represent its version
TODO: It's a dummy value for now until the 2.0 consensus engine is fully implemented. TODO: It's a dummy value for now until the 2.0 consensus engine is fully implemented.
*/ */
func BlockConsensusVersion(num *big.Int) int { func (c *XDPoSConfig) BlockConsensusVersion(num *big.Int) int {
if c.V2ConsensusBlockNumber != nil && num.Cmp(c.V2ConsensusBlockNumber) > 0 {
return 2
}
return 1 return 1
} }

View file

@ -0,0 +1,46 @@
package consensus
import (
"fmt"
"testing"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/stretchr/testify/assert"
)
func TestAdaptorShouldGetAuthorForDifferentConsensusVersion(t *testing.T) {
blockchain, _, currentBlock := PrepareXDCTestBlockChain(t, 10, params.TestXDPoSMockChainConfigWithV2Engine)
adaptor := blockchain.Engine().(*XDPoS.XDPoS)
addressFromAdaptor, errorAdaptor := adaptor.Author(currentBlock.Header())
if errorAdaptor != nil {
t.Fatalf("Failed while trying to get Author from adaptor")
}
addressFromV1Engine, errV1 := adaptor.EngineV1.Author(currentBlock.Header())
if errV1 != nil {
t.Fatalf("Failed while trying to get Author from engine v1")
}
// Make sure the value is exactly the same as from V1 engine
assert.Equal(t, addressFromAdaptor, addressFromV1Engine)
// Insert one more block to make it above 10, which means now we are on v2 of consensus engine
// Insert block 11
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 11)
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
block11, err := insertBlock(blockchain, 11, blockCoinBase, currentBlock, merkleRoot)
if err != nil {
t.Fatal(err)
}
addressFromAdaptor, errorAdaptor = adaptor.Author(block11.Header())
if errorAdaptor != nil {
t.Fatalf("Failed while trying to get Author from adaptor")
}
addressFromV2Engine, errV2 := adaptor.EngineV2.Author(block11.Header())
if errV2 != nil {
t.Fatalf("Failed while trying to get Author from engine v2")
}
// Make sure the value is exactly the same as from V2 engine
assert.Equal(t, addressFromAdaptor, addressFromV2Engine)
}

View file

@ -1,368 +1,18 @@
package tests package consensus
import ( import (
"bytes"
"context"
"encoding/hex"
"fmt" "fmt"
"math/big" "math/big"
"reflect" "reflect"
"strings"
"testing" "testing"
"time"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
contractValidator "github.com/XinFinOrg/XDPoSChain/contracts/validator/contract"
"github.com/XinFinOrg/XDPoSChain/core"
. "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/rlp"
) )
type masterNodes map[string]big.Int
type signersList map[string]bool
const GAP = int(450)
var (
acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
acc3Key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
voterKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee04aefe388d1e14474d32c45c72ce7b7a")
acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey) //xdc703c4b2bD70c169f5717101CaeE543299Fc946C7
acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey) //xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
acc3Addr = crypto.PubkeyToAddress(acc3Key.PublicKey) //xdc71562b71999873DB5b286dF957af199Ec94617F7
voterAddr = crypto.PubkeyToAddress(voterKey.PublicKey) //xdc5F74529C0338546f82389402a01c31fB52c6f434
chainID = int64(1337)
)
func debugMessage(backend *backends.SimulatedBackend, signers signersList, t *testing.T) {
ms := GetCandidateFromCurrentSmartContract(backend, t)
fmt.Println("=== current smart contract")
for nodeAddr, cap := range ms {
if !strings.Contains(nodeAddr, "000000000000000000000000000000000000") { //remove defaults
fmt.Println(nodeAddr, cap)
}
}
fmt.Println("=== this block signer list")
for signer := range signers {
if !strings.Contains(signer, "000000000000000000000000000000000000") { //remove defaults
fmt.Println(signer)
}
}
}
func getCommonBackend(t *testing.T) *backends.SimulatedBackend {
// initial helper backend
contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{
voterAddr: {Balance: new(big.Int).SetUint64(10000000000)},
}, 10000000)
transactOpts := bind.NewKeyedTransactor(voterKey)
var candidates []common.Address
var caps []*big.Int
defalutCap := new(big.Int)
defalutCap.SetString("1000000000", 10)
for i := 1; i <= 16; i++ {
addr := fmt.Sprintf("%02d", i)
candidates = append(candidates, common.StringToAddress(addr)) // StringToAddress does not exist
caps = append(caps, defalutCap)
}
acc1Cap, acc2Cap, acc3Cap, voterCap := new(big.Int), new(big.Int), new(big.Int), new(big.Int)
acc1Cap.SetString("10000001", 10)
acc2Cap.SetString("10000002", 10)
acc3Cap.SetString("10000003", 10)
voterCap.SetString("1000000000", 10)
caps = append(caps, voterCap, acc1Cap, acc2Cap, acc3Cap)
candidates = append(candidates, voterAddr, acc1Addr, acc2Addr, acc3Addr)
// create validator smart contract
validatorSCAddr, _, _, err := contractValidator.DeployXDCValidator(
transactOpts,
contractBackendForSC,
candidates,
caps,
voterAddr, // first owner, not used
big.NewInt(50000),
big.NewInt(1),
big.NewInt(99),
big.NewInt(100),
big.NewInt(100),
)
if err != nil {
t.Fatalf("can't deploy root registry: %v", err)
}
contractBackendForSC.Commit() // Write into database(state)
// Prepare Code and Storage
d := time.Now().Add(1000 * time.Millisecond)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()
code, _ := contractBackendForSC.CodeAt(ctx, validatorSCAddr, nil)
storage := make(map[common.Hash]common.Hash)
f := func(key, val common.Hash) bool {
decode := []byte{}
trim := bytes.TrimLeft(val.Bytes(), "\x00")
rlp.DecodeBytes(trim, &decode)
storage[key] = common.BytesToHash(decode)
log.Info("DecodeBytes", "value", val.String(), "decode", storage[key].String())
return true
}
contractBackendForSC.ForEachStorageAt(ctx, validatorSCAddr, nil, f)
// create test backend with smart contract in it
contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{
acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)},
acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)},
acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)},
voterAddr: {Balance: new(big.Int).SetUint64(10000000000)},
common.HexToAddress(common.MasternodeVotingSMC): {Balance: new(big.Int).SetUint64(1), Code: code, Storage: storage}, // Binding the MasternodeVotingSMC with newly created 'code' for SC execution
}, 10000000)
return contractBackend2
}
func transferTx(t *testing.T, to common.Address, transferAmount int64) *types.Transaction {
t.Logf("Transfering %v to address: %v", transferAmount, to.String())
data := []byte{}
gasPrice := big.NewInt(int64(0))
gasLimit := uint64(21000)
amount := big.NewInt(transferAmount)
nonce := uint64(1)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
if err != nil {
t.Fatal(err)
}
return signedTX
}
/*
func proposeTX(t *testing.T) *types.Transaction {
data := common.Hex2Bytes("012679510000000000000000000000000d3ab14bbad3d99f4203bd7a11acb94882050e7e")
//data := []byte{}
fmt.Println("data", string(data[:]))
gasPrice := big.NewInt(int64(0))
gasLimit := uint64(22680)
amountInt := new(big.Int)
amount, ok := amountInt.SetString("11000000000000000000000000", 10)
if !ok {
t.Fatal("big int init failed")
}
nonce := uint64(0)
to := common.HexToAddress("xdc35658f7b2a9e7701e65e7a654659eb1c481d1dc5")
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), acc4Key)
if err != nil {
t.Fatal(err)
}
return signedTX
}
*/
func voteTX(gasLimit uint64, nonce uint64, addr string) (*types.Transaction, error) {
vote := "6dd7d8ea" // VoteMethod = "0x6dd7d8ea"
action := fmt.Sprintf("%s%s%s", vote, "000000000000000000000000", addr[3:])
data := common.Hex2Bytes(action)
gasPrice := big.NewInt(int64(0))
amountInt := new(big.Int)
amount, ok := amountInt.SetString("60000", 10)
if !ok {
return nil, fmt.Errorf("big int init failed")
}
to := common.HexToAddress(common.MasternodeVotingSMC)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
if err != nil {
return nil, err
}
return signedTX, nil
}
func UpdateSigner(bc *BlockChain) error {
err := bc.UpdateM1()
return err
}
func GetSnapshotSigner(bc *BlockChain, header *types.Header) (signersList, error) {
engine := bc.Engine().(*XDPoS.XDPoS)
snap, err := engine.GetSnapshot(bc, header)
if err != nil {
return nil, err
}
ms := make(signersList)
for addr := range snap.Signers {
ms[addr.Hex()] = true
}
return ms, nil
}
func GetCandidateFromCurrentSmartContract(backend bind.ContractBackend, t *testing.T) masterNodes {
addr := common.HexToAddress(common.MasternodeVotingSMC)
validator, err := contractValidator.NewXDCValidator(addr, backend)
if err != nil {
t.Fatal(err)
}
opts := new(bind.CallOpts)
candidates, err := validator.GetCandidates(opts)
if err != nil {
t.Fatal(err)
}
ms := make(masterNodes)
for _, candidate := range candidates {
v, err := validator.GetCandidateCap(opts, candidate)
if err != nil {
t.Fatal(err)
}
ms[candidate.String()] = *v
}
return ms
}
func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int) (*BlockChain, *backends.SimulatedBackend, *types.Block) {
// Preparation
var err error
backend := getCommonBackend(t)
blockchain := backend.GetBlockChain()
blockchain.Client = backend
currentBlock := blockchain.Genesis()
// Insert initial blocks
for i := 1; i <= numOfBlocks; i++ {
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", i)
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
block, err := insertBlock(blockchain, i, blockCoinBase, currentBlock, merkleRoot)
if err != nil {
t.Fatal(err)
}
currentBlock = block
}
// Update Signer as there is no previous signer assigned
err = UpdateSigner(blockchain)
if err != nil {
t.Fatal(err)
}
return blockchain, backend, currentBlock
}
// insert Block without transcation attached
func insertBlock(blockchain *BlockChain, blockNum int, blockCoinBase string, parentBlock *types.Block, root string) (*types.Block, error) {
block, err := createXDPoSTestBlock(
blockchain,
parentBlock.Hash().Hex(),
blockCoinBase, blockNum, nil,
"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
common.HexToHash(root),
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
// insert Block with transcation attached
func insertBlockTxs(blockchain *BlockChain, blockNum int, blockCoinBase string, parentBlock *types.Block, txs []*types.Transaction, root string) (*types.Block, error) {
block, err := createXDPoSTestBlock(
blockchain,
parentBlock.Hash().Hex(),
blockCoinBase, blockNum, txs,
"0x9319777b782ba2c83a33c995481ff894ac96d9a92a1963091346a3e1e386705c",
common.HexToHash(root),
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
func createXDPoSTestBlock(bc *BlockChain, parentHash, coinbase string, number int, txs []*types.Transaction, receiptHash string, root common.Hash) (*types.Block, error) {
extraSubstring := "d7830100018358444388676f312e31342e31856c696e75780000000000000000b185dc0d0e917d18e5dbf0746be6597d3331dd27ea0554e6db433feb2e81730b20b2807d33a1527bf43cd3bc057aa7f641609c2551ebe2fd575f4db704fbf38101" // Grabbed from existing mainnet block, it does not have any meaning except for the length validation
//ReceiptHash = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
//Root := "0xc99c095e53ff1afe3b86750affd13c7550a2d24d51fb8e41b3c3ef2ea8274bcc"
extraByte, _ := hex.DecodeString(extraSubstring)
header := types.Header{
ParentHash: common.HexToHash(parentHash),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
// ReceiptHash: types.EmptyRootHash,
ReceiptHash: common.HexToHash(receiptHash),
Root: root,
Coinbase: common.HexToAddress(coinbase),
Difficulty: big.NewInt(int64(1)),
Number: big.NewInt(int64(number)),
GasLimit: 1200000000,
Time: big.NewInt(int64(number * 10)),
Extra: extraByte,
}
var block *types.Block
if len(txs) == 0 {
block = types.NewBlockWithHeader(&header)
} else {
// Prepare Receipt
statedb, err := bc.StateAt(bc.GetBlockByNumber(uint64(number - 1)).Root()) //Get parent root
if err != nil {
return nil, fmt.Errorf("%v when get state", err)
}
gp := new(GasPool).AddGas(header.GasLimit)
// usedGas := uint64(0)
var gasUsed = new(uint64)
var receipts types.Receipts
for i, tx := range txs {
statedb.Prepare(tx.Hash(), header.Hash(), i)
receipt, _, err, _ := ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{})
if err != nil {
return nil, fmt.Errorf("%v when applying transaction", err)
}
receipts = append(receipts, receipt)
}
header.GasUsed = *gasUsed
block = types.NewBlock(&header, txs, nil, receipts)
}
return block, nil
}
// Should NOT update signerList if not on the gap block // Should NOT update signerList if not on the gap block
func TestNotUpdateSignerListIfNotOnGapBlock(t *testing.T) { func TestNotUpdateSignerListIfNotOnGapBlock(t *testing.T) {
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, 400) blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, 400, params.TestXDPoSMockChainConfig)
parentSigners, err := GetSnapshotSigner(blockchain, parentBlock.Header()) parentSigners, err := GetSnapshotSigner(blockchain, parentBlock.Header())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -400,7 +50,7 @@ func TestNotUpdateSignerListIfNotOnGapBlock(t *testing.T) {
// Should call updateM1 at the gap block, and have the same snapshot values as the parent block if no SM transaction is involved // Should call updateM1 at the gap block, and have the same snapshot values as the parent block if no SM transaction is involved
func TestNotChangeSingerListIfNothingProposedOrVoted(t *testing.T) { func TestNotChangeSingerListIfNothingProposedOrVoted(t *testing.T) {
blockchain, _, parentBlock := PrepareXDCTestBlockChain(t, GAP-1) blockchain, _, parentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Insert block 450 // Insert block 450
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 450) blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 450)
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930" merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
@ -428,7 +78,7 @@ func TestNotChangeSingerListIfNothingProposedOrVoted(t *testing.T) {
//Should call updateM1 at gap block, and update the snapshot if there are SM transactions involved //Should call updateM1 at gap block, and update the snapshot if there are SM transactions involved
func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) { func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-2) blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-2, params.TestXDPoSMockChainConfig)
// Insert first Block 449 // Insert first Block 449
t.Logf("Inserting block with propose at 449...") t.Logf("Inserting block with propose at 449...")
blockCoinbaseA := "0xaaa0000000000000000000000000000000000449" blockCoinbaseA := "0xaaa0000000000000000000000000000000000449"
@ -469,6 +119,9 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
} }
signers, err = GetSnapshotSigner(blockchain, block450.Header()) signers, err = GetSnapshotSigner(blockchain, block450.Header())
if err != nil {
t.Fatalf("Failed while trying to get signers")
}
// Now, we voted acc 1 to be in the signerList, which will kick out acc3 because it has less funds // Now, we voted acc 1 to be in the signerList, which will kick out acc3 because it has less funds
if signers[acc3Addr.Hex()] == true { if signers[acc3Addr.Hex()] == true {
debugMessage(backend, signers, t) debugMessage(backend, signers, t)
@ -483,7 +136,7 @@ func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
//Should call updateM1 before gap block, and update the snapshot if there are SM transactions involved //Should call updateM1 before gap block, and update the snapshot if there are SM transactions involved
func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) { func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1) blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Insert first Block 450 A // Insert first Block 450 A
t.Logf("Inserting block with propose at 450 A...") t.Logf("Inserting block with propose at 450 A...")
blockCoinbaseA := "0xaaa0000000000000000000000000000000000450" blockCoinbaseA := "0xaaa0000000000000000000000000000000000450"
@ -512,7 +165,7 @@ func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
// Should call updateM1 and update snapshot when a forked block(at gap block number) is inserted back into main chain (Edge case) // Should call updateM1 and update snapshot when a forked block(at gap block number) is inserted back into main chain (Edge case)
func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) { func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1) blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Check initial signer, by default, acc3 is in the signerList // Check initial signer, by default, acc3 is in the signerList
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header()) signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
if err != nil { if err != nil {
@ -635,9 +288,12 @@ func TestCallUpdateM1WhenForkedBlockBackToMainChain(t *testing.T) {
func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testing.T) { func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testing.T) {
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1) blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
state, err := blockchain.State() 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)) t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
// Check initial signer // Check initial signer
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header()) signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
@ -665,6 +321,9 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
t.Fatal(err) t.Fatal(err)
} }
state, err = blockchain.State() 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)) 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 { if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000999)) != 0 {
@ -697,6 +356,9 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
t.Fatal(err) t.Fatal(err)
} }
state, err = blockchain.State() 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(10000000999)) != 0 { if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000999)) != 0 {
t.Fatalf("account 1 should have 10000000999 in balance as the block is forked, not on the main chain") t.Fatalf("account 1 should have 10000000999 in balance as the block is forked, not on the main chain")
} }
@ -749,6 +411,9 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
t.Fatalf("acc2Addr should sit in the signer list") t.Fatalf("acc2Addr should sit in the signer list")
} }
state, err = blockchain.State() 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)) 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 { if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000888)) != 0 {
@ -757,7 +422,7 @@ func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testin
} }
func TestVoteShouldNotBeAffectedByFork(t *testing.T) { func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1) blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1, params.TestXDPoSMockChainConfig)
// Check initial signer, by default, acc3 is in the signerList // Check initial signer, by default, acc3 is in the signerList
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header()) signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
if err != nil { if err != nil {

View file

@ -0,0 +1,367 @@
package consensus
import (
"bytes"
"context"
"encoding/hex"
"fmt"
"math/big"
"strings"
"testing"
"time"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
contractValidator "github.com/XinFinOrg/XDPoSChain/contracts/validator/contract"
"github.com/XinFinOrg/XDPoSChain/core"
. "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/crypto"
"github.com/XinFinOrg/XDPoSChain/log"
"github.com/XinFinOrg/XDPoSChain/params"
"github.com/XinFinOrg/XDPoSChain/rlp"
)
type masterNodes map[string]big.Int
type signersList map[string]bool
const GAP = int(450)
var (
acc1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a")
acc2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee")
acc3Key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
voterKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee04aefe388d1e14474d32c45c72ce7b7a")
acc1Addr = crypto.PubkeyToAddress(acc1Key.PublicKey) //xdc703c4b2bD70c169f5717101CaeE543299Fc946C7
acc2Addr = crypto.PubkeyToAddress(acc2Key.PublicKey) //xdc0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e
acc3Addr = crypto.PubkeyToAddress(acc3Key.PublicKey) //xdc71562b71999873DB5b286dF957af199Ec94617F7
voterAddr = crypto.PubkeyToAddress(voterKey.PublicKey) //xdc5F74529C0338546f82389402a01c31fB52c6f434
chainID = int64(1337)
)
func debugMessage(backend *backends.SimulatedBackend, signers signersList, t *testing.T) {
ms := GetCandidateFromCurrentSmartContract(backend, t)
fmt.Println("=== current smart contract")
for nodeAddr, cap := range ms {
if !strings.Contains(nodeAddr, "000000000000000000000000000000000000") { //remove defaults
fmt.Println(nodeAddr, cap)
}
}
fmt.Println("=== this block signer list")
for signer := range signers {
if !strings.Contains(signer, "000000000000000000000000000000000000") { //remove defaults
fmt.Println(signer)
}
}
}
func getCommonBackend(t *testing.T, chainConfig *params.ChainConfig) *backends.SimulatedBackend {
// initial helper backend
contractBackendForSC := backends.NewXDCSimulatedBackend(core.GenesisAlloc{
voterAddr: {Balance: new(big.Int).SetUint64(10000000000)},
}, 10000000, chainConfig)
transactOpts := bind.NewKeyedTransactor(voterKey)
var candidates []common.Address
var caps []*big.Int
defalutCap := new(big.Int)
defalutCap.SetString("1000000000", 10)
for i := 1; i <= 16; i++ {
addr := fmt.Sprintf("%02d", i)
candidates = append(candidates, common.StringToAddress(addr)) // StringToAddress does not exist
caps = append(caps, defalutCap)
}
acc1Cap, acc2Cap, acc3Cap, voterCap := new(big.Int), new(big.Int), new(big.Int), new(big.Int)
acc1Cap.SetString("10000001", 10)
acc2Cap.SetString("10000002", 10)
acc3Cap.SetString("10000003", 10)
voterCap.SetString("1000000000", 10)
caps = append(caps, voterCap, acc1Cap, acc2Cap, acc3Cap)
candidates = append(candidates, voterAddr, acc1Addr, acc2Addr, acc3Addr)
// create validator smart contract
validatorSCAddr, _, _, err := contractValidator.DeployXDCValidator(
transactOpts,
contractBackendForSC,
candidates,
caps,
voterAddr, // first owner, not used
big.NewInt(50000),
big.NewInt(1),
big.NewInt(99),
big.NewInt(100),
big.NewInt(100),
)
if err != nil {
t.Fatalf("can't deploy root registry: %v", err)
}
contractBackendForSC.Commit() // Write into database(state)
// Prepare Code and Storage
d := time.Now().Add(1000 * time.Millisecond)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()
code, _ := contractBackendForSC.CodeAt(ctx, validatorSCAddr, nil)
storage := make(map[common.Hash]common.Hash)
f := func(key, val common.Hash) bool {
decode := []byte{}
trim := bytes.TrimLeft(val.Bytes(), "\x00")
err := rlp.DecodeBytes(trim, &decode)
if err != nil {
t.Fatalf("Failed while decode byte")
}
storage[key] = common.BytesToHash(decode)
log.Info("DecodeBytes", "value", val.String(), "decode", storage[key].String())
return true
}
err = contractBackendForSC.ForEachStorageAt(ctx, validatorSCAddr, nil, f)
if err != nil {
t.Fatalf("Failed while trying to read all keys from SC")
}
// create test backend with smart contract in it
contractBackend2 := backends.NewXDCSimulatedBackend(core.GenesisAlloc{
acc1Addr: {Balance: new(big.Int).SetUint64(10000000000)},
acc2Addr: {Balance: new(big.Int).SetUint64(10000000000)},
acc3Addr: {Balance: new(big.Int).SetUint64(10000000000)},
voterAddr: {Balance: new(big.Int).SetUint64(10000000000)},
common.HexToAddress(common.MasternodeVotingSMC): {Balance: new(big.Int).SetUint64(1), Code: code, Storage: storage}, // Binding the MasternodeVotingSMC with newly created 'code' for SC execution
}, 10000000, chainConfig)
return contractBackend2
}
func transferTx(t *testing.T, to common.Address, transferAmount int64) *types.Transaction {
t.Logf("Transfering %v to address: %v", transferAmount, to.String())
data := []byte{}
gasPrice := big.NewInt(int64(0))
gasLimit := uint64(21000)
amount := big.NewInt(transferAmount)
nonce := uint64(1)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
if err != nil {
t.Fatal(err)
}
return signedTX
}
func voteTX(gasLimit uint64, nonce uint64, addr string) (*types.Transaction, error) {
vote := "6dd7d8ea" // VoteMethod = "0x6dd7d8ea"
action := fmt.Sprintf("%s%s%s", vote, "000000000000000000000000", addr[3:])
data := common.Hex2Bytes(action)
gasPrice := big.NewInt(int64(0))
amountInt := new(big.Int)
amount, ok := amountInt.SetString("60000", 10)
if !ok {
return nil, fmt.Errorf("big int init failed")
}
to := common.HexToAddress(common.MasternodeVotingSMC)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), voterKey)
if err != nil {
return nil, err
}
return signedTX, nil
}
func UpdateSigner(bc *BlockChain) error {
err := bc.UpdateM1()
return err
}
func GetSnapshotSigner(bc *BlockChain, header *types.Header) (signersList, error) {
engine := bc.Engine().(*XDPoS.XDPoS)
snap, err := engine.GetSnapshot(bc, header)
if err != nil {
return nil, err
}
ms := make(signersList)
for addr := range snap.Signers {
ms[addr.Hex()] = true
}
return ms, nil
}
func GetCandidateFromCurrentSmartContract(backend bind.ContractBackend, t *testing.T) masterNodes {
addr := common.HexToAddress(common.MasternodeVotingSMC)
validator, err := contractValidator.NewXDCValidator(addr, backend)
if err != nil {
t.Fatal(err)
}
opts := new(bind.CallOpts)
candidates, err := validator.GetCandidates(opts)
if err != nil {
t.Fatal(err)
}
ms := make(masterNodes)
for _, candidate := range candidates {
v, err := validator.GetCandidateCap(opts, candidate)
if err != nil {
t.Fatal(err)
}
ms[candidate.String()] = *v
}
return ms
}
func PrepareXDCTestBlockChain(t *testing.T, numOfBlocks int, chainConfig *params.ChainConfig) (*BlockChain, *backends.SimulatedBackend, *types.Block) {
// Preparation
var err error
backend := getCommonBackend(t, chainConfig)
blockchain := backend.GetBlockChain()
blockchain.Client = backend
currentBlock := blockchain.Genesis()
// Insert initial blocks
for i := 1; i <= numOfBlocks; i++ {
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", i)
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
block, err := insertBlock(blockchain, i, blockCoinBase, currentBlock, merkleRoot)
if err != nil {
t.Fatal(err)
}
currentBlock = block
}
// Update Signer as there is no previous signer assigned
err = UpdateSigner(blockchain)
if err != nil {
t.Fatal(err)
}
return blockchain, backend, currentBlock
}
// insert Block without transcation attached
func insertBlock(blockchain *BlockChain, blockNum int, blockCoinBase string, parentBlock *types.Block, root string) (*types.Block, error) {
block, err := createXDPoSTestBlock(
blockchain,
parentBlock.Hash().Hex(),
blockCoinBase, blockNum, nil,
"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
common.HexToHash(root),
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
// insert Block with transcation attached
func insertBlockTxs(blockchain *BlockChain, blockNum int, blockCoinBase string, parentBlock *types.Block, txs []*types.Transaction, root string) (*types.Block, error) {
block, err := createXDPoSTestBlock(
blockchain,
parentBlock.Hash().Hex(),
blockCoinBase, blockNum, txs,
"0x9319777b782ba2c83a33c995481ff894ac96d9a92a1963091346a3e1e386705c",
common.HexToHash(root),
)
if err != nil {
return nil, err
}
err = blockchain.InsertBlock(block)
if err != nil {
return nil, err
}
return block, nil
}
func createXDPoSTestBlock(bc *BlockChain, parentHash, coinbase string, number int, txs []*types.Transaction, receiptHash string, root common.Hash) (*types.Block, error) {
extraSubstring := "d7830100018358444388676f312e31342e31856c696e75780000000000000000b185dc0d0e917d18e5dbf0746be6597d3331dd27ea0554e6db433feb2e81730b20b2807d33a1527bf43cd3bc057aa7f641609c2551ebe2fd575f4db704fbf38101" // Grabbed from existing mainnet block, it does not have any meaning except for the length validation
//ReceiptHash = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"
//Root := "0xc99c095e53ff1afe3b86750affd13c7550a2d24d51fb8e41b3c3ef2ea8274bcc"
extraByte, _ := hex.DecodeString(extraSubstring)
header := types.Header{
ParentHash: common.HexToHash(parentHash),
UncleHash: types.EmptyUncleHash,
TxHash: types.EmptyRootHash,
// ReceiptHash: types.EmptyRootHash,
ReceiptHash: common.HexToHash(receiptHash),
Root: root,
Coinbase: common.HexToAddress(coinbase),
Difficulty: big.NewInt(int64(1)),
Number: big.NewInt(int64(number)),
GasLimit: 1200000000,
Time: big.NewInt(int64(number * 10)),
Extra: extraByte,
}
var block *types.Block
if len(txs) == 0 {
block = types.NewBlockWithHeader(&header)
} else {
// Prepare Receipt
statedb, err := bc.StateAt(bc.GetBlockByNumber(uint64(number - 1)).Root()) //Get parent root
if err != nil {
return nil, fmt.Errorf("%v when get state", err)
}
gp := new(GasPool).AddGas(header.GasLimit)
// usedGas := uint64(0)
var gasUsed = new(uint64)
var receipts types.Receipts
for i, tx := range txs {
statedb.Prepare(tx.Hash(), header.Hash(), i)
receipt, _, err, _ := ApplyTransaction(bc.Config(), nil, bc, &header.Coinbase, gp, statedb, nil, &header, tx, gasUsed, vm.Config{})
if err != nil {
return nil, fmt.Errorf("%v when applying transaction", err)
}
receipts = append(receipts, receipt)
}
header.GasUsed = *gasUsed
block = types.NewBlock(&header, txs, nil, receipts)
}
return block, nil
}
// /*
// func proposeTX(t *testing.T) *types.Transaction {
// data := common.Hex2Bytes("012679510000000000000000000000000d3ab14bbad3d99f4203bd7a11acb94882050e7e")
// //data := []byte{}
// fmt.Println("data", string(data[:]))
// gasPrice := big.NewInt(int64(0))
// gasLimit := uint64(22680)
// amountInt := new(big.Int)
// amount, ok := amountInt.SetString("11000000000000000000000000", 10)
// if !ok {
// t.Fatal("big int init failed")
// }
// nonce := uint64(0)
// to := common.HexToAddress("xdc35658f7b2a9e7701e65e7a654659eb1c481d1dc5")
// tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, data)
// signedTX, err := types.SignTx(tx, types.NewEIP155Signer(big.NewInt(chainID)), acc4Key)
// if err != nil {
// t.Fatal(err)
// }
// return signedTX
// }
// */