mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +00:00
Merge pull request #12 from hash-laboratories-au/adaptor-config-setup-with-tests
Adaptor config setup with tests
This commit is contained in:
commit
a996c3a1a3
23 changed files with 900 additions and 31233 deletions
|
|
@ -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{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -72,26 +71,34 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
|
||||||
|
|
||||||
return &XDPoS{
|
return &XDPoS{
|
||||||
config: &conf,
|
config: &conf,
|
||||||
|
db: db,
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
fakeEngine = &XDPoS{
|
fakeEngine = &XDPoS{
|
||||||
config: conf,
|
config: conf,
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
@ -101,92 +108,94 @@ func NewFaker(db ethdb.Database) *XDPoS {
|
||||||
*/
|
*/
|
||||||
// APIs implements consensus.Engine, returning the user facing RPC API to allow
|
// APIs implements consensus.Engine, returning the user facing RPC API to allow
|
||||||
// controlling the signer voting.
|
// controlling the signer voting.
|
||||||
func (c *XDPoS) APIs(chain consensus.ChainReader) []rpc.API {
|
func (x *XDPoS) APIs(chain consensus.ChainReader) []rpc.API {
|
||||||
return []rpc.API{{
|
return []rpc.API{{
|
||||||
Namespace: "XDPoS",
|
Namespace: "XDPoS",
|
||||||
Version: "1.0",
|
Version: "1.0",
|
||||||
Service: &API{chain: chain, XDPoS: c},
|
Service: &API{chain: chain, XDPoS: x},
|
||||||
Public: true,
|
Public: true,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) Author(header *types.Header) (common.Address, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
case params.ConsensusEngineVersion2:
|
||||||
return c.EngineV1.Author(header)
|
return x.EngineV2.Author(header)
|
||||||
|
default: // Default "v1"
|
||||||
|
return x.EngineV1.Author(header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.VerifyHeader(chain, header, fullVerify)
|
return x.EngineV1.VerifyHeader(chain, header, fullVerify)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
||||||
// method returns a quit channel to abort the operations and a results channel to
|
// method returns a quit channel to abort the operations and a results channel to
|
||||||
// retrieve the async verifications (the order is that of the input slice).
|
// retrieve the async verifications (the order is that of the input slice).
|
||||||
func (c *XDPoS) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
func (x *XDPoS) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
||||||
// TODO: (Hashlab) This funciton is a special case
|
// TODO: (Hashlab) This funciton is a special case
|
||||||
return c.EngineV1.VerifyHeaders(chain, headers, fullVerifies)
|
return x.EngineV1.VerifyHeaders(chain, headers, fullVerifies)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
|
||||||
switch params.BlockConsensusVersion(block.Number()) {
|
switch x.config.BlockConsensusVersion(block.Number()) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.VerifyUncles(chain, block)
|
return x.EngineV1.VerifyUncles(chain, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.VerifySeal(chain, header)
|
return x.EngineV1.VerifySeal(chain, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) Prepare(chain consensus.ChainReader, header *types.Header) error {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.Prepare(chain, header)
|
return x.EngineV1.Prepare(chain, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *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 x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.Finalize(chain, header, state, parentState, txs, uncles, receipts)
|
return x.EngineV1.Finalize(chain, header, state, parentState, txs, uncles, receipts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
|
||||||
switch params.BlockConsensusVersion(block.Number()) {
|
switch x.config.BlockConsensusVersion(block.Number()) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.Seal(chain, block, stop)
|
return x.EngineV1.Seal(chain, block, stop)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
||||||
// 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 (x *XDPoS) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
|
||||||
switch params.BlockConsensusVersion(parent.Number) {
|
switch x.config.BlockConsensusVersion(parent.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.CalcDifficulty(chain, time, parent)
|
return x.EngineV1.CalcDifficulty(chain, time, parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,81 +205,81 @@ func (c *XDPoS) CalcDifficulty(chain consensus.ChainReader, time uint64, parent
|
||||||
|
|
||||||
// Authorize injects a private key into the consensus engine to mint new blocks
|
// Authorize injects a private key into the consensus engine to mint new blocks
|
||||||
// with.
|
// with.
|
||||||
func (c *XDPoS) Authorize(signer common.Address, signFn clique.SignerFn) {
|
func (x *XDPoS) Authorize(signer common.Address, signFn clique.SignerFn) {
|
||||||
// Authorize each consensus individually
|
// Authorize each consensus individually
|
||||||
c.EngineV1.Authorize(signer, signFn)
|
x.EngineV1.Authorize(signer, signFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetPeriod() uint64 {
|
func (x *XDPoS) GetPeriod() uint64 {
|
||||||
return c.config.Period
|
return x.config.Period
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool {
|
func (x *XDPoS) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.IsAuthorisedAddress(header, chain, address)
|
return x.EngineV1.IsAuthorisedAddress(header, chain, address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
|
func (x *XDPoS) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.GetMasternodes(chain, header)
|
return x.EngineV1.GetMasternodes(chain, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
|
func (x *XDPoS) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
|
||||||
switch params.BlockConsensusVersion(parent.Number) {
|
switch x.config.BlockConsensusVersion(parent.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.YourTurn(chain, parent, signer)
|
return x.EngineV1.YourTurn(chain, parent, signer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
func (x *XDPoS) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.GetValidator(creator, chain, header)
|
return x.EngineV1.GetValidator(creator, chain, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error {
|
func (x *XDPoS) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.UpdateMasternodes(chain, header, ms)
|
return x.EngineV1.UpdateMasternodes(chain, header, ms)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) RecoverSigner(header *types.Header) (common.Address, error) {
|
func (x *XDPoS) RecoverSigner(header *types.Header) (common.Address, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.RecoverSigner(header)
|
return x.EngineV1.RecoverSigner(header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) RecoverValidator(header *types.Header) (common.Address, error) {
|
func (x *XDPoS) RecoverValidator(header *types.Header) (common.Address, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.RecoverValidator(header)
|
return x.EngineV1.RecoverValidator(header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 (x *XDPoS) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
|
||||||
switch params.BlockConsensusVersion(preCheckpointHeader.Number) {
|
switch x.config.BlockConsensusVersion(preCheckpointHeader.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.GetMasternodesFromCheckpointHeader(preCheckpointHeader, n, e)
|
return x.EngineV1.GetMasternodesFromCheckpointHeader(preCheckpointHeader, n, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same DB across all consensus engines
|
// Same DB across all consensus engines
|
||||||
func (c *XDPoS) GetDb() ethdb.Database {
|
func (x *XDPoS) GetDb() ethdb.Database {
|
||||||
return c.db
|
return x.db
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiSnapshot, error) {
|
func (x *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*utils.PublicApiSnapshot, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
sp, err := c.EngineV1.GetSnapshot(chain, header)
|
sp, err := x.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
|
||||||
return &utils.PublicApiSnapshot{
|
return &utils.PublicApiSnapshot{
|
||||||
Number: sp.Number,
|
Number: sp.Number,
|
||||||
|
|
@ -283,10 +292,10 @@ func (c *XDPoS) GetSnapshot(chain consensus.ChainReader, header *types.Header) (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
|
func (x *XDPoS) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
|
||||||
switch params.BlockConsensusVersion(header.Number) {
|
switch x.config.BlockConsensusVersion(header.Number) {
|
||||||
default: // Default "1.0"
|
default: // Default "v1"
|
||||||
return c.EngineV1.GetAuthorisedSignersFromSnapshot(chain, header)
|
return x.EngineV1.GetAuthorisedSignersFromSnapshot(chain, header)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,7 +304,7 @@ Caching
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Cache signing transaction data into BlockSingers cache object
|
// Cache signing transaction data into BlockSingers cache object
|
||||||
func (c *XDPoS) CacheNoneTIPSigningTxs(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt) []*types.Transaction {
|
func (x *XDPoS) CacheNoneTIPSigningTxs(header *types.Header, txs []*types.Transaction, receipts []*types.Receipt) []*types.Transaction {
|
||||||
signTxs := []*types.Transaction{}
|
signTxs := []*types.Transaction{}
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if tx.IsSigningTransaction() {
|
if tx.IsSigningTransaction() {
|
||||||
|
|
@ -320,13 +329,13 @@ func (c *XDPoS) CacheNoneTIPSigningTxs(header *types.Header, txs []*types.Transa
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
|
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
|
||||||
c.signingTxsCache.Add(header.Hash(), signTxs)
|
x.signingTxsCache.Add(header.Hash(), signTxs)
|
||||||
|
|
||||||
return signTxs
|
return signTxs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache
|
// Cache
|
||||||
func (c *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*types.Transaction {
|
func (x *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*types.Transaction {
|
||||||
signTxs := []*types.Transaction{}
|
signTxs := []*types.Transaction{}
|
||||||
for _, tx := range txs {
|
for _, tx := range txs {
|
||||||
if tx.IsSigningTransaction() {
|
if tx.IsSigningTransaction() {
|
||||||
|
|
@ -334,10 +343,10 @@ func (c *XDPoS) CacheSigningTxs(hash common.Hash, txs []*types.Transaction) []*t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debug("Save tx signers to cache", "hash", hash.String(), "len(txs)", len(signTxs))
|
log.Debug("Save tx signers to cache", "hash", hash.String(), "len(txs)", len(signTxs))
|
||||||
c.signingTxsCache.Add(hash, signTxs)
|
x.signingTxsCache.Add(hash, signTxs)
|
||||||
return signTxs
|
return signTxs
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) {
|
func (x *XDPoS) GetCachedSigningTxs(hash common.Hash) (interface{}, bool) {
|
||||||
return c.signingTxsCache.Get(hash)
|
return x.signingTxsCache.Get(hash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,18 @@
|
||||||
package XDPoS
|
package XDPoS
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
func TestNewAdaptorShallContainMultipleConsensusEngine(t *testing.T) {
|
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||||
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAdaptorShouldShareDbWithV1Engine(t *testing.T) {
|
||||||
|
database := rawdb.NewMemoryDatabase()
|
||||||
|
config := params.TestXDPoSMockChainConfig.XDPoS
|
||||||
|
engine := New(config, database)
|
||||||
|
|
||||||
|
assert := assert.New(t)
|
||||||
|
assert.Equal(engine.EngineV1.GetDb(), engine.GetDb())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -148,25 +105,25 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS_v1 {
|
||||||
|
|
||||||
// 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_v1) Author(header *types.Header) (common.Address, error) {
|
func (x *XDPoS_v1) Author(header *types.Header) (common.Address, error) {
|
||||||
return ecrecover(header, c.signatures)
|
return ecrecover(header, x.signatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyHeader checks whether a header conforms to the consensus rules.
|
// VerifyHeader checks whether a header conforms to the consensus rules.
|
||||||
func (c *XDPoS_v1) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
|
func (x *XDPoS_v1) VerifyHeader(chain consensus.ChainReader, header *types.Header, fullVerify bool) error {
|
||||||
return c.verifyHeaderWithCache(chain, header, nil, fullVerify)
|
return x.verifyHeaderWithCache(chain, header, nil, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers. The
|
||||||
// method returns a quit channel to abort the operations and a results channel to
|
// method returns a quit channel to abort the operations and a results channel to
|
||||||
// retrieve the async verifications (the order is that of the input slice).
|
// retrieve the async verifications (the order is that of the input slice).
|
||||||
func (c *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
func (x *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, fullVerifies []bool) (chan<- struct{}, <-chan error) {
|
||||||
abort := make(chan struct{})
|
abort := make(chan struct{})
|
||||||
results := make(chan error, len(headers))
|
results := make(chan error, len(headers))
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for i, header := range headers {
|
for i, header := range headers {
|
||||||
err := c.verifyHeaderWithCache(chain, header, headers[:i], fullVerifies[i])
|
err := x.verifyHeaderWithCache(chain, header, headers[:i], fullVerifies[i])
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-abort:
|
case <-abort:
|
||||||
|
|
@ -178,14 +135,14 @@ func (c *XDPoS_v1) VerifyHeaders(chain consensus.ChainReader, headers []*types.H
|
||||||
return abort, results
|
return abort, results
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
func (x *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
||||||
_, check := c.verifiedHeaders.Get(header.Hash())
|
_, check := x.verifiedHeaders.Get(header.Hash())
|
||||||
if check {
|
if check {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := c.verifyHeader(chain, header, parents, fullVerify)
|
err := x.verifyHeader(chain, header, parents, fullVerify)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.verifiedHeaders.Add(header.Hash(), true)
|
x.verifiedHeaders.Add(header.Hash(), true)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -194,9 +151,9 @@ func (c *XDPoS_v1) verifyHeaderWithCache(chain consensus.ChainReader, header *ty
|
||||||
// caller may optionally pass in a batch of parents (ascending order) to avoid
|
// caller may optionally pass in a batch of parents (ascending order) to avoid
|
||||||
// looking those up from the database. This is useful for concurrently verifying
|
// looking those up from the database. This is useful for concurrently verifying
|
||||||
// a batch of new headers.
|
// a batch of new headers.
|
||||||
func (c *XDPoS_v1) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
func (x *XDPoS_v1) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
||||||
// If we're running a engine faking, accept any block as valid
|
// If we're running a engine faking, accept any block as valid
|
||||||
if c.config.SkipValidation {
|
if x.config.SkipValidation {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if common.IsTestnet {
|
if common.IsTestnet {
|
||||||
|
|
@ -207,7 +164,7 @@ func (c *XDPoS_v1) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
}
|
}
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
if fullVerify {
|
if fullVerify {
|
||||||
if header.Number.Uint64() > c.config.Epoch && len(header.Validator) == 0 {
|
if header.Number.Uint64() > x.config.Epoch && len(header.Validator) == 0 {
|
||||||
return consensus.ErrNoValidatorSignature
|
return consensus.ErrNoValidatorSignature
|
||||||
}
|
}
|
||||||
// Don't waste time checking blocks from the future
|
// Don't waste time checking blocks from the future
|
||||||
|
|
@ -216,7 +173,7 @@ func (c *XDPoS_v1) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Checkpoint blocks need to enforce zero beneficiary
|
// Checkpoint blocks need to enforce zero beneficiary
|
||||||
checkpoint := (number % c.config.Epoch) == 0
|
checkpoint := (number % x.config.Epoch) == 0
|
||||||
if checkpoint && header.Coinbase != (common.Address{}) {
|
if checkpoint && header.Coinbase != (common.Address{}) {
|
||||||
return utils.ErrInvalidCheckpointBeneficiary
|
return utils.ErrInvalidCheckpointBeneficiary
|
||||||
}
|
}
|
||||||
|
|
@ -256,14 +213,14 @@ func (c *XDPoS_v1) verifyHeader(chain consensus.ChainReader, header *types.Heade
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// All basic checks passed, verify cascading fields
|
// All basic checks passed, verify cascading fields
|
||||||
return c.verifyCascadingFields(chain, header, parents, fullVerify)
|
return x.verifyCascadingFields(chain, header, parents, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyCascadingFields verifies all the header fields that are not standalone,
|
// verifyCascadingFields verifies all the header fields that are not standalone,
|
||||||
// rather depend on a batch of previous headers. The caller may optionally pass
|
// rather depend on a batch of previous headers. The caller may optionally pass
|
||||||
// in a batch of parents (ascending order) to avoid looking those up from the
|
// in a batch of parents (ascending order) to avoid looking those up from the
|
||||||
// database. This is useful for concurrently verifying a batch of new headers.
|
// database. This is useful for concurrently verifying a batch of new headers.
|
||||||
func (c *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
func (x *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
||||||
// The genesis block is the always valid dead-end
|
// The genesis block is the always valid dead-end
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
|
|
@ -279,12 +236,12 @@ func (c *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *ty
|
||||||
if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
|
if parent == nil || parent.Number.Uint64() != number-1 || parent.Hash() != header.ParentHash {
|
||||||
return consensus.ErrUnknownAncestor
|
return consensus.ErrUnknownAncestor
|
||||||
}
|
}
|
||||||
if parent.Time.Uint64()+c.config.Period > header.Time.Uint64() {
|
if parent.Time.Uint64()+x.config.Period > header.Time.Uint64() {
|
||||||
return utils.ErrInvalidTimestamp
|
return utils.ErrInvalidTimestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
if number%c.config.Epoch != 0 {
|
if number%x.config.Epoch != 0 {
|
||||||
return c.verifySeal(chain, header, parents, fullVerify)
|
return x.verifySeal(chain, header, parents, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -292,42 +249,42 @@ func (c *XDPoS_v1) verifyCascadingFields(chain consensus.ChainReader, header *ty
|
||||||
when it happens we get the signers list by requesting smart contract
|
when it happens we get the signers list by requesting smart contract
|
||||||
*/
|
*/
|
||||||
// Retrieve the snapshot needed to verify this header and cache it
|
// Retrieve the snapshot needed to verify this header and cache it
|
||||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
|
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
signers := snap.GetSigners()
|
signers := snap.GetSigners()
|
||||||
err = c.checkSignersOnCheckpoint(chain, header, signers)
|
err = x.checkSignersOnCheckpoint(chain, header, signers)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return c.verifySeal(chain, header, parents, fullVerify)
|
return x.verifySeal(chain, header, parents, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
signers, err = c.getSignersFromContract(chain, header)
|
signers, err = x.getSignersFromContract(chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = c.checkSignersOnCheckpoint(chain, header, signers)
|
err = x.checkSignersOnCheckpoint(chain, header, signers)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return c.verifySeal(chain, header, parents, fullVerify)
|
return x.verifySeal(chain, header, parents, fullVerify)
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error {
|
func (x *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header *types.Header, signers []common.Address) error {
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
// ignore signerCheck at checkpoint block 14458500 due to wrong snapshot at gap 14458495
|
// ignore signerCheck at checkpoint block 14458500 due to wrong snapshot at gap 14458495
|
||||||
if number == common.IgnoreSignerCheckBlock {
|
if number == common.IgnoreSignerCheckBlock {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
penPenalties := []common.Address{}
|
penPenalties := []common.Address{}
|
||||||
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
|
if x.HookPenalty != nil || x.HookPenaltyTIPSigning != nil {
|
||||||
var err error
|
var err error
|
||||||
if chain.Config().IsTIPSigning(header.Number) {
|
if chain.Config().IsTIPSigning(header.Number) {
|
||||||
penPenalties, err = c.HookPenaltyTIPSigning(chain, header, signers)
|
penPenalties, err = x.HookPenaltyTIPSigning(chain, header, signers)
|
||||||
} else {
|
} else {
|
||||||
penPenalties, err = c.HookPenalty(chain, number)
|
penPenalties, err = x.HookPenalty(chain, number)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -342,8 +299,8 @@ func (c *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header
|
||||||
}
|
}
|
||||||
signers = common.RemoveItemFromArray(signers, penPenalties)
|
signers = common.RemoveItemFromArray(signers, penPenalties)
|
||||||
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
|
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
|
||||||
if number > uint64(i)*c.config.Epoch {
|
if number > uint64(i)*x.config.Epoch {
|
||||||
signers = removePenaltiesFromBlock(chain, signers, number-uint64(i)*c.config.Epoch)
|
signers = removePenaltiesFromBlock(chain, signers, number-uint64(i)*x.config.Epoch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extraSuffix := len(header.Extra) - utils.ExtraSeal
|
extraSuffix := len(header.Extra) - utils.ExtraSeal
|
||||||
|
|
@ -354,8 +311,8 @@ func (c *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header
|
||||||
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
|
log.Error("Masternodes lists are different in checkpoint header and snapshot", "number", number, "masternodes_from_checkpoint_header", masternodesFromCheckpointHeader, "masternodes_in_snapshot", signers, "penList", penPenalties)
|
||||||
return utils.ErrInvalidCheckpointSigners
|
return utils.ErrInvalidCheckpointSigners
|
||||||
}
|
}
|
||||||
if c.HookVerifyMNs != nil {
|
if x.HookVerifyMNs != nil {
|
||||||
err := c.HookVerifyMNs(header, signers)
|
err := x.HookVerifyMNs(header, signers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -364,8 +321,8 @@ func (c *XDPoS_v1) checkSignersOnCheckpoint(chain consensus.ChainReader, header
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool {
|
func (x *XDPoS_v1) IsAuthorisedAddress(header *types.Header, chain consensus.ChainReader, address common.Address) bool {
|
||||||
snap, err := c.GetSnapshot(chain, header)
|
snap, err := x.GetSnapshot(chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("[IsAuthorisedAddress] Can't get snapshot with at ", "number", header.Number, "hash", header.Hash().Hex(), "err", err)
|
log.Error("[IsAuthorisedAddress] Can't get snapshot with at ", "number", header.Number, "hash", header.Hash().Hex(), "err", err)
|
||||||
return false
|
return false
|
||||||
|
|
@ -376,26 +333,26 @@ func (c *XDPoS_v1) IsAuthorisedAddress(header *types.Header, chain consensus.Cha
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*SnapshotV1, error) {
|
func (x *XDPoS_v1) GetSnapshot(chain consensus.ChainReader, header *types.Header) (*SnapshotV1, error) {
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
log.Trace("get snapshot", "number", number, "hash", header.Hash())
|
log.Trace("get snapshot", "number", number, "hash", header.Hash())
|
||||||
snap, err := c.snapshot(chain, number, header.Hash(), nil)
|
snap, err := x.snapshot(chain, number, header.Hash(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
|
func (x *XDPoS_v1) GetAuthorisedSignersFromSnapshot(chain consensus.ChainReader, header *types.Header) ([]common.Address, error) {
|
||||||
snap, err := c.GetSnapshot(chain, header)
|
snap, err := x.GetSnapshot(chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return snap.GetSigners(), nil
|
return snap.GetSigners(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) StoreSnapshot(snap *SnapshotV1) error {
|
func (x *XDPoS_v1) StoreSnapshot(snap *SnapshotV1) error {
|
||||||
return snap.store(c.db)
|
return snap.store(x.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func position(list []common.Address, x common.Address) int {
|
func position(list []common.Address, x common.Address) int {
|
||||||
|
|
@ -407,21 +364,21 @@ func position(list []common.Address, x common.Address) int {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
|
func (x *XDPoS_v1) GetMasternodes(chain consensus.ChainReader, header *types.Header) []common.Address {
|
||||||
n := header.Number.Uint64()
|
n := header.Number.Uint64()
|
||||||
e := c.config.Epoch
|
e := x.config.Epoch
|
||||||
switch {
|
switch {
|
||||||
case n%e == 0:
|
case n%e == 0:
|
||||||
return c.GetMasternodesFromCheckpointHeader(header, n, e)
|
return x.GetMasternodesFromCheckpointHeader(header, n, e)
|
||||||
case n%e != 0:
|
case n%e != 0:
|
||||||
h := chain.GetHeaderByNumber(n - (n % e))
|
h := chain.GetHeaderByNumber(n - (n % e))
|
||||||
return c.GetMasternodesFromCheckpointHeader(h, n, e)
|
return x.GetMasternodesFromCheckpointHeader(h, n, e)
|
||||||
default:
|
default:
|
||||||
return []common.Address{}
|
return []common.Address{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetPeriod() uint64 { return c.config.Period }
|
func (x *XDPoS_v1) GetPeriod() uint64 { return x.config.Period }
|
||||||
|
|
||||||
func whoIsCreator(snap *SnapshotV1, header *types.Header) (common.Address, error) {
|
func whoIsCreator(snap *SnapshotV1, header *types.Header) (common.Address, error) {
|
||||||
if header.Number.Uint64() == 0 {
|
if header.Number.Uint64() == 0 {
|
||||||
|
|
@ -434,8 +391,8 @@ func whoIsCreator(snap *SnapshotV1, header *types.Header) (common.Address, error
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
|
func (x *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, signer common.Address) (int, int, int, bool, error) {
|
||||||
masternodes := c.GetMasternodes(chain, parent)
|
masternodes := x.GetMasternodes(chain, parent)
|
||||||
|
|
||||||
// if common.IsTestnet {
|
// if common.IsTestnet {
|
||||||
// // Only three mns hard code for XDC testnet.
|
// // Only three mns hard code for XDC testnet.
|
||||||
|
|
@ -446,7 +403,7 @@ func (c *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, s
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
snap, err := c.GetSnapshot(chain, parent)
|
snap, err := x.GetSnapshot(chain, parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed when trying to commit new work", "err", err)
|
log.Warn("Failed when trying to commit new work", "err", err)
|
||||||
return 0, -1, -1, false, err
|
return 0, -1, -1, false, err
|
||||||
|
|
@ -465,7 +422,7 @@ func (c *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, s
|
||||||
preIndex = position(masternodes, pre)
|
preIndex = position(masternodes, pre)
|
||||||
}
|
}
|
||||||
curIndex := position(masternodes, signer)
|
curIndex := position(masternodes, signer)
|
||||||
if signer == c.signer {
|
if signer == x.signer {
|
||||||
log.Debug("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", signer, "position", curIndex)
|
log.Debug("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", signer, "position", curIndex)
|
||||||
}
|
}
|
||||||
for i, s := range masternodes {
|
for i, s := range masternodes {
|
||||||
|
|
@ -478,7 +435,7 @@ func (c *XDPoS_v1) YourTurn(chain consensus.ChainReader, parent *types.Header, s
|
||||||
}
|
}
|
||||||
|
|
||||||
// snapshot retrieves the authorization snapshot at a given point in time.
|
// snapshot retrieves the authorization snapshot at a given point in time.
|
||||||
func (c *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*SnapshotV1, error) {
|
func (x *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash common.Hash, parents []*types.Header) (*SnapshotV1, error) {
|
||||||
// Search for a SnapshotV1 in memory or on disk for checkpoints
|
// Search for a SnapshotV1 in memory or on disk for checkpoints
|
||||||
var (
|
var (
|
||||||
headers []*types.Header
|
headers []*types.Header
|
||||||
|
|
@ -486,14 +443,14 @@ func (c *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
|
||||||
)
|
)
|
||||||
for snap == nil {
|
for snap == nil {
|
||||||
// If an in-memory SnapshotV1 was found, use that
|
// If an in-memory SnapshotV1 was found, use that
|
||||||
if s, ok := c.recents.Get(hash); ok {
|
if s, ok := x.recents.Get(hash); ok {
|
||||||
snap = s.(*SnapshotV1)
|
snap = s.(*SnapshotV1)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// If an on-disk checkpoint snapshot can be found, use that
|
// If an on-disk checkpoint snapshot can be found, use that
|
||||||
// checkpoint snapshot = checkpoint - gap
|
// checkpoint snapshot = checkpoint - gap
|
||||||
if (number+c.config.Gap)%c.config.Epoch == 0 {
|
if (number+x.config.Gap)%x.config.Epoch == 0 {
|
||||||
if s, err := loadSnapshot(c.config, c.signatures, c.db, hash); err == nil {
|
if s, err := loadSnapshot(x.config, x.signatures, x.db, hash); err == nil {
|
||||||
log.Trace("Loaded voting snapshot form disk", "number", number, "hash", hash)
|
log.Trace("Loaded voting snapshot form disk", "number", number, "hash", hash)
|
||||||
snap = s
|
snap = s
|
||||||
break
|
break
|
||||||
|
|
@ -502,15 +459,15 @@ func (c *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
|
||||||
// If we're at block zero, make a snapshot
|
// If we're at block zero, make a snapshot
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
genesis := chain.GetHeaderByNumber(0)
|
genesis := chain.GetHeaderByNumber(0)
|
||||||
if err := c.VerifyHeader(chain, genesis, true); err != nil {
|
if err := x.VerifyHeader(chain, genesis, true); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
signers := make([]common.Address, (len(genesis.Extra)-utils.ExtraVanity-utils.ExtraSeal)/common.AddressLength)
|
signers := make([]common.Address, (len(genesis.Extra)-utils.ExtraVanity-utils.ExtraSeal)/common.AddressLength)
|
||||||
for i := 0; i < len(signers); i++ {
|
for i := 0; i < len(signers); i++ {
|
||||||
copy(signers[i][:], genesis.Extra[utils.ExtraVanity+i*common.AddressLength:])
|
copy(signers[i][:], genesis.Extra[utils.ExtraVanity+i*common.AddressLength:])
|
||||||
}
|
}
|
||||||
snap = newSnapshot(c.config, c.signatures, 0, genesis.Hash(), signers)
|
snap = newSnapshot(x.config, x.signatures, 0, genesis.Hash(), signers)
|
||||||
if err := snap.store(c.db); err != nil {
|
if err := snap.store(x.db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Trace("Stored genesis voting snapshot to disk")
|
log.Trace("Stored genesis voting snapshot to disk")
|
||||||
|
|
@ -543,11 +500,11 @@ func (c *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.recents.Add(snap.Hash, snap)
|
x.recents.Add(snap.Hash, snap)
|
||||||
|
|
||||||
// If we've generated a new checkpoint snapshot, save to disk
|
// If we've generated a new checkpoint snapshot, save to disk
|
||||||
if (snap.Number+c.config.Gap)%c.config.Epoch == 0 {
|
if (snap.Number+x.config.Gap)%x.config.Epoch == 0 {
|
||||||
if err = snap.store(c.db); err != nil {
|
if err = snap.store(x.db); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
|
log.Trace("Stored voting snapshot to disk", "number", snap.Number, "hash", snap.Hash)
|
||||||
|
|
@ -557,7 +514,7 @@ func (c *XDPoS_v1) snapshot(chain consensus.ChainReader, number uint64, hash com
|
||||||
|
|
||||||
// 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_v1) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
|
func (x *XDPoS_v1) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
|
||||||
if len(block.Uncles()) > 0 {
|
if len(block.Uncles()) > 0 {
|
||||||
return errors.New("uncles not allowed")
|
return errors.New("uncles not allowed")
|
||||||
}
|
}
|
||||||
|
|
@ -566,8 +523,8 @@ func (c *XDPoS_v1) VerifyUncles(chain consensus.ChainReader, block *types.Block)
|
||||||
|
|
||||||
// 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_v1) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
|
func (x *XDPoS_v1) VerifySeal(chain consensus.ChainReader, header *types.Header) error {
|
||||||
return c.verifySeal(chain, header, nil, true)
|
return x.verifySeal(chain, header, nil, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifySeal checks whether the signature contained in the header satisfies the
|
// verifySeal checks whether the signature contained in the header satisfies the
|
||||||
|
|
@ -576,20 +533,20 @@ func (c *XDPoS_v1) VerifySeal(chain consensus.ChainReader, header *types.Header)
|
||||||
// from.
|
// from.
|
||||||
// verifySeal also checks the pair of creator-validator set in the header satisfies
|
// verifySeal also checks the pair of creator-validator set in the header satisfies
|
||||||
// the double validation.
|
// the double validation.
|
||||||
func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
func (x *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error {
|
||||||
// Verifying the genesis block is not supported
|
// Verifying the genesis block is not supported
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
if number == 0 {
|
if number == 0 {
|
||||||
return utils.ErrUnknownBlock
|
return utils.ErrUnknownBlock
|
||||||
}
|
}
|
||||||
// Retrieve the snapshot needed to verify this header and cache it
|
// Retrieve the snapshot needed to verify this header and cache it
|
||||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, parents)
|
snap, err := x.snapshot(chain, number-1, header.ParentHash, parents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve the authorization key and check against signers
|
// Resolve the authorization key and check against signers
|
||||||
creator, err := ecrecover(header, c.signatures)
|
creator, err := ecrecover(header, x.signatures)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -599,7 +556,7 @@ func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
|
||||||
} else {
|
} else {
|
||||||
parent = chain.GetHeader(header.ParentHash, number-1)
|
parent = chain.GetHeader(header.ParentHash, number-1)
|
||||||
}
|
}
|
||||||
difficulty := c.calcDifficulty(chain, parent, creator)
|
difficulty := x.calcDifficulty(chain, parent, creator)
|
||||||
log.Debug("verify seal block", "number", header.Number, "hash", header.Hash(), "block difficulty", header.Difficulty, "calc difficulty", difficulty, "creator", creator)
|
log.Debug("verify seal block", "number", header.Number, "hash", header.Hash(), "block difficulty", header.Difficulty, "calc difficulty", difficulty, "creator", creator)
|
||||||
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
|
// Ensure that the block's difficulty is meaningful (may not be correct at this point)
|
||||||
if number > 0 {
|
if number > 0 {
|
||||||
|
|
@ -607,7 +564,7 @@ func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
|
||||||
return utils.ErrInvalidDifficulty
|
return utils.ErrInvalidDifficulty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
masternodes := c.GetMasternodes(chain, header)
|
masternodes := x.GetMasternodes(chain, header)
|
||||||
mstring := []string{}
|
mstring := []string{}
|
||||||
for _, m := range masternodes {
|
for _, m := range masternodes {
|
||||||
mstring = append(mstring, m.String())
|
mstring = append(mstring, m.String())
|
||||||
|
|
@ -636,7 +593,7 @@ func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
|
||||||
// There is only case that we don't allow signer to create two continuous blocks.
|
// There is only case that we don't allow signer to create two continuous blocks.
|
||||||
if limit := uint64(2); seen > number-limit {
|
if limit := uint64(2); seen > number-limit {
|
||||||
// Only take into account the non-epoch blocks
|
// Only take into account the non-epoch blocks
|
||||||
if number%c.config.Epoch != 0 {
|
if number%x.config.Epoch != 0 {
|
||||||
return utils.ErrUnauthorized
|
return utils.ErrUnauthorized
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -646,14 +603,14 @@ func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
|
||||||
|
|
||||||
// header must contain validator info following double validation design
|
// header must contain validator info following double validation design
|
||||||
// start checking from epoch 2nd.
|
// start checking from epoch 2nd.
|
||||||
if header.Number.Uint64() > c.config.Epoch && fullVerify {
|
if header.Number.Uint64() > x.config.Epoch && fullVerify {
|
||||||
validator, err := c.RecoverValidator(header)
|
validator, err := x.RecoverValidator(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify validator
|
// verify validator
|
||||||
assignedValidator, err := c.GetValidator(creator, chain, header)
|
assignedValidator, err := x.GetValidator(creator, chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -665,8 +622,8 @@ func (c *XDPoS_v1) verifySeal(chain consensus.ChainReader, header *types.Header,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
func (x *XDPoS_v1) GetValidator(creator common.Address, chain consensus.ChainReader, header *types.Header) (common.Address, error) {
|
||||||
epoch := c.config.Epoch
|
epoch := x.config.Epoch
|
||||||
no := header.Number.Uint64()
|
no := header.Number.Uint64()
|
||||||
cpNo := no
|
cpNo := no
|
||||||
if no%epoch != 0 {
|
if no%epoch != 0 {
|
||||||
|
|
@ -692,23 +649,23 @@ func (c *XDPoS_v1) GetValidator(creator common.Address, chain consensus.ChainRea
|
||||||
|
|
||||||
// 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_v1) Prepare(chain consensus.ChainReader, header *types.Header) error {
|
func (x *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) error {
|
||||||
// If the block isn't a checkpoint, cast a random vote (good enough for now)
|
// If the block isn't a checkpoint, cast a random vote (good enough for now)
|
||||||
header.Coinbase = common.Address{}
|
header.Coinbase = common.Address{}
|
||||||
header.Nonce = types.BlockNonce{}
|
header.Nonce = types.BlockNonce{}
|
||||||
|
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
// Assemble the voting snapshot to check which votes make sense
|
// Assemble the voting snapshot to check which votes make sense
|
||||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
|
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if number%c.config.Epoch != 0 {
|
if number%x.config.Epoch != 0 {
|
||||||
c.lock.RLock()
|
x.lock.RLock()
|
||||||
|
|
||||||
// Gather all the proposals that make sense voting on
|
// Gather all the proposals that make sense voting on
|
||||||
addresses := make([]common.Address, 0, len(c.proposals))
|
addresses := make([]common.Address, 0, len(x.proposals))
|
||||||
for address, authorize := range c.proposals {
|
for address, authorize := range x.proposals {
|
||||||
if snap.validVote(address, authorize) {
|
if snap.validVote(address, authorize) {
|
||||||
addresses = append(addresses, address)
|
addresses = append(addresses, address)
|
||||||
}
|
}
|
||||||
|
|
@ -716,20 +673,20 @@ func (c *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
|
||||||
// If there's pending proposals, cast a vote on them
|
// If there's pending proposals, cast a vote on them
|
||||||
if len(addresses) > 0 {
|
if len(addresses) > 0 {
|
||||||
header.Coinbase = addresses[rand.Intn(len(addresses))]
|
header.Coinbase = addresses[rand.Intn(len(addresses))]
|
||||||
if c.proposals[header.Coinbase] {
|
if x.proposals[header.Coinbase] {
|
||||||
copy(header.Nonce[:], utils.NonceAuthVote)
|
copy(header.Nonce[:], utils.NonceAuthVote)
|
||||||
} else {
|
} else {
|
||||||
copy(header.Nonce[:], utils.NonceDropVote)
|
copy(header.Nonce[:], utils.NonceDropVote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.lock.RUnlock()
|
x.lock.RUnlock()
|
||||||
}
|
}
|
||||||
parent := chain.GetHeader(header.ParentHash, number-1)
|
parent := chain.GetHeader(header.ParentHash, number-1)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
return consensus.ErrUnknownAncestor
|
return consensus.ErrUnknownAncestor
|
||||||
}
|
}
|
||||||
// Set the correct difficulty
|
// Set the correct difficulty
|
||||||
header.Difficulty = c.calcDifficulty(chain, parent, c.signer)
|
header.Difficulty = x.calcDifficulty(chain, parent, x.signer)
|
||||||
log.Debug("CalcDifficulty ", "number", header.Number, "difficulty", header.Difficulty)
|
log.Debug("CalcDifficulty ", "number", header.Number, "difficulty", header.Difficulty)
|
||||||
// Ensure the extra data has all it's components
|
// Ensure the extra data has all it's components
|
||||||
if len(header.Extra) < utils.ExtraVanity {
|
if len(header.Extra) < utils.ExtraVanity {
|
||||||
|
|
@ -737,14 +694,14 @@ func (c *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
|
||||||
}
|
}
|
||||||
header.Extra = header.Extra[:utils.ExtraVanity]
|
header.Extra = header.Extra[:utils.ExtraVanity]
|
||||||
masternodes := snap.GetSigners()
|
masternodes := snap.GetSigners()
|
||||||
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
|
if number >= x.config.Epoch && number%x.config.Epoch == 0 {
|
||||||
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
|
if x.HookPenalty != nil || x.HookPenaltyTIPSigning != nil {
|
||||||
var penMasternodes []common.Address
|
var penMasternodes []common.Address
|
||||||
var err error
|
var err error
|
||||||
if chain.Config().IsTIPSigning(header.Number) {
|
if chain.Config().IsTIPSigning(header.Number) {
|
||||||
penMasternodes, err = c.HookPenaltyTIPSigning(chain, header, masternodes)
|
penMasternodes, err = x.HookPenaltyTIPSigning(chain, header, masternodes)
|
||||||
} else {
|
} else {
|
||||||
penMasternodes, err = c.HookPenalty(chain, number)
|
penMasternodes, err = x.HookPenalty(chain, number)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -760,15 +717,15 @@ func (c *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
|
||||||
}
|
}
|
||||||
// Prevent penalized masternode(s) within 4 recent epochs
|
// Prevent penalized masternode(s) within 4 recent epochs
|
||||||
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
|
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
|
||||||
if number > uint64(i)*c.config.Epoch {
|
if number > uint64(i)*x.config.Epoch {
|
||||||
masternodes = removePenaltiesFromBlock(chain, masternodes, number-uint64(i)*c.config.Epoch)
|
masternodes = removePenaltiesFromBlock(chain, masternodes, number-uint64(i)*x.config.Epoch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, masternode := range masternodes {
|
for _, masternode := range masternodes {
|
||||||
header.Extra = append(header.Extra, masternode[:]...)
|
header.Extra = append(header.Extra, masternode[:]...)
|
||||||
}
|
}
|
||||||
if c.HookValidator != nil {
|
if x.HookValidator != nil {
|
||||||
validators, err := c.HookValidator(header, masternodes)
|
validators, err := x.HookValidator(header, masternodes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -782,18 +739,18 @@ func (c *XDPoS_v1) Prepare(chain consensus.ChainReader, header *types.Header) er
|
||||||
|
|
||||||
// Ensure the timestamp has the correct delay
|
// Ensure the timestamp has the correct delay
|
||||||
|
|
||||||
header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(c.config.Period))
|
header.Time = new(big.Int).Add(parent.Time, new(big.Int).SetUint64(x.config.Period))
|
||||||
if header.Time.Int64() < time.Now().Unix() {
|
if header.Time.Int64() < time.Now().Unix() {
|
||||||
header.Time = big.NewInt(time.Now().Unix())
|
header.Time = big.NewInt(time.Now().Unix())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error {
|
func (x *XDPoS_v1) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []utils.Masternode) error {
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
log.Trace("take snapshot", "number", number, "hash", header.Hash())
|
log.Trace("take snapshot", "number", number, "hash", header.Hash())
|
||||||
// get snapshot
|
// get snapshot
|
||||||
snap, err := c.snapshot(chain, number, header.Hash(), nil)
|
snap, err := x.snapshot(chain, number, header.Hash(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -806,22 +763,22 @@ func (c *XDPoS_v1) UpdateMasternodes(chain consensus.ChainReader, header *types.
|
||||||
for _, n := range ms {
|
for _, n := range ms {
|
||||||
nm = append(nm, n.Address.String())
|
nm = append(nm, n.Address.String())
|
||||||
}
|
}
|
||||||
c.recents.Add(snap.Hash, snap)
|
x.recents.Add(snap.Hash, snap)
|
||||||
log.Info("New set of masternodes has been updated to snapshot", "number", snap.Number, "hash", snap.Hash, "new masternodes", nm)
|
log.Info("New set of masternodes has been updated to snapshot", "number", snap.Number, "hash", snap.Hash, "new masternodes", nm)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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_v1) 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 (x *XDPoS_v1) 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) {
|
||||||
// set block reward
|
// set block reward
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
rCheckpoint := chain.Config().XDPoS.RewardCheckpoint
|
rCheckpoint := chain.Config().XDPoS.RewardCheckpoint
|
||||||
|
|
||||||
// _ = c.CacheData(header, txs, receipts)
|
// _ = c.CacheData(header, txs, receipts)
|
||||||
|
|
||||||
if c.HookReward != nil && number%rCheckpoint == 0 {
|
if x.HookReward != nil && number%rCheckpoint == 0 {
|
||||||
err, rewards := c.HookReward(chain, state, parentState, header)
|
err, rewards := x.HookReward(chain, state, parentState, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -846,17 +803,17 @@ func (c *XDPoS_v1) Finalize(chain consensus.ChainReader, header *types.Header, s
|
||||||
|
|
||||||
// Authorize injects a private key into the consensus engine to mint new blocks
|
// Authorize injects a private key into the consensus engine to mint new blocks
|
||||||
// with.
|
// with.
|
||||||
func (c *XDPoS_v1) Authorize(signer common.Address, signFn clique.SignerFn) {
|
func (x *XDPoS_v1) Authorize(signer common.Address, signFn clique.SignerFn) {
|
||||||
c.lock.Lock()
|
x.lock.Lock()
|
||||||
defer c.lock.Unlock()
|
defer x.lock.Unlock()
|
||||||
|
|
||||||
c.signer = signer
|
x.signer = signer
|
||||||
c.signFn = signFn
|
x.signFn = signFn
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
|
func (x *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error) {
|
||||||
header := block.Header()
|
header := block.Header()
|
||||||
|
|
||||||
// Sealing the genesis block is not supported
|
// Sealing the genesis block is not supported
|
||||||
|
|
@ -866,20 +823,20 @@ func (c *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
|
||||||
}
|
}
|
||||||
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
// For 0-period chains, refuse to seal empty blocks (no reward but would spin sealing)
|
||||||
// checkpoint blocks have no tx
|
// checkpoint blocks have no tx
|
||||||
if c.config.Period == 0 && len(block.Transactions()) == 0 && number%c.config.Epoch != 0 {
|
if x.config.Period == 0 && len(block.Transactions()) == 0 && number%x.config.Epoch != 0 {
|
||||||
return nil, utils.ErrWaitTransactions
|
return nil, utils.ErrWaitTransactions
|
||||||
}
|
}
|
||||||
// Don't hold the signer fields for the entire sealing procedure
|
// Don't hold the signer fields for the entire sealing procedure
|
||||||
c.lock.RLock()
|
x.lock.RLock()
|
||||||
signer, signFn := c.signer, c.signFn
|
signer, signFn := x.signer, x.signFn
|
||||||
c.lock.RUnlock()
|
x.lock.RUnlock()
|
||||||
|
|
||||||
// Bail out if we're unauthorized to sign a block
|
// Bail out if we're unauthorized to sign a block
|
||||||
snap, err := c.snapshot(chain, number-1, header.ParentHash, nil)
|
snap, err := x.snapshot(chain, number-1, header.ParentHash, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
masternodes := c.GetMasternodes(chain, header)
|
masternodes := x.GetMasternodes(chain, header)
|
||||||
if _, authorized := snap.Signers[signer]; !authorized {
|
if _, authorized := snap.Signers[signer]; !authorized {
|
||||||
valid := false
|
valid := false
|
||||||
for _, m := range masternodes {
|
for _, m := range masternodes {
|
||||||
|
|
@ -901,7 +858,7 @@ func (c *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
|
||||||
// There is only case that we don't allow signer to create two continuous blocks.
|
// There is only case that we don't allow signer to create two continuous blocks.
|
||||||
if limit := uint64(2); number < limit || seen > number-limit {
|
if limit := uint64(2); number < limit || seen > number-limit {
|
||||||
// Only take into account the non-epoch blocks
|
// Only take into account the non-epoch blocks
|
||||||
if number%c.config.Epoch != 0 {
|
if number%x.config.Epoch != 0 {
|
||||||
log.Info("Signed recently, must wait for others ", "len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
|
log.Info("Signed recently, must wait for others ", "len(masternodes)", len(masternodes), "number", number, "limit", limit, "seen", seen, "recent", recent.String(), "snap.Recents", snap.Recents)
|
||||||
<-stop
|
<-stop
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
@ -916,12 +873,12 @@ 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
|
||||||
}
|
}
|
||||||
copy(header.Extra[len(header.Extra)-utils.ExtraSeal:], sighash)
|
copy(header.Extra[len(header.Extra)-utils.ExtraSeal:], sighash)
|
||||||
m2, err := c.GetValidator(signer, chain, header)
|
m2, err := x.GetValidator(signer, chain, header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get block validator: %v", err)
|
return nil, fmt.Errorf("can't get block validator: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -934,30 +891,30 @@ func (c *XDPoS_v1) Seal(chain consensus.ChainReader, block *types.Block, stop <-
|
||||||
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
// CalcDifficulty is the difficulty adjustment algorithm. It returns the difficulty
|
||||||
// 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_v1) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
|
func (x *XDPoS_v1) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
|
||||||
return c.calcDifficulty(chain, parent, c.signer)
|
return x.calcDifficulty(chain, parent, x.signer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) calcDifficulty(chain consensus.ChainReader, parent *types.Header, signer common.Address) *big.Int {
|
func (x *XDPoS_v1) calcDifficulty(chain consensus.ChainReader, parent *types.Header, signer common.Address) *big.Int {
|
||||||
// If we're running a engine faking, skip calculation
|
// If we're running a engine faking, skip calculation
|
||||||
if c.config.SkipValidation {
|
if x.config.SkipValidation {
|
||||||
return big.NewInt(1)
|
return big.NewInt(1)
|
||||||
}
|
}
|
||||||
len, preIndex, curIndex, _, err := c.YourTurn(chain, parent, signer)
|
len, preIndex, curIndex, _, err := x.YourTurn(chain, parent, signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return big.NewInt(int64(len + curIndex - preIndex))
|
return big.NewInt(int64(len + curIndex - preIndex))
|
||||||
}
|
}
|
||||||
return big.NewInt(int64(len - utils.Hop(len, preIndex, curIndex)))
|
return big.NewInt(int64(len - utils.Hop(len, preIndex, curIndex)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) RecoverSigner(header *types.Header) (common.Address, error) {
|
func (x *XDPoS_v1) RecoverSigner(header *types.Header) (common.Address, error) {
|
||||||
return ecrecover(header, c.signatures)
|
return ecrecover(header, x.signatures)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) RecoverValidator(header *types.Header) (common.Address, error) {
|
func (x *XDPoS_v1) RecoverValidator(header *types.Header) (common.Address, error) {
|
||||||
// If the signature's already cached, return that
|
// If the signature's already cached, return that
|
||||||
hash := header.Hash()
|
hash := header.Hash()
|
||||||
if address, known := c.validatorSignatures.Get(hash); known {
|
if address, known := x.validatorSignatures.Get(hash); known {
|
||||||
return address.(common.Address), nil
|
return address.(common.Address), nil
|
||||||
}
|
}
|
||||||
// Retrieve the signature from the header.Validator
|
// Retrieve the signature from the header.Validator
|
||||||
|
|
@ -966,19 +923,19 @@ 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
|
||||||
}
|
}
|
||||||
var signer common.Address
|
var signer common.Address
|
||||||
copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
|
copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
|
||||||
|
|
||||||
c.validatorSignatures.Add(hash, signer)
|
x.validatorSignatures.Add(hash, signer)
|
||||||
return signer, nil
|
return signer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get master nodes over extra data of previous checkpoint block.
|
// Get master nodes over extra data of previous checkpoint block.
|
||||||
func (c *XDPoS_v1) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
|
func (x *XDPoS_v1) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types.Header, n, e uint64) []common.Address {
|
||||||
if preCheckpointHeader == nil {
|
if preCheckpointHeader == nil {
|
||||||
log.Info("Previous checkpoint's header is empty", "block number", n, "epoch", e)
|
log.Info("Previous checkpoint's header is empty", "block number", n, "epoch", e)
|
||||||
return []common.Address{}
|
return []common.Address{}
|
||||||
|
|
@ -991,8 +948,8 @@ func (c *XDPoS_v1) GetMasternodesFromCheckpointHeader(preCheckpointHeader *types
|
||||||
return masternodes
|
return masternodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) GetDb() ethdb.Database {
|
func (x *XDPoS_v1) GetDb() ethdb.Database {
|
||||||
return c.db
|
return x.db
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract validators from byte array.
|
// Extract validators from byte array.
|
||||||
|
|
@ -1034,23 +991,23 @@ func GetM1M2FromCheckpointHeader(checkpointHeader *types.Header, currentHeader *
|
||||||
return m1m2, nil
|
return m1m2, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *XDPoS_v1) getSignersFromContract(chain consensus.ChainReader, checkpointHeader *types.Header) ([]common.Address, error) {
|
func (x *XDPoS_v1) getSignersFromContract(chain consensus.ChainReader, checkpointHeader *types.Header) ([]common.Address, error) {
|
||||||
startGapBlockHeader := checkpointHeader
|
startGapBlockHeader := checkpointHeader
|
||||||
number := checkpointHeader.Number.Uint64()
|
number := checkpointHeader.Number.Uint64()
|
||||||
for step := uint64(1); step <= chain.Config().XDPoS.Gap; step++ {
|
for step := uint64(1); step <= chain.Config().XDPoS.Gap; step++ {
|
||||||
startGapBlockHeader = chain.GetHeader(startGapBlockHeader.ParentHash, number-step)
|
startGapBlockHeader = chain.GetHeader(startGapBlockHeader.ParentHash, number-step)
|
||||||
}
|
}
|
||||||
signers, err := c.HookGetSignersFromContract(startGapBlockHeader.Hash())
|
signers, err := x.HookGetSignersFromContract(startGapBlockHeader.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []common.Address{}, fmt.Errorf("Can't get signers from Smart Contract . Err: %v", err)
|
return []common.Address{}, fmt.Errorf("Can't get signers from Smart Contract . Err: %v", err)
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,13 @@
|
||||||
package consensus
|
package consensus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
"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/params"
|
"github.com/XinFinOrg/XDPoSChain/params"
|
||||||
"github.com/XinFinOrg/XDPoSChain/rpc"
|
"github.com/XinFinOrg/XDPoSChain/rpc"
|
||||||
"math/big"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ChainReader defines a small collection of methods needed to access the local
|
// ChainReader defines a small collection of methods needed to access the local
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
30631
coverage.txt
File diff suppressed because it is too large
Load diff
2
go.mod
2
go.mod
|
|
@ -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
|
||||||
|
|
|
||||||
6
go.sum
6
go.sum
|
|
@ -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=
|
||||||
|
|
@ -255,11 +256,14 @@ github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8
|
||||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
||||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
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=
|
||||||
|
|
@ -347,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=
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,11 @@ import (
|
||||||
"github.com/XinFinOrg/XDPoSChain/common"
|
"github.com/XinFinOrg/XDPoSChain/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
ConsensusEngineVersion1 = "v1"
|
||||||
|
ConsensusEngineVersion2 = "v2"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
XDCMainnetGenesisHash = common.HexToHash("9326145f8a2c8c00bbe13afc7d7f3d9c868b5ef39d89f2f4e9390e9720298624") // XDC Mainnet genesis hash to enforce below configs on
|
XDCMainnetGenesisHash = common.HexToHash("9326145f8a2c8c00bbe13afc7d7f3d9c868b5ef39d89f2f4e9390e9720298624") // XDC Mainnet genesis hash to enforce below configs on
|
||||||
MainnetGenesisHash = common.HexToHash("8d13370621558f4ed0da587934473c0404729f28b0ff1d50e5fdd840457a2f17") // Mainnet genesis hash to enforce below configs on
|
MainnetGenesisHash = common.HexToHash("8d13370621558f4ed0da587934473c0404729f28b0ff1d50e5fdd840457a2f17") // Mainnet genesis hash to enforce below configs on
|
||||||
|
|
@ -111,10 +116,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 +177,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,8 +196,11 @@ 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) string {
|
||||||
return 1
|
if c.V2ConsensusBlockNumber != nil && num.Cmp(c.V2ConsensusBlockNumber) > 0 {
|
||||||
|
return ConsensusEngineVersion2
|
||||||
|
}
|
||||||
|
return ConsensusEngineVersion1
|
||||||
}
|
}
|
||||||
|
|
||||||
// String implements the fmt.Stringer interface.
|
// String implements the fmt.Stringer interface.
|
||||||
|
|
|
||||||
46
tests/consensus/adaptor_test.go
Normal file
46
tests/consensus/adaptor_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
|
@ -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 {
|
||||||
367
tests/consensus/test_helper.go
Normal file
367
tests/consensus/test_helper.go
Normal 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
|
||||||
|
// }
|
||||||
|
// */
|
||||||
Loading…
Reference in a new issue