mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
Merge branch 'forking-incident-fix' of https://github.com/hash-laboratories-au/XDPoSChain into hash-laboratories-au-forking-incident-fix
This commit is contained in:
commit
cf18ceba33
21 changed files with 1069 additions and 177 deletions
177
.travis.yml
177
.travis.yml
|
|
@ -1,110 +1,81 @@
|
|||
sudo: required
|
||||
language: go
|
||||
go_import_path: github.com/XinFinOrg/XDPoSChain
|
||||
|
||||
env:
|
||||
global:
|
||||
- GOPROXY=https://proxy.golang.org
|
||||
- GO111MODULE=on
|
||||
|
||||
|
||||
sudo: false
|
||||
jobs:
|
||||
include:
|
||||
|
||||
- stage: Lint
|
||||
sudo: false
|
||||
go: '1.12.x'
|
||||
git:
|
||||
submodules: false
|
||||
# This builder only tests code linters on latest version of Go
|
||||
- stage: lint
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- lint
|
||||
git:
|
||||
submodules: false # avoid cloning ethereum/tests
|
||||
script:
|
||||
- go run build/ci.go lint
|
||||
|
||||
- stage: Build and test
|
||||
go: '1.12.x'
|
||||
script:
|
||||
- sudo modprobe fuse
|
||||
- sudo chmod 666 /dev/fuse
|
||||
- sudo chown root:$USER /etc/fuse.conf
|
||||
- go run build/ci.go install
|
||||
- while sleep 540; do echo "[ still running ]"; done &
|
||||
- go run build/ci.go test -coverage
|
||||
- kill %1
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
|
||||
- go: '1.11.x'
|
||||
script:
|
||||
- sudo modprobe fuse
|
||||
- sudo chmod 666 /dev/fuse
|
||||
- sudo chown root:$USER /etc/fuse.conf
|
||||
- go run build/ci.go install
|
||||
- while sleep 540; do echo "[ still running ]"; done &
|
||||
- go run build/ci.go test -coverage
|
||||
- kill %1
|
||||
|
||||
- stage: Github release
|
||||
go: '1.12.x'
|
||||
script:
|
||||
- GOARCH=amd64 GOOS=linux go build -o ./build/bin/XDC-linux-amd64 -v ./cmd/XDC
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key: $GITHUB_TOKEN
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
file: build/bin/XDC-*
|
||||
skip_cleanup: true
|
||||
on:
|
||||
tags: true
|
||||
|
||||
- stage: Build and push image
|
||||
services:
|
||||
- docker
|
||||
install: skip
|
||||
before_script:
|
||||
- docker build -t XDPoSChain/XDPoSChain .
|
||||
- docker build -t XDPoSChain/node -f Dockerfile.node .
|
||||
script:
|
||||
- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
|
||||
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:latest
|
||||
- docker push XDPoSChain/XDPoSChain:latest
|
||||
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:$TRAVIS_BUILD_ID
|
||||
- docker push XDPoSChain/XDPoSChain:$TRAVIS_BUILD_ID
|
||||
- docker tag XDPoSChain/node XDPoSChain/node:latest
|
||||
- docker push XDPoSChain/node:latest
|
||||
- docker tag XDPoSChain/node XDPoSChain/node:$TRAVIS_BUILD_ID
|
||||
- docker push XDPoSChain/node:$TRAVIS_BUILD_ID
|
||||
|
||||
- stage: Build and push image (tagged)
|
||||
services:
|
||||
- docker
|
||||
install: skip
|
||||
before_script:
|
||||
- docker build -t XDPoSChain/XDPoSChain .
|
||||
- docker build -t XDPoSChain/XDPoSChain -f Dockerfile.node .
|
||||
script:
|
||||
- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
|
||||
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:latest
|
||||
- docker push XDPoSChain/XDPoSChain:latest
|
||||
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:$TRAVIS_TAG
|
||||
- docker push XDPoSChain/XDPoSChain:$TRAVIS_TAG
|
||||
- docker tag XDPoSChain/XDPoSChain XDPoSChain/node:latest
|
||||
- docker push XDPoSChain/node:latest
|
||||
- docker tag XDPoSChain/node XDPoSChain/node:$TRAVIS_TAG
|
||||
- docker push XDPoSChain/node:$TRAVIS_TAG
|
||||
|
||||
stages:
|
||||
- name: Lint
|
||||
- name: Build and test
|
||||
- name: Github release
|
||||
if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XDPoSChain/XDPoSChain
|
||||
- name: Build and push image
|
||||
if: type != pull_request AND branch = master AND tag IS blank AND repo = XDPoSChain/XDPoSChain
|
||||
- name: Build and push image (tagged)
|
||||
if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XDPoSChain/XDPoSChain
|
||||
|
||||
notifications:
|
||||
slack:
|
||||
rooms:
|
||||
secure:
|
||||
on_success: change
|
||||
on_failure: always
|
||||
- stage: Tests
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: A-B tests
|
||||
script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/[a-b].*")
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/c[a-m].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: C-[a-m] tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/c[n-o].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: C-[n-o] tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/c[p-z].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: C-[p-z] tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/[d-i].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: D-I tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/[j-n].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: J-N tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/[o-r].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: O-R tests
|
||||
- script: travis_retry go run build/ci.go test -v -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/s.*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: S tests
|
||||
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/ethereum\/go-ethereum\/[t-z].*")
|
||||
os: linux
|
||||
dist: bionic
|
||||
go: 1.14.x
|
||||
env:
|
||||
- GO111MODULE=auto
|
||||
name: T-Z tests
|
||||
|
|
@ -20,16 +20,18 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||
"math/big"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/common/math"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
|
||||
"github.com/XinFinOrg/XDPoSChain/consensus/ethash"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/bloombits"
|
||||
|
|
@ -64,6 +66,31 @@ type SimulatedBackend struct {
|
|||
config *params.ChainConfig
|
||||
}
|
||||
|
||||
// XDC simulated backend for testing purpose.
|
||||
func NewXDCSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
|
||||
// database := ethdb.NewMemDatabase()
|
||||
database := rawdb.NewMemoryDatabase()
|
||||
|
||||
genesis := core.Genesis{
|
||||
GasLimit: gasLimit, // need this big, support initial smart contract
|
||||
Config: params.TestXDPoSMockChainConfig,
|
||||
Alloc: alloc,
|
||||
ExtraData: append(make([]byte, 32), make([]byte, 65)...),
|
||||
}
|
||||
genesis.MustCommit(database)
|
||||
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, XDPoS.NewFaker(database), vm.Config{})
|
||||
|
||||
backend := &SimulatedBackend{
|
||||
database: database,
|
||||
blockchain: blockchain,
|
||||
config: genesis.Config,
|
||||
events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{database, blockchain}, false),
|
||||
}
|
||||
blockchain.Client = backend
|
||||
backend.rollback()
|
||||
return backend
|
||||
}
|
||||
|
||||
// NewSimulatedBackend creates a new binding backend using a simulated blockchain
|
||||
// for testing purposes.
|
||||
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
|
||||
|
|
@ -103,7 +130,7 @@ func (b *SimulatedBackend) Rollback() {
|
|||
}
|
||||
|
||||
func (b *SimulatedBackend) rollback() {
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(int, *core.BlockGen) {})
|
||||
statedb, _ := b.blockchain.State()
|
||||
|
||||
b.pendingBlock = blocks[0]
|
||||
|
|
@ -359,7 +386,8 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
|
|||
panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
|
||||
}
|
||||
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
// blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
for _, tx := range b.pendingBlock.Transactions() {
|
||||
block.AddTxWithChain(b.blockchain, tx)
|
||||
}
|
||||
|
|
@ -438,7 +466,8 @@ func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query XDPoSC
|
|||
func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
// blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), b.blockchain.Engine(), b.database, 1, func(number int, block *core.BlockGen) {
|
||||
for _, tx := range b.pendingBlock.Transactions() {
|
||||
block.AddTx(tx)
|
||||
}
|
||||
|
|
@ -452,6 +481,10 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *SimulatedBackend) GetBlockChain() *core.BlockChain {
|
||||
return b.blockchain
|
||||
}
|
||||
|
||||
// callmsg implements core.Message to allow passing it as a transaction simulator.
|
||||
type callmsg struct {
|
||||
XDPoSChain.CallMsg
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy an interaction tester contract and call a transaction on it
|
||||
_, _, interactor, err := DeployInteractor(auth, sim, "Deploy string")
|
||||
|
|
@ -270,7 +270,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a tuple tester contract and execute a structured call on it
|
||||
_, _, getter, err := DeployGetter(auth, sim)
|
||||
|
|
@ -302,7 +302,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a tuple tester contract and execute a structured call on it
|
||||
_, _, tupler, err := DeployTupler(auth, sim)
|
||||
|
|
@ -344,7 +344,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a slice tester contract and execute a n array call on it
|
||||
_, _, slicer, err := DeploySlicer(auth, sim)
|
||||
|
|
@ -378,7 +378,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a default method invoker contract and execute its default method
|
||||
_, _, defaulter, err := DeployDefaulter(auth, sim)
|
||||
|
|
@ -411,7 +411,7 @@ var bindTests = []struct {
|
|||
`[{"constant":true,"inputs":[],"name":"String","outputs":[{"name":"","type":"string"}],"type":"function"}]`,
|
||||
`
|
||||
// Create a simulator and wrap a non-deployed contract
|
||||
sim := backends.NewSimulatedBackend(nil)
|
||||
sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000))
|
||||
|
||||
nonexistent, err := NewNonExistent(common.Address{}, sim)
|
||||
if err != nil {
|
||||
|
|
@ -447,7 +447,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a funky gas pattern contract
|
||||
_, _, limiter, err := DeployFunkyGasPattern(auth, sim)
|
||||
|
|
@ -482,7 +482,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a sender tester contract and execute a structured call on it
|
||||
_, _, callfrom, err := DeployCallFrom(auth, sim)
|
||||
|
|
@ -542,7 +542,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy a underscorer tester contract and execute a structured call on it
|
||||
_, _, underscorer, err := DeployUnderscorer(auth, sim)
|
||||
|
|
@ -612,7 +612,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
// Deploy an eventer contract
|
||||
_, _, eventer, err := DeployEventer(auth, sim)
|
||||
|
|
@ -761,7 +761,7 @@ var bindTests = []struct {
|
|||
// Generate a new random account and a funded simulator
|
||||
key, _ := crypto.GenerateKey()
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
|
||||
sim := backends.NewXDCSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}}, 10000000)
|
||||
|
||||
//deploy the test contract
|
||||
_, _, testContract, err := DeployDeeplyNestedArray(auth, sim)
|
||||
|
|
|
|||
|
|
@ -53,9 +53,11 @@ var waitDeployedTests = map[string]struct {
|
|||
|
||||
func TestWaitDeployed(t *testing.T) {
|
||||
for name, test := range waitDeployedTests {
|
||||
backend := backends.NewSimulatedBackend(core.GenesisAlloc{
|
||||
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
|
||||
})
|
||||
backend := backends.NewXDCSimulatedBackend(
|
||||
core.GenesisAlloc{
|
||||
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
|
||||
}, 10000000,
|
||||
)
|
||||
|
||||
// Create the transaction.
|
||||
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code))
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ func (w *wizard) makeGenesis() {
|
|||
// Validator Smart Contract Code
|
||||
pKey, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
||||
addr := crypto.PubkeyToAddress(pKey.PublicKey)
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||
transactOpts := bind.NewKeyedTransactor(pKey)
|
||||
|
||||
validatorAddress, _, err := validatorContract.DeployValidator(transactOpts, contractBackend, signers, validatorCaps, owner)
|
||||
|
|
|
|||
|
|
@ -167,9 +167,16 @@ func BytesToAddress(b []byte) Address {
|
|||
a.SetBytes(b)
|
||||
return a
|
||||
}
|
||||
|
||||
func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
|
||||
func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
|
||||
func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
|
||||
|
||||
// BigToAddress returns Address with byte values of b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
|
||||
|
||||
// HexToAddress returns Address with byte values of s.
|
||||
// If s is larger than len(h), s will be cropped from the left.
|
||||
func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
|
||||
|
||||
// IsHexAddress verifies whether a string can represent a valid hex-encoded
|
||||
// Ethereum address or not.
|
||||
|
|
|
|||
|
|
@ -297,6 +297,32 @@ func New(config *params.XDPoSConfig, db ethdb.Database) *XDPoS {
|
|||
}
|
||||
}
|
||||
|
||||
// NewFullFaker creates an ethash consensus engine with a full fake scheme that
|
||||
// accepts all blocks as valid, without checking any consensus rules whatsoever.
|
||||
func NewFaker(db ethdb.Database) *XDPoS {
|
||||
var fakeEngine *XDPoS
|
||||
// Set any missing consensus parameters to their defaults
|
||||
conf := params.TestXDPoSMockChainConfig.XDPoS
|
||||
|
||||
// Allocate the snapshot caches and create the engine
|
||||
BlockSigners, _ := lru.New(blockSignersCacheLimit)
|
||||
recents, _ := lru.NewARC(inmemorySnapshots)
|
||||
signatures, _ := lru.NewARC(inmemorySnapshots)
|
||||
validatorSignatures, _ := lru.NewARC(inmemorySnapshots)
|
||||
verifiedHeaders, _ := lru.NewARC(inmemorySnapshots)
|
||||
fakeEngine = &XDPoS{
|
||||
config: conf,
|
||||
db: db,
|
||||
BlockSigners: BlockSigners,
|
||||
recents: recents,
|
||||
signatures: signatures,
|
||||
verifiedHeaders: verifiedHeaders,
|
||||
validatorSignatures: validatorSignatures,
|
||||
proposals: make(map[common.Address]bool),
|
||||
}
|
||||
return fakeEngine
|
||||
}
|
||||
|
||||
// Author implements consensus.Engine, returning the Ethereum address recovered
|
||||
// from the signature in the header's extra-data section.
|
||||
func (c *XDPoS) Author(header *types.Header) (common.Address, error) {
|
||||
|
|
@ -349,6 +375,10 @@ func (c *XDPoS) verifyHeaderWithCache(chain consensus.ChainReader, header *types
|
|||
// looking those up from the database. This is useful for concurrently verifying
|
||||
// a batch of new headers.
|
||||
func (c *XDPoS) 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 c.config.SkipValidation {
|
||||
return nil
|
||||
}
|
||||
if common.IsTestnet {
|
||||
fullVerify = false
|
||||
}
|
||||
|
|
@ -1084,6 +1114,10 @@ func (c *XDPoS) CalcDifficulty(chain consensus.ChainReader, time uint64, parent
|
|||
}
|
||||
|
||||
func (c *XDPoS) calcDifficulty(chain consensus.ChainReader, parent *types.Header, signer common.Address) *big.Int {
|
||||
// If we're running a engine faking, skip calculation
|
||||
if c.config.SkipValidation {
|
||||
return big.NewInt(1)
|
||||
}
|
||||
len, preIndex, curIndex, _, err := c.YourTurn(chain, parent, signer)
|
||||
if err != nil {
|
||||
return big.NewInt(int64(len + curIndex - preIndex))
|
||||
|
|
|
|||
|
|
@ -21,12 +21,13 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"math/rand"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -35,7 +36,7 @@ var (
|
|||
)
|
||||
|
||||
func TestBlockSigner(t *testing.T) {
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
|
||||
blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99))
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ var (
|
|||
)
|
||||
|
||||
func newTestBackend() *backends.SimulatedBackend {
|
||||
return backends.NewSimulatedBackend(core.GenesisAlloc{
|
||||
return backends.NewXDCSimulatedBackend(core.GenesisAlloc{
|
||||
addr0: {Balance: big.NewInt(1000000000)},
|
||||
addr1: {Balance: big.NewInt(1000000000)},
|
||||
addr2: {Balance: big.NewInt(1000000000)},
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ var (
|
|||
)
|
||||
|
||||
func TestENS(t *testing.T) {
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
|
||||
ensAddr, ens, err := DeployENS(transactOpts, contractBackend)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ var (
|
|||
)
|
||||
|
||||
func TestRandomize(t *testing.T) {
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}})
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(100000000000000)}}, 10000000)
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
transactOpts.GasLimit = 1000000
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,11 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
|
|
@ -27,10 +32,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -46,7 +47,7 @@ var (
|
|||
|
||||
func getCommonBackend() *backends.SimulatedBackend {
|
||||
genesis := core.GenesisAlloc{acc1Addr: {Balance: big.NewInt(1000000000000)}}
|
||||
backend := backends.NewSimulatedBackend(genesis)
|
||||
backend := backends.NewXDCSimulatedBackend(genesis, 10000000)
|
||||
backend.Commit()
|
||||
|
||||
return backend
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ var (
|
|||
)
|
||||
|
||||
func TestValidator(t *testing.T) {
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}})
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||
transactOpts := bind.NewKeyedTransactor(key)
|
||||
|
||||
validatorCap := new(big.Int)
|
||||
|
|
@ -82,7 +82,7 @@ func TestValidator(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRewardBalance(t *testing.T) {
|
||||
contractBackend := backends.NewSimulatedBackend(core.GenesisAlloc{
|
||||
contractBackend := backends.NewXDCSimulatedBackend(core.GenesisAlloc{
|
||||
acc1Addr: {Balance: new(big.Int).SetUint64(10000000)},
|
||||
acc2Addr: {Balance: new(big.Int).SetUint64(10000000)},
|
||||
acc4Addr: {Balance: new(big.Int).SetUint64(10000000)},
|
||||
|
|
|
|||
|
|
@ -152,10 +152,10 @@ type BlockChain struct {
|
|||
validator Validator // block and state validator interface
|
||||
vmConfig vm.Config
|
||||
|
||||
badBlocks *lru.Cache // Bad block cache
|
||||
IPCEndpoint string
|
||||
Client *ethclient.Client // Global ipc client instance.
|
||||
|
||||
badBlocks *lru.Cache // Bad block cache
|
||||
shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
|
||||
IPCEndpoint string
|
||||
Client bind.ContractBackend // Global ipc client instance.
|
||||
// Blocks hash array by block number
|
||||
// cache field for tracking finality purpose, can't use for tracking block vs block relationship
|
||||
blocksHashCache *lru.Cache
|
||||
|
|
@ -1362,6 +1362,13 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
|
|||
// Set new head.
|
||||
if status == CanonStatTy {
|
||||
bc.insert(block)
|
||||
// prepare set of masternodes for the next epoch
|
||||
if bc.chainConfig.XDPoS != nil && ((block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap)) {
|
||||
err := bc.UpdateM1()
|
||||
if err != nil {
|
||||
log.Crit("Error when update masternodes set. Stopping node", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// save cache BlockSigners
|
||||
if bc.chainConfig.XDPoS != nil && bc.chainConfig.IsTIPSigning(block.Number()) {
|
||||
|
|
@ -1695,13 +1702,6 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
|
|||
CheckpointCh <- 1
|
||||
|
||||
}
|
||||
// prepare set of masternodes for the next epoch
|
||||
if (chain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap) {
|
||||
err := bc.UpdateM1()
|
||||
if err != nil {
|
||||
log.Crit("Error when update masternodes set. Stopping node", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Append a single chain head event if we've progressed the chain
|
||||
|
|
@ -2039,14 +2039,6 @@ func (bc *BlockChain) insertBlock(block *types.Block) ([]interface{}, []*types.L
|
|||
CheckpointCh <- 1
|
||||
|
||||
}
|
||||
// prepare set of masternodes for the next epoch
|
||||
if (block.NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap) {
|
||||
err := bc.UpdateM1()
|
||||
if err != nil {
|
||||
log.Error("Error when update masternodes set. Stopping node", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Append a single chain head event if we've progressed the chain
|
||||
if status == CanonStatTy && bc.CurrentBlock().Hash() == block.Hash() {
|
||||
|
|
@ -2193,6 +2185,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
|
|||
return err
|
||||
}
|
||||
addedTxs = append(addedTxs, newChain[i].Transactions()...)
|
||||
// prepare set of masternodes for the next epoch
|
||||
if bc.chainConfig.XDPoS != nil && ((newChain[i].NumberU64() % bc.chainConfig.XDPoS.Epoch) == (bc.chainConfig.XDPoS.Epoch - bc.chainConfig.XDPoS.Gap)) {
|
||||
err := bc.UpdateM1()
|
||||
if err != nil {
|
||||
log.Crit("Error when update masternodes set. Stopping node", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// calculate the difference between deleted and added transactions
|
||||
diff := types.TxDifference(deletedTxs, addedTxs)
|
||||
|
|
@ -2428,7 +2427,7 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript
|
|||
}
|
||||
|
||||
// Get current IPC Client.
|
||||
func (bc *BlockChain) GetClient() (*ethclient.Client, error) {
|
||||
func (bc *BlockChain) GetClient() (bind.ContractBackend, error) {
|
||||
if bc.Client == nil {
|
||||
// Inject ipc client global instance.
|
||||
client, err := ethclient.Dial(bc.IPCEndpoint)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import (
|
|||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx"
|
||||
|
||||
|
|
@ -45,7 +46,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/gasprice"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethclient"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/event"
|
||||
"github.com/XinFinOrg/XDPoSChain/log"
|
||||
|
|
@ -253,7 +253,8 @@ func (b *EthApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
|
|||
}
|
||||
}
|
||||
|
||||
func (b *EthApiBackend) GetIPCClient() (*ethclient.Client, error) {
|
||||
func (b *EthApiBackend) GetIPCClient() (bind.ContractBackend, error) {
|
||||
// func (b *EthApiBackend) GetIPCClient() (*ethclient.Client, error) {
|
||||
client, err := b.eth.blockchain.GetClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ package ethapi
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
|
||||
"math/big"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx"
|
||||
|
||||
|
|
@ -33,7 +35,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethclient"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/event"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
|
|
@ -83,7 +84,7 @@ type Backend interface {
|
|||
|
||||
ChainConfig() *params.ChainConfig
|
||||
CurrentBlock() *types.Block
|
||||
GetIPCClient() (*ethclient.Client, error)
|
||||
GetIPCClient() (bind.ContractBackend, error)
|
||||
GetEngine() consensus.Engine
|
||||
GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,14 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
|
|
@ -39,7 +41,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/core/vm"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/downloader"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/gasprice"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethclient"
|
||||
"github.com/XinFinOrg/XDPoSChain/ethdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/event"
|
||||
"github.com/XinFinOrg/XDPoSChain/light"
|
||||
|
|
@ -214,7 +215,9 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
|
|||
}
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetIPCClient() (*ethclient.Client, error) {
|
||||
// func (b *LesApiBackend) GetIPCClient() (*ethclient.Client, error) {
|
||||
func (b *LesApiBackend) GetIPCClient() (bind.ContractBackend, error) {
|
||||
// func (b *LesApiBackend) GetIPCClient() (bind.ContractBackend, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import (
|
|||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
|
||||
"math/big"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
|
@ -384,14 +383,6 @@ func (self *worker) wait() {
|
|||
if (block.NumberU64() % work.config.XDPoS.Epoch) == 0 {
|
||||
core.CheckpointCh <- 1
|
||||
}
|
||||
// prepare set of masternodes for the next epoch
|
||||
if (block.NumberU64() % work.config.XDPoS.Epoch) == (work.config.XDPoS.Epoch - work.config.XDPoS.Gap) {
|
||||
err := self.chain.UpdateM1()
|
||||
if err != nil {
|
||||
log.Error("Error when update masternodes set. Stopping node", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.chain.UpdateBlocksHashCache(block)
|
||||
self.chain.PostChainEvents(events, logs)
|
||||
|
|
|
|||
|
|
@ -111,8 +111,12 @@ var (
|
|||
// 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}}
|
||||
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}
|
||||
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))
|
||||
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")}}
|
||||
// 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}}
|
||||
// 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}
|
||||
TestRules = TestChainConfig.Rules(new(big.Int))
|
||||
)
|
||||
|
||||
// ChainConfig is the core config which determines the blockchain settings.
|
||||
|
|
@ -171,6 +175,7 @@ type XDPoSConfig struct {
|
|||
RewardCheckpoint uint64 `json:"rewardCheckpoint"` // Checkpoint block for calculate rewards.
|
||||
Gap uint64 `json:"gap"` // Gap time preparing for the next epoch
|
||||
FoudationWalletAddr common.Address `json:"foudationWalletAddr"` // Foundation Address Wallet
|
||||
SkipValidation bool //Skip Block Validation for testing purpose
|
||||
}
|
||||
|
||||
// String implements the stringer interface, returning the consensus engine details.
|
||||
|
|
|
|||
842
tests/block_signer_test.go
Normal file
842
tests/block_signer_test.go
Normal file
|
|
@ -0,0 +1,842 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
. "github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/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: uint64(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(), bc, &header.Coinbase, gp, statedb, &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
|
||||
func TestNotUpdateSignerListIfNotOnGapBlock(t *testing.T) {
|
||||
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, 400)
|
||||
parentSigners, err := GetSnapshotSigner(blockchain, parentBlock.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("Inserting block with propose at 401")
|
||||
blockCoinbaseA := "0xaaa0000000000000000000000000000000000401"
|
||||
tx, err := voteTX(37117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
//Get from block validator error message
|
||||
merkleRoot := "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
blockA, err := insertBlockTxs(blockchain, 401, blockCoinbaseA, parentBlock, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err := GetSnapshotSigner(blockchain, blockA.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if signers[acc1Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should NOT sit in the signer list")
|
||||
}
|
||||
eq := reflect.DeepEqual(parentSigners, signers)
|
||||
if eq {
|
||||
t.Logf("Signers unchanged")
|
||||
} else {
|
||||
t.Fatalf("Singers should not be changed!")
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
blockchain, _, parentBlock := PrepareXDCTestBlockChain(t, GAP-1)
|
||||
// Insert block 450
|
||||
blockCoinBase := fmt.Sprintf("0x111000000000000000000000000000000%03d", 450)
|
||||
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
|
||||
block, err := insertBlock(blockchain, 450, blockCoinBase, parentBlock, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
parentSigners, err := GetSnapshotSigner(blockchain, parentBlock.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signers, err := GetSnapshotSigner(blockchain, block.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
eq := reflect.DeepEqual(parentSigners, signers)
|
||||
if eq {
|
||||
t.Logf("Signers unchanged")
|
||||
} else {
|
||||
t.Fatalf("Singers should not be changed!")
|
||||
}
|
||||
}
|
||||
|
||||
//Should call updateM1 at gap block, and update the snapshot if there are SM transactions involved
|
||||
func TestUpdateSignerListIfVotedBeforeGap(t *testing.T) {
|
||||
|
||||
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-2)
|
||||
// Insert first Block 449
|
||||
t.Logf("Inserting block with propose at 449...")
|
||||
blockCoinbaseA := "0xaaa0000000000000000000000000000000000449"
|
||||
tx, err := voteTX(37117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
//Get from block validator error message
|
||||
merkleRoot := "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
block449, err := insertBlockTxs(blockchain, 449, blockCoinbaseA, parentBlock, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
parentBlock = block449
|
||||
|
||||
signers, err := GetSnapshotSigner(blockchain, block449.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// At block 449, we should not update signerList. we need to update it till block 450 gap block.
|
||||
// Acc3 is the default account that is on the signerList
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should sit in the signer list")
|
||||
}
|
||||
if signers[acc1Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
// Now, let's mine another block to trigger the GAP block signerList update
|
||||
block450CoinbaseAddress := "0xaaa0000000000000000000000000000000000450"
|
||||
merkleRoot = "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
block450, err := insertBlock(blockchain, 450, block450CoinbaseAddress, parentBlock, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block450.Header())
|
||||
// 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 {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should NOT sit in the signer list")
|
||||
}
|
||||
if signers[acc1Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should sit in the signer list")
|
||||
}
|
||||
}
|
||||
|
||||
//Should call updateM1 before gap block, and update the snapshot if there are SM transactions involved
|
||||
func TestCallUpdateM1WithSmartContractTranscation(t *testing.T) {
|
||||
|
||||
blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1)
|
||||
// Insert first Block 450 A
|
||||
t.Logf("Inserting block with propose at 450 A...")
|
||||
blockCoinbaseA := "0xaaa0000000000000000000000000000000000450"
|
||||
tx, err := voteTX(37117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
//Get from block validator error message
|
||||
merkleRoot := "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
blockA, err := insertBlockTxs(blockchain, 450, blockCoinbaseA, currentBlock, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err := GetSnapshotSigner(blockchain, blockA.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc1Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should sit in the signer list")
|
||||
}
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
blockchain, backend, currentBlock := PrepareXDCTestBlockChain(t, GAP-1)
|
||||
// Check initial signer, by default, acc3 is in the signerList
|
||||
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc3 should sit in the signer list")
|
||||
}
|
||||
if (signers[acc1Addr.Hex()] == true) || (signers[acc2Addr.Hex()] == true) {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,2should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
// Insert first Block 450 A
|
||||
t.Logf("Inserting block with propose at 450 A...")
|
||||
blockCoinbaseA := "0xaaa0000000000000000000000000000000000450"
|
||||
tx, err := voteTX(37117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
merkleRoot := "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
blockA, err := insertBlockTxs(blockchain, 450, blockCoinbaseA, currentBlock, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, blockA.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc1Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should sit in the signer list")
|
||||
}
|
||||
if signers[acc2Addr.Hex()] == true || signers[acc3Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 2,3 should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
// Insert forked Block 450 B
|
||||
t.Logf("Inserting block with propose for acc2 at 450 B...")
|
||||
|
||||
blockCoinBase450B := "0xbbb0000000000000000000000000000000000450"
|
||||
tx, err = voteTX(37117, 0, acc2Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
merkleRoot = "068dfa09d7b4093441c0cc4d9807a71bc586f6101c072d939b214c21cd136eb3"
|
||||
block450B, err := insertBlockTxs(blockchain, 450, blockCoinBase450B, currentBlock, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
||||
}
|
||||
if (signers[acc1Addr.Hex()] == true) || (signers[acc2Addr.Hex()] == true) {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,2should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
//Insert block 451 parent is 451 B
|
||||
t.Logf("Inserting block with propose at 451 B...")
|
||||
|
||||
blockCoinBase451B := "0xbbb0000000000000000000000000000000000451"
|
||||
merkleRoot = "068dfa09d7b4093441c0cc4d9807a71bc586f6101c072d939b214c21cd136eb3"
|
||||
block451B, err := insertBlock(blockchain, 451, blockCoinBase451B, block450B, merkleRoot)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 2 should sit in the signer list")
|
||||
}
|
||||
if signers[acc1Addr.Hex()] == true || signers[acc3Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,3should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block451B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 2 should sit in the signer list")
|
||||
}
|
||||
if signers[acc1Addr.Hex()] == true || signers[acc3Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,3should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc2Addr should sit in the signer list")
|
||||
}
|
||||
if signers[acc1Addr.Hex()] == true || signers[acc3Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,3should NOT sit in the signer list")
|
||||
}
|
||||
}
|
||||
|
||||
func TestStatesShouldBeUpdatedWhenForkedBlockBecameMainChainAtGapBlock(t *testing.T) {
|
||||
|
||||
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1)
|
||||
|
||||
state, err := blockchain.State()
|
||||
t.Logf("Account %v have balance of: %v", acc1Addr.String(), state.GetBalance(acc1Addr))
|
||||
// Check initial signer
|
||||
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc3Addr should sit in the signer list")
|
||||
}
|
||||
|
||||
// Insert first Block 450 A
|
||||
t.Logf("Inserting block with propose and transfer at 450 A...")
|
||||
blockCoinbaseA := "0xaaa0000000000000000000000000000000000450"
|
||||
tx, err := voteTX(58117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
transferTransaction := transferTx(t, acc1Addr, 999)
|
||||
|
||||
merkleRoot := "ea465415b60d88429f181fec9fae67c0f19cbf5a4fa10971d96d4faa57d96ffa"
|
||||
blockA, err := insertBlockTxs(blockchain, 450, blockCoinbaseA, parentBlock, []*types.Transaction{tx, transferTransaction}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
state, err = blockchain.State()
|
||||
t.Log("After transfer transaction at block 450 A, Account 1 have balance of: ", state.GetBalance(acc1Addr))
|
||||
|
||||
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000999)) != 0 {
|
||||
t.Fatalf("account 1 should have 10000000999 in balance")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, blockA.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc1Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should sit in the signer list")
|
||||
}
|
||||
|
||||
// Insert forked Block 450 B
|
||||
t.Logf("Inserting block with propose at 450 B...")
|
||||
|
||||
blockCoinBase450B := "0xbbb0000000000000000000000000000000000450"
|
||||
tx, err = voteTX(37117, 0, acc2Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
transferTransaction = transferTx(t, acc1Addr, 888)
|
||||
|
||||
merkleRoot = "184edaddeafc2404248f896ae46be503ae68949896c8eb6b6ad43695581e5022"
|
||||
block450B, err := insertBlockTxs(blockchain, 450, blockCoinBase450B, parentBlock, []*types.Transaction{tx, transferTransaction}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
state, err = blockchain.State()
|
||||
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")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Should not run the `updateM1` for forked chain, hence account3 still exit
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
||||
}
|
||||
|
||||
//Insert block 451 parent is 451 B
|
||||
t.Logf("Inserting block with propose at 451 B...")
|
||||
|
||||
blockCoinBase451B := "0xbbb0000000000000000000000000000000000451"
|
||||
merkleRoot = "184edaddeafc2404248f896ae46be503ae68949896c8eb6b6ad43695581e5022"
|
||||
block451B, err := insertBlock(blockchain, 451, blockCoinBase451B, block450B, merkleRoot)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block450B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 2 should sit in the signer list")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, block451B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 2 should sit in the signer list")
|
||||
}
|
||||
|
||||
signers, err = GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc2Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc2Addr should sit in the signer list")
|
||||
}
|
||||
state, err = blockchain.State()
|
||||
t.Log("After transfer transaction at block 450 B and the B fork has been merged into main chain, Account 1 have balance of: ", state.GetBalance(acc1Addr))
|
||||
|
||||
if state.GetBalance(acc1Addr).Cmp(new(big.Int).SetUint64(10000000888)) != 0 {
|
||||
t.Fatalf("account 1 should have 10000000888 in balance")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVoteShouldNotBeAffectedByFork(t *testing.T) {
|
||||
blockchain, backend, parentBlock := PrepareXDCTestBlockChain(t, GAP-1)
|
||||
// Check initial signer, by default, acc3 is in the signerList
|
||||
signers, err := GetSnapshotSigner(blockchain, blockchain.CurrentBlock().Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc3 should sit in the signer list")
|
||||
}
|
||||
if (signers[acc1Addr.Hex()] == true) || (signers[acc2Addr.Hex()] == true) {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("acc1,2should NOT sit in the signer list")
|
||||
}
|
||||
|
||||
// Insert normal blocks 450 A
|
||||
blockCoinBase450A := "0xaaa0000000000000000000000000000000000450"
|
||||
merkleRoot := "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
|
||||
block450A, err := insertBlock(blockchain, 450, blockCoinBase450A, parentBlock, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Insert 451 A with vote
|
||||
blockCoinbase451A := "0xaaa0000000000000000000000000000000000451"
|
||||
tx, err := voteTX(37117, 0, acc1Addr.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
merkleRoot = "46234e9cd7e85a267f7f0435b15256a794a2f6d65cc98cdbd21dcd10a01d9772"
|
||||
block451A, err := insertBlockTxs(blockchain, 451, blockCoinbase451A, block450A, []*types.Transaction{tx}, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// SignerList should be unchanged as the vote happen after GAP block
|
||||
signers, err = GetSnapshotSigner(blockchain, block451A.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if signers[acc1Addr.Hex()] == true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 1 should NOT sit in the signer list")
|
||||
}
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should sit in the signer list")
|
||||
}
|
||||
|
||||
// Now, we going to inject normal blocks of 450B, 451B and 452B. Because it's the longest, it will become the mainchain
|
||||
// Insert forked Block 450 B
|
||||
blockCoinBase450B := "0xbbb0000000000000000000000000000000000450"
|
||||
merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
|
||||
block450B, err := insertBlock(blockchain, 450, blockCoinBase450B, parentBlock, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
blockCoinBase451B := "0xbbb0000000000000000000000000000000000451"
|
||||
merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
|
||||
block451B, err := insertBlock(blockchain, 451, blockCoinBase451B, block450B, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
blockCoinBase452B := "0xbbb0000000000000000000000000000000000452"
|
||||
merkleRoot = "35999dded35e8db12de7e6c1471eb9670c162eec616ecebbaf4fddd4676fb930"
|
||||
block452B, err := insertBlock(blockchain, 452, blockCoinBase452B, block451B, merkleRoot)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
signers, err = GetSnapshotSigner(blockchain, block452B.Header())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Should run the `updateM1` for forked chain, but it should not be affected by the voted block 451A which is not on the mainchain anymore
|
||||
if signers[acc3Addr.Hex()] != true {
|
||||
debugMessage(backend, signers, t)
|
||||
t.Fatalf("account 3 should sit in the signer list as previos block result")
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue