Merge pull request #135 from olumuyiwadad/new_EVM_Upgrade

Merge branch 'forking-incident-fix'  @hash-laboratories-au
This commit is contained in:
Anil Chinchawale 2021-10-07 12:37:36 +05:30 committed by GitHub
commit a0046ff4be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1102 additions and 141 deletions

View file

@ -13,39 +13,80 @@ jobs:
- stage: Lint - stage: Lint
sudo: false sudo: false
go: '1.12.x' go: '1.14.x'
git: git:
submodules: false submodules: false
script: script:
- go run build/ci.go lint - go run build/ci.go lint
- stage: Build and test - stage: Tests
go: '1.12.x' os: linux
script: dist: bionic
- sudo modprobe fuse go: 1.14.x
- sudo chmod 666 /dev/fuse env:
- sudo chown root:$USER /etc/fuse.conf - GO111MODULE=auto
- go run build/ci.go install name: A-B tests
- while sleep 540; do echo "[ still running ]"; done & script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/[a-b].*")
- go run build/ci.go test -coverage - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[a-m].*")
- kill %1 os: linux
after_success: dist: bionic
- bash <(curl -s https://codecov.io/bash) go: 1.14.x
env:
- go: '1.11.x' - GO111MODULE=auto
script: name: C-[a-m] tests
- sudo modprobe fuse - script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/c[n-o].*")
- sudo chmod 666 /dev/fuse os: linux
- sudo chown root:$USER /etc/fuse.conf dist: bionic
- go run build/ci.go install go: 1.14.x
- while sleep 540; do echo "[ still running ]"; done & env:
- go run build/ci.go test -coverage - GO111MODULE=auto
- kill %1 name: C-[n-o] tests
- script: travis_retry go run build/ci.go test -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/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\/XinFinOrg\/XDPoSChain\/[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\/XinFinOrg\/XDPoSChain\/[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\/XinFinOrg\/XDPoSChain\/[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 -coverage $(go list ./... | grep "github.com\/XinFinOrg\/XDPoSChain\/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\/XinFinOrg\/XDPoSChain\/[t-z].*")
os: linux
dist: bionic
go: 1.14.x
env:
- GO111MODULE=auto
name: T-Z tests
- stage: Github release - stage: Github release
go: '1.12.x' go: '1.14.x'
script: script:
- GOARCH=amd64 GOOS=linux go build -o ./build/bin/XDC-linux-amd64 -v ./cmd/XDC - GOARCH=amd64 GOOS=linux go build -o ./build/bin/XDC-linux-amd64 ./cmd/XDC
deploy: deploy:
provider: releases provider: releases
api_key: $GITHUB_TOKEN api_key: $GITHUB_TOKEN
@ -61,46 +102,46 @@ jobs:
- docker - docker
install: skip install: skip
before_script: before_script:
- docker build -t XDPoSChain/XDPoSChain . - docker build -t XinFinOrg/XDPoSChain .
- docker build -t XDPoSChain/node -f Dockerfile.node . - docker build -t XinFinOrg/node -f Dockerfile.node .
script: script:
- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin - echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:latest - docker tag XinFinOrg/XDPoSChain XinFinOrg/XDPoSChain:latest
- docker push XDPoSChain/XDPoSChain:latest - docker push XinFinOrg/XDPoSChain:latest
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:$TRAVIS_BUILD_ID - docker tag XinFinOrg/XDPoSChain XinFinOrg/XDPoSChain:$TRAVIS_BUILD_ID
- docker push XDPoSChain/XDPoSChain:$TRAVIS_BUILD_ID - docker push XinFinOrg/XDPoSChain:$TRAVIS_BUILD_ID
- docker tag XDPoSChain/node XDPoSChain/node:latest - docker tag XinFinOrg/node XinFinOrg/node:latest
- docker push XDPoSChain/node:latest - docker push XinFinOrg/node:latest
- docker tag XDPoSChain/node XDPoSChain/node:$TRAVIS_BUILD_ID - docker tag XinFinOrg/node XinFinOrg/node:$TRAVIS_BUILD_ID
- docker push XDPoSChain/node:$TRAVIS_BUILD_ID - docker push XinFinOrg/node:$TRAVIS_BUILD_ID
- stage: Build and push image (tagged) - stage: Build and push image (tagged)
services: services:
- docker - docker
install: skip install: skip
before_script: before_script:
- docker build -t XDPoSChain/XDPoSChain . - docker build -t XinFinOrg/XDPoSChain .
- docker build -t XDPoSChain/XDPoSChain -f Dockerfile.node . - docker build -t XinFinOrg/XDPoSChain -f Dockerfile.node .
script: script:
- echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin - echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:latest - docker tag XinFinOrg/XDPoSChain XinFinOrg/XDPoSChain:latest
- docker push XDPoSChain/XDPoSChain:latest - docker push XinFinOrg/XDPoSChain:latest
- docker tag XDPoSChain/XDPoSChain XDPoSChain/XDPoSChain:$TRAVIS_TAG - docker tag XinFinOrg/XDPoSChain XinFinOrg/XDPoSChain:$TRAVIS_TAG
- docker push XDPoSChain/XDPoSChain:$TRAVIS_TAG - docker push XinFinOrg/XDPoSChain:$TRAVIS_TAG
- docker tag XDPoSChain/XDPoSChain XDPoSChain/node:latest - docker tag XinFinOrg/XDPoSChain XinFinOrg/node:latest
- docker push XDPoSChain/node:latest - docker push XinFinOrg/node:latest
- docker tag XDPoSChain/node XDPoSChain/node:$TRAVIS_TAG - docker tag XinFinOrg/node XinFinOrg/node:$TRAVIS_TAG
- docker push XDPoSChain/node:$TRAVIS_TAG - docker push XinFinOrg/node:$TRAVIS_TAG
stages: stages:
- name: Lint - name: Lint
- name: Build and test - name: Build and test
- name: Github release - name: Github release
if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XDPoSChain/XDPoSChain if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XinFinOrg/XDPoSChain
- name: Build and push image - name: Build and push image
if: type != pull_request AND branch = master AND tag IS blank AND repo = XDPoSChain/XDPoSChain if: type != pull_request AND branch = master AND tag IS blank AND repo = XinFinOrg/XDPoSChain
- name: Build and push image (tagged) - name: Build and push image (tagged)
if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XDPoSChain/XDPoSChain if: type != pull_request AND branch =~ ^v AND tag IS present AND repo = XinFinOrg/XDPoSChain
notifications: notifications:
slack: slack:

View file

@ -20,16 +20,18 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"math/big" "math/big"
"sync" "sync"
"time" "time"
"github.com/XinFinOrg/XDPoSChain/consensus"
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
"github.com/XinFinOrg/XDPoSChain" "github.com/XinFinOrg/XDPoSChain"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
"github.com/XinFinOrg/XDPoSChain/common/math" "github.com/XinFinOrg/XDPoSChain/common/math"
"github.com/XinFinOrg/XDPoSChain/consensus/XDPoS"
"github.com/XinFinOrg/XDPoSChain/consensus/ethash" "github.com/XinFinOrg/XDPoSChain/consensus/ethash"
"github.com/XinFinOrg/XDPoSChain/core" "github.com/XinFinOrg/XDPoSChain/core"
"github.com/XinFinOrg/XDPoSChain/core/bloombits" "github.com/XinFinOrg/XDPoSChain/core/bloombits"
@ -64,6 +66,31 @@ type SimulatedBackend struct {
config *params.ChainConfig 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 // NewSimulatedBackend creates a new binding backend using a simulated blockchain
// for testing purposes. // for testing purposes.
func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend { func NewSimulatedBackend(alloc core.GenesisAlloc) *SimulatedBackend {
@ -103,7 +130,7 @@ func (b *SimulatedBackend) Rollback() {
} }
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() statedb, _ := b.blockchain.State()
b.pendingBlock = blocks[0] 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)) 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() { for _, tx := range b.pendingBlock.Transactions() {
block.AddTxWithChain(b.blockchain, tx) 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 { func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
b.mu.Lock() b.mu.Lock()
defer b.mu.Unlock() 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() { for _, tx := range b.pendingBlock.Transactions() {
block.AddTx(tx) block.AddTx(tx)
} }
@ -452,6 +481,10 @@ func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
return nil return nil
} }
func (b *SimulatedBackend) GetBlockChain() *core.BlockChain {
return b.blockchain
}
// callmsg implements core.Message to allow passing it as a transaction simulator. // callmsg implements core.Message to allow passing it as a transaction simulator.
type callmsg struct { type callmsg struct {
XDPoSChain.CallMsg XDPoSChain.CallMsg

View file

@ -229,7 +229,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.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 // 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 +270,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.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 // Deploy a tuple tester contract and execute a structured call on it
_, _, getter, err := DeployGetter(auth, sim) _, _, getter, err := DeployGetter(auth, sim)
@ -302,7 +302,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.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 // Deploy a tuple tester contract and execute a structured call on it
_, _, tupler, err := DeployTupler(auth, sim) _, _, tupler, err := DeployTupler(auth, sim)
@ -344,7 +344,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.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 // 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 +378,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.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 // Deploy a default method invoker contract and execute its default method
_, _, defaulter, err := DeployDefaulter(auth, sim) _, _, defaulter, err := DeployDefaulter(auth, sim)
@ -411,7 +411,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.NewSimulatedBackend(nil) sim := backends.NewXDCSimulatedBackend(nil, uint64(10000000000))
nonexistent, err := NewNonExistent(common.Address{}, sim) nonexistent, err := NewNonExistent(common.Address{}, sim)
if err != nil { if err != nil {
@ -447,7 +447,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.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 // Deploy a funky gas pattern contract
_, _, limiter, err := DeployFunkyGasPattern(auth, sim) _, _, limiter, err := DeployFunkyGasPattern(auth, sim)
@ -482,7 +482,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.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 // Deploy a sender tester contract and execute a structured call on it
_, _, callfrom, err := DeployCallFrom(auth, sim) _, _, callfrom, err := DeployCallFrom(auth, sim)
@ -542,7 +542,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.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 // Deploy a underscorer tester contract and execute a structured call on it
_, _, underscorer, err := DeployUnderscorer(auth, sim) _, _, underscorer, err := DeployUnderscorer(auth, sim)
@ -612,7 +612,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.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 // Deploy an eventer contract
_, _, eventer, err := DeployEventer(auth, sim) _, _, eventer, err := DeployEventer(auth, sim)
@ -761,7 +761,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.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 //deploy the test contract
_, _, testContract, err := DeployDeeplyNestedArray(auth, sim) _, _, testContract, err := DeployDeeplyNestedArray(auth, sim)

View file

@ -53,9 +53,11 @@ var waitDeployedTests = map[string]struct {
func TestWaitDeployed(t *testing.T) { func TestWaitDeployed(t *testing.T) {
for name, test := range waitDeployedTests { for name, test := range waitDeployedTests {
backend := backends.NewSimulatedBackend(core.GenesisAlloc{ backend := backends.NewXDCSimulatedBackend(
crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)}, core.GenesisAlloc{
}) crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000)},
}, 10000000,
)
// Create the transaction. // Create the transaction.
tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code)) tx := types.NewContractCreation(0, big.NewInt(0), test.gas, big.NewInt(1), common.FromHex(test.code))

View file

@ -4,11 +4,11 @@ The passphrase that unlocks them is "foobar".
The "good" key files which are supposed to be loadable are: The "good" key files which are supposed to be loadable are:
- File: UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 - File: UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
Address: 0x7ef5a6135f1fd6a02593eedc869c6d41d934aef8 Address: xdc7ef5a6135f1fd6a02593eedc869c6d41d934aef8
- File: aaa - File: aaa
Address: 0xf466859ead1932d743d622cb74fc058882e8648a Address: xdcf466859ead1932d743d622cb74fc058882e8648a
- File: zzz - File: zzz
Address: 0x289d485d9771714cce91d3393d764e1311907acc Address: xdc289d485d9771714cce91d3393d764e1311907acc
The other files (including this README) are broken in various ways The other files (including this README) are broken in various ways
and should not be picked up by package accounts: and should not be picked up by package accounts:

View file

@ -75,7 +75,7 @@ Your new account is locked with a password. Please give a password. Do not forge
Passphrase: {{.InputLine "foobar"}} Passphrase: {{.InputLine "foobar"}}
Repeat passphrase: {{.InputLine "foobar"}} Repeat passphrase: {{.InputLine "foobar"}}
`) `)
XDC.ExpectRegexp(`Address: \{[0-9a-f]{40}\}\n`) XDC.ExpectRegexp(`Address: \{xdc[0-9a-f]{40}\}\n`)
} }
func TestAccountNewBadRepeat(t *testing.T) { func TestAccountNewBadRepeat(t *testing.T) {
@ -112,7 +112,7 @@ func TestWalletImport(t *testing.T) {
XDC.Expect(` XDC.Expect(`
!! Unsupported terminal, password will be echoed. !! Unsupported terminal, password will be echoed.
Passphrase: {{.InputLine "foo"}} Passphrase: {{.InputLine "foo"}}
Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f} Address: {xdcd4584b5f6229b7be90727b0fc8c6b91bb427821f}
`) `)
files, err := ioutil.ReadDir(filepath.Join(XDC.Datadir, "keystore")) files, err := ioutil.ReadDir(filepath.Join(XDC.Datadir, "keystore"))
@ -146,7 +146,7 @@ Passphrase: {{.InputLine "foobar"}}
wantMessages := []string{ wantMessages := []string{
"Unlocked account", "Unlocked account",
"=0xf466859eAD1932D743d622CB74FC058882E8648A", "=xdcf466859eAD1932D743d622CB74FC058882E8648A",
} }
for _, m := range wantMessages { for _, m := range wantMessages {
if !strings.Contains(XDC.StderrText(), m) { if !strings.Contains(XDC.StderrText(), m) {
@ -191,8 +191,8 @@ Passphrase: {{.InputLine "foobar"}}
wantMessages := []string{ wantMessages := []string{
"Unlocked account", "Unlocked account",
"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", "=xdc7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
"=0x289d485D9771714CCe91D3393D764E1311907ACc", "=xdc289d485D9771714CCe91D3393D764E1311907ACc",
} }
for _, m := range wantMessages { for _, m := range wantMessages {
if !strings.Contains(XDC.StderrText(), m) { if !strings.Contains(XDC.StderrText(), m) {
@ -211,8 +211,8 @@ func TestUnlockFlagPasswordFile(t *testing.T) {
wantMessages := []string{ wantMessages := []string{
"Unlocked account", "Unlocked account",
"=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8", "=xdc7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
"=0x289d485D9771714CCe91D3393D764E1311907ACc", "=xdc289d485D9771714CCe91D3393D764E1311907ACc",
} }
for _, m := range wantMessages { for _, m := range wantMessages {
if !strings.Contains(XDC.StderrText(), m) { if !strings.Contains(XDC.StderrText(), m) {
@ -261,7 +261,7 @@ In order to avoid this warning, you need to remove the following duplicate key f
wantMessages := []string{ wantMessages := []string{
"Unlocked account", "Unlocked account",
"=0xf466859eAD1932D743d622CB74FC058882E8648A", "=xdcf466859eAD1932D743d622CB74FC058882E8648A",
} }
for _, m := range wantMessages { for _, m := range wantMessages {
if !strings.Contains(XDC.StderrText(), m) { if !strings.Contains(XDC.StderrText(), m) {

View file

@ -31,14 +31,14 @@ import (
) )
const ( const (
ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 XDPoS:1.0 rpc:1.0 XDCx:1.0 XDCxlending:1.0 txpool:1.0 web3:1.0" ipcAPIs = "XDCx:1.0 XDCxlending:1.0 XDPoS:1.0 admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0"
httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
) )
// Tests that a node embedded within a console can be started up properly and // Tests that a node embedded within a console can be started up properly and
// then terminated by closing the input stream. // then terminated by closing the input stream.
func TestConsoleWelcome(t *testing.T) { func TestConsoleWelcome(t *testing.T) {
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" coinbase := "xdc8605cdbbdb6d264aa742e77020dcbc58fcdce182"
// Start a XDC console, make sure it's cleaned up and terminate the console // Start a XDC console, make sure it's cleaned up and terminate the console
XDC := runXDC(t, XDC := runXDC(t,
@ -73,7 +73,7 @@ at block: 0 ({{niltime}})
// Tests that a console can be attached to a running node via various means. // Tests that a console can be attached to a running node via various means.
func TestIPCAttachWelcome(t *testing.T) { func TestIPCAttachWelcome(t *testing.T) {
// Configure the instance for IPC attachement // Configure the instance for IPC attachement
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" coinbase := "xdc8605cdbbdb6d264aa742e77020dcbc58fcdce182"
var ipc string var ipc string
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
ipc = `\\.\pipe\XDC` + strconv.Itoa(trulyRandInt(100000, 999999)) ipc = `\\.\pipe\XDC` + strconv.Itoa(trulyRandInt(100000, 999999))
@ -95,7 +95,7 @@ func TestIPCAttachWelcome(t *testing.T) {
} }
func TestHTTPAttachWelcome(t *testing.T) { func TestHTTPAttachWelcome(t *testing.T) {
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" coinbase := "xdc8605cdbbdb6d264aa742e77020dcbc58fcdce182"
port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
XDC := runXDC(t, XDC := runXDC(t,
"--XDCx.datadir", tmpdir(t)+"XDCx/"+time.Now().String(), "--XDCx.datadir", tmpdir(t)+"XDCx/"+time.Now().String(),
@ -110,7 +110,7 @@ func TestHTTPAttachWelcome(t *testing.T) {
} }
func TestWSAttachWelcome(t *testing.T) { func TestWSAttachWelcome(t *testing.T) {
coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182" coinbase := "xdc8605cdbbdb6d264aa742e77020dcbc58fcdce182"
port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
XDC := runXDC(t, XDC := runXDC(t,

View file

@ -40,7 +40,7 @@ func TestMessageSignVerify(t *testing.T) {
Passphrase: {{.InputLine "foobar"}} Passphrase: {{.InputLine "foobar"}}
Repeat passphrase: {{.InputLine "foobar"}} Repeat passphrase: {{.InputLine "foobar"}}
`) `)
_, matches := generate.ExpectRegexp(`Address: (0x[0-9a-fA-F]{40})\n`) _, matches := generate.ExpectRegexp(`Address: (xdc[0-9a-fA-F]{40})\n`)
address := matches[1] address := matches[1]
generate.ExpectExit() generate.ExpectExit()
@ -59,7 +59,7 @@ Passphrase: {{.InputLine "foobar"}}
_, matches = verify.ExpectRegexp(` _, matches = verify.ExpectRegexp(`
Signature verification successful! Signature verification successful!
Recovered public key: [0-9a-f]+ Recovered public key: [0-9a-f]+
Recovered address: (0x[0-9a-fA-F]{40}) Recovered address: (xdc[0-9a-fA-F]{40})
`) `)
recovered := matches[1] recovered := matches[1]
verify.ExpectExit() verify.ExpectExit()

View file

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

View file

@ -167,9 +167,16 @@ func BytesToAddress(b []byte) Address {
a.SetBytes(b) a.SetBytes(b)
return a return a
} }
func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } 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 // IsHexAddress verifies whether a string can represent a valid hex-encoded
// Ethereum address or not. // Ethereum address or not.

View file

@ -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 // Author implements consensus.Engine, returning the Ethereum address recovered
// from the signature in the header's extra-data section. // from the signature in the header's extra-data section.
func (c *XDPoS) Author(header *types.Header) (common.Address, error) { func (c *XDPoS) Author(header *types.Header) (common.Address, error) {
@ -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 // 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) verifyHeader(chain consensus.ChainReader, header *types.Header, parents []*types.Header, fullVerify bool) error { 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 { if common.IsTestnet {
fullVerify = false 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 { 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) len, preIndex, curIndex, _, err := c.YourTurn(chain, parent, signer)
if err != nil { if err != nil {
return big.NewInt(int64(len + curIndex - preIndex)) return big.NewInt(int64(len + curIndex - preIndex))

View file

@ -21,12 +21,13 @@ import (
"testing" "testing"
"time" "time"
"math/rand"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"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"
"math/rand"
) )
var ( var (
@ -35,7 +36,7 @@ var (
) )
func TestBlockSigner(t *testing.T) { 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) transactOpts := bind.NewKeyedTransactor(key)
blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99)) blockSignerAddress, blockSigner, err := DeployBlockSigner(transactOpts, contractBackend, big.NewInt(99))

View file

@ -42,7 +42,7 @@ var (
) )
func newTestBackend() *backends.SimulatedBackend { func newTestBackend() *backends.SimulatedBackend {
return backends.NewSimulatedBackend(core.GenesisAlloc{ return backends.NewXDCSimulatedBackend(core.GenesisAlloc{
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)},

View file

@ -35,7 +35,7 @@ var (
) )
func TestENS(t *testing.T) { 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) transactOpts := bind.NewKeyedTransactor(key)
ensAddr, ens, err := DeployENS(transactOpts, contractBackend) ensAddr, ens, err := DeployENS(transactOpts, contractBackend)

View file

@ -40,7 +40,7 @@ var (
) )
func TestRandomize(t *testing.T) { 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 := bind.NewKeyedTransactor(key)
transactOpts.GasLimit = 1000000 transactOpts.GasLimit = 1000000

View file

@ -19,6 +19,11 @@ import (
"bytes" "bytes"
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"math/big"
"math/rand"
"testing"
"time"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind/backends"
"github.com/XinFinOrg/XDPoSChain/common" "github.com/XinFinOrg/XDPoSChain/common"
@ -27,10 +32,6 @@ 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"
"math/big"
"math/rand"
"testing"
"time"
) )
var ( var (
@ -46,7 +47,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.NewSimulatedBackend(genesis) backend := backends.NewXDCSimulatedBackend(genesis, 10000000)
backend.Commit() backend.Commit()
return backend return backend

View file

@ -46,7 +46,7 @@ var (
) )
func TestValidator(t *testing.T) { 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) transactOpts := bind.NewKeyedTransactor(key)
validatorCap := new(big.Int) validatorCap := new(big.Int)
@ -82,7 +82,7 @@ func TestValidator(t *testing.T) {
} }
func TestRewardBalance(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)}, 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)},

View file

@ -152,10 +152,10 @@ type BlockChain struct {
validator Validator // block and state validator interface validator Validator // block and state validator interface
vmConfig vm.Config vmConfig vm.Config
badBlocks *lru.Cache // Bad block cache badBlocks *lru.Cache // Bad block cache
IPCEndpoint string shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
Client *ethclient.Client // Global ipc client instance. IPCEndpoint string
Client bind.ContractBackend // Global ipc client instance.
// Blocks hash array by block number // Blocks hash array by block number
// cache field for tracking finality purpose, can't use for tracking block vs block relationship // cache field for tracking finality purpose, can't use for tracking block vs block relationship
blocksHashCache *lru.Cache blocksHashCache *lru.Cache
@ -1362,6 +1362,13 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
// Set new head. // Set new head.
if status == CanonStatTy { if status == CanonStatTy {
bc.insert(block) 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 // save cache BlockSigners
if bc.chainConfig.XDPoS != nil && bc.chainConfig.IsTIPSigning(block.Number()) { 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 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 // 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 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 // Append a single chain head event if we've progressed the chain
if status == CanonStatTy && bc.CurrentBlock().Hash() == block.Hash() { if status == CanonStatTy && bc.CurrentBlock().Hash() == block.Hash() {
@ -2193,6 +2185,13 @@ func (bc *BlockChain) reorg(oldBlock, newBlock *types.Block) error {
return err return err
} }
addedTxs = append(addedTxs, newChain[i].Transactions()...) 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 // calculate the difference between deleted and added transactions
diff := types.TxDifference(deletedTxs, addedTxs) diff := types.TxDifference(deletedTxs, addedTxs)
@ -2428,7 +2427,7 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript
} }
// Get current IPC Client. // Get current IPC Client.
func (bc *BlockChain) GetClient() (*ethclient.Client, error) { func (bc *BlockChain) GetClient() (bind.ContractBackend, error) {
if bc.Client == nil { if bc.Client == nil {
// Inject ipc client global instance. // Inject ipc client global instance.
client, err := ethclient.Dial(bc.IPCEndpoint) client, err := ethclient.Dial(bc.IPCEndpoint)

View file

@ -27,6 +27,7 @@ import (
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/XDCxlending"
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCx"
@ -45,7 +46,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/eth/downloader"
"github.com/XinFinOrg/XDPoSChain/eth/gasprice" "github.com/XinFinOrg/XDPoSChain/eth/gasprice"
"github.com/XinFinOrg/XDPoSChain/ethclient"
"github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/event"
"github.com/XinFinOrg/XDPoSChain/log" "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() client, err := b.eth.blockchain.GetClient()
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -19,9 +19,11 @@ package ethapi
import ( import (
"context" "context"
"math/big"
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate" "github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"github.com/XinFinOrg/XDPoSChain/XDCxlending" "github.com/XinFinOrg/XDPoSChain/XDCxlending"
"math/big" "github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
"github.com/XinFinOrg/XDPoSChain/XDCx" "github.com/XinFinOrg/XDPoSChain/XDCx"
@ -33,7 +35,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/types" "github.com/XinFinOrg/XDPoSChain/core/types"
"github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/eth/downloader"
"github.com/XinFinOrg/XDPoSChain/ethclient"
"github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/event"
"github.com/XinFinOrg/XDPoSChain/params" "github.com/XinFinOrg/XDPoSChain/params"
@ -83,7 +84,7 @@ type Backend interface {
ChainConfig() *params.ChainConfig ChainConfig() *params.ChainConfig
CurrentBlock() *types.Block CurrentBlock() *types.Block
GetIPCClient() (*ethclient.Client, error) GetIPCClient() (bind.ContractBackend, error)
GetEngine() consensus.Engine GetEngine() consensus.Engine
GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int GetRewardByHash(hash common.Hash) map[string]map[string]map[string]*big.Int

View file

@ -20,12 +20,14 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/XinFinOrg/XDPoSChain/XDCx/tradingstate"
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"path/filepath" "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/XDCx"
"github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts"
@ -39,7 +41,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/core/vm" "github.com/XinFinOrg/XDPoSChain/core/vm"
"github.com/XinFinOrg/XDPoSChain/eth/downloader" "github.com/XinFinOrg/XDPoSChain/eth/downloader"
"github.com/XinFinOrg/XDPoSChain/eth/gasprice" "github.com/XinFinOrg/XDPoSChain/eth/gasprice"
"github.com/XinFinOrg/XDPoSChain/ethclient"
"github.com/XinFinOrg/XDPoSChain/ethdb" "github.com/XinFinOrg/XDPoSChain/ethdb"
"github.com/XinFinOrg/XDPoSChain/event" "github.com/XinFinOrg/XDPoSChain/event"
"github.com/XinFinOrg/XDPoSChain/light" "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 return nil, nil
} }

View file

@ -25,7 +25,6 @@ import (
"github.com/XinFinOrg/XDPoSChain/accounts" "github.com/XinFinOrg/XDPoSChain/accounts"
"math/big" "math/big"
"os"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -384,14 +383,6 @@ func (self *worker) wait() {
if (block.NumberU64() % work.config.XDPoS.Epoch) == 0 { if (block.NumberU64() % work.config.XDPoS.Epoch) == 0 {
core.CheckpointCh <- 1 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.UpdateBlocksHashCache(block)
self.chain.PostChainEvents(events, logs) self.chain.PostChainEvents(events, logs)

View file

@ -111,8 +111,12 @@ 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}
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} 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}}
TestRules = TestChainConfig.Rules(new(big.Int)) 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. // 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. 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
} }
// String implements the stringer interface, returning the consensus engine details. // String implements the stringer interface, returning the consensus engine details.

842
tests/block_signer_test.go Normal file
View file

@ -0,0 +1,842 @@
package tests
import (
"bytes"
"context"
"encoding/hex"
"fmt"
"math/big"
"reflect"
"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/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")
}
}