mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 21:31:37 +00:00
Minor error fixed.
This commit is contained in:
parent
bf626ddc95
commit
a638d2adc0
21 changed files with 415 additions and 451 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "tests"]
|
||||
path = tests/testdata
|
||||
url = https://github.com/ethereum/tests
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
# Build XDC in a stock Go builder container
|
||||
FROM golang:1.10-alpine as builder
|
||||
|
||||
RUN apk add --no-cache make gcc musl-dev linux-headers
|
||||
|
|
@ -8,7 +7,7 @@ RUN cd /XDCchain && make XDC
|
|||
|
||||
FROM alpine:latest
|
||||
|
||||
LABEL maintainer="admin@xinfin.org"
|
||||
LABEL maintainer="anil@xinfin.org"
|
||||
|
||||
WORKDIR /XDCchain
|
||||
|
||||
|
|
@ -22,4 +21,3 @@ EXPOSE 30303
|
|||
ENTRYPOINT ["/usr/local/bin/XDC"]
|
||||
|
||||
CMD ["--help"]
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ RUN chmod +x /XDCchain/build/bin/bootnode
|
|||
|
||||
FROM alpine:latest
|
||||
|
||||
LABEL maintainer="admin@xinfin.org"
|
||||
LABEL maintainer="anil@xinfin.org"
|
||||
|
||||
WORKDIR /XDCchain
|
||||
|
||||
|
|
@ -21,4 +21,4 @@ EXPOSE 30301
|
|||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
||||
CMD ["-verbosity", "6", "-nodekey", "bootnode.key", "--addr", ":30301"
|
||||
CMD ["-verbosity", "6", "-nodekey", "bootnode.key", "--addr", ":30301"]
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
FROM golang:1.10-alpine as builder
|
||||
FROM golang:1.10-alpine as builder
|
||||
|
||||
RUN apk add --no-cache make gcc musl-dev linux-headers
|
||||
RUN apk add --no-cache make gcc musl-dev linux-headers
|
||||
|
||||
ADD . /XDCchain
|
||||
ADD . /XDChain
|
||||
|
||||
RUN cd /XDCchain \
|
||||
&& make XDC \
|
||||
RUN cd /XDChain \
|
||||
&& make XDC\
|
||||
&& chmod +x /XDCchain/build/bin/XDC
|
||||
|
||||
FROM alpine:latest
|
||||
FROM alpine:latest
|
||||
|
||||
LABEL maintainer="admin@xinfin.org"
|
||||
LABEL maintainer="anil@xinfin.org"
|
||||
|
||||
WORKDIR /XDCchain
|
||||
WORKDIR /XDChain
|
||||
|
||||
COPY --from=builder /XDCchain/build/bin/XDC /usr/local/bin/XDC
|
||||
COPY --from=builder /XDCchain/build/bin/XDC /usr/local/bin/XDC
|
||||
|
||||
ENV IDENTITY ''
|
||||
ENV IDENTITY ''
|
||||
ENV PASSWORD ''
|
||||
ENV PRIVATE_KEY ''
|
||||
ENV BOOTNODES ''
|
||||
|
|
@ -29,11 +29,11 @@ ENV NETSTATS_HOST 'netstats-server'
|
|||
ENV NETSTATS_PORT '3000'
|
||||
ENV ANNOUNCE_TXS ''
|
||||
|
||||
RUN apk add --no-cache ca-certificates
|
||||
RUN apk add --no-cache ca-certificates
|
||||
|
||||
COPY docker/XDCchain ./
|
||||
COPY docker/XDChain ./
|
||||
COPY genesis/ ./
|
||||
|
||||
EXPOSE 8545 8546 30303 30303/udp
|
||||
EXPOSE 8545 8546 30303 30303/udp
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
|
|
|
|||
32
circle.yml
32
circle.yml
|
|
@ -1,32 +0,0 @@
|
|||
machine:
|
||||
services:
|
||||
- docker
|
||||
|
||||
dependencies:
|
||||
cache_directories:
|
||||
- "~/.ethash" # Cache the ethash DAG generated by hive for consecutive builds
|
||||
- "~/.docker" # Cache all docker images manually to avoid lengthy rebuilds
|
||||
override:
|
||||
# Restore all previously cached docker images
|
||||
- mkdir -p ~/.docker
|
||||
- for img in `ls ~/.docker`; do docker load -i ~/.docker/$img; done
|
||||
|
||||
# Pull in and hive, restore cached ethash DAGs and do a dry run
|
||||
- go get -u github.com/karalabe/hive
|
||||
- (cd ~/.go_workspace/src/github.com/karalabe/hive && mkdir -p workspace/ethash/ ~/.ethash)
|
||||
- (cd ~/.go_workspace/src/github.com/karalabe/hive && cp -r ~/.ethash/. workspace/ethash/)
|
||||
- (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=NONE --test=. --sim=. --loglevel=6)
|
||||
|
||||
# Cache all the docker images and the ethash DAGs
|
||||
- for img in `docker images | grep -v "^<none>" | tail -n +2 | awk '{print $1}'`; do docker save $img > ~/.docker/`echo $img | tr '/' ':'`.tar; done
|
||||
- cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/ethash/. ~/.ethash
|
||||
|
||||
test:
|
||||
override:
|
||||
# Build Geth and move into a known folder
|
||||
- make geth
|
||||
- cp ./build/bin/geth $HOME/geth
|
||||
|
||||
# Run hive and move all generated logs into the public artifacts folder
|
||||
- (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/geth --test=. --sim=.)
|
||||
- cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/logs/* $CIRCLE_ARTIFACTS
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright 2016 The go-ethereum Authors
|
||||
// This file is part of go-ethereum.
|
||||
//
|
||||
// go-ethereum is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// go-ethereum is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var customGenesisTests = []struct {
|
||||
genesis string
|
||||
query string
|
||||
result string
|
||||
}{
|
||||
// Plain genesis file without anything extra
|
||||
{
|
||||
genesis: `{
|
||||
"alloc" : {},
|
||||
"coinbase" : "0x0000000000000000000000000000000000000000",
|
||||
"difficulty" : "0x20000",
|
||||
"extraData" : "",
|
||||
"gasLimit" : "0x2fefd8",
|
||||
"nonce" : "0x0000000000000042",
|
||||
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"timestamp" : "0x00"
|
||||
}`,
|
||||
query: "eth.getBlock(0).nonce",
|
||||
result: "0x0000000000000042",
|
||||
},
|
||||
// Genesis file with an empty chain configuration (ensure missing fields work)
|
||||
{
|
||||
genesis: `{
|
||||
"alloc" : {},
|
||||
"coinbase" : "0x0000000000000000000000000000000000000000",
|
||||
"difficulty" : "0x20000",
|
||||
"extraData" : "",
|
||||
"gasLimit" : "0x2fefd8",
|
||||
"nonce" : "0x0000000000000042",
|
||||
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"timestamp" : "0x00",
|
||||
"config" : {}
|
||||
}`,
|
||||
query: "eth.getBlock(0).nonce",
|
||||
result: "0x0000000000000042",
|
||||
},
|
||||
// Genesis file with specific chain configurations
|
||||
{
|
||||
genesis: `{
|
||||
"alloc" : {},
|
||||
"coinbase" : "0x0000000000000000000000000000000000000000",
|
||||
"difficulty" : "0x20000",
|
||||
"extraData" : "",
|
||||
"gasLimit" : "0x2fefd8",
|
||||
"nonce" : "0x0000000000000042",
|
||||
"mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"timestamp" : "0x00",
|
||||
"config" : {
|
||||
"homesteadBlock" : 314,
|
||||
"daoForkBlock" : 141,
|
||||
"daoForkSupport" : true
|
||||
},
|
||||
}`,
|
||||
query: "eth.getBlock(0).nonce",
|
||||
result: "0x0000000000000042",
|
||||
},
|
||||
}
|
||||
|
||||
// Tests that initializing XDC with a custom genesis block and chain definitions
|
||||
// work properly.
|
||||
func TestCustomGenesis(t *testing.T) {
|
||||
for i, tt := range customGenesisTests {
|
||||
// Create a temporary data directory to use and inspect later
|
||||
datadir := tmpdir(t)
|
||||
defer os.RemoveAll(datadir)
|
||||
|
||||
// Initialize the data directory with the custom genesis block
|
||||
json := filepath.Join(datadir, "genesis.json")
|
||||
if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil {
|
||||
t.Fatalf("test %d: failed to write genesis file: %v", i, err)
|
||||
}
|
||||
runXDC(t, "--datadir", datadir, "init", json).WaitExit()
|
||||
|
||||
// Query the custom genesis block
|
||||
XDC := runXDC(t,
|
||||
"--datadir", datadir, "--maxpeers", "0", "--port", "0",
|
||||
"--nodiscover", "--nat", "none", "--ipcdisable",
|
||||
"--exec", tt.query, "console")
|
||||
XDC.ExpectRegexp(tt.result)
|
||||
XDC.ExpectExit()
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||
"github.com/ethereum/go-ethereum/console"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
|
|
@ -123,6 +124,7 @@ var (
|
|||
configFileFlag,
|
||||
utils.AnnounceTxsFlag,
|
||||
utils.StoreRewardFlag,
|
||||
utils.RollbackFlag,
|
||||
}
|
||||
|
||||
rpcFlags = []cli.Flag{
|
||||
|
|
@ -291,9 +293,18 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) {
|
|||
if _, ok := ethereum.Engine().(*XDPoS.XDPoS); ok {
|
||||
go func() {
|
||||
started := false
|
||||
ok, err := ethereum.ValidateMasternode()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
ok := false
|
||||
var err error
|
||||
if common.IsTestnet {
|
||||
ok, err = ethereum.ValidateMasternodeTestnet()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
}
|
||||
} else {
|
||||
ok, err = ethereum.ValidateMasternode()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
}
|
||||
}
|
||||
if ok {
|
||||
log.Info("Masternode found. Enabling staking mode...")
|
||||
|
|
@ -317,9 +328,16 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) {
|
|||
defer close(core.CheckpointCh)
|
||||
for range core.CheckpointCh {
|
||||
log.Info("Checkpoint!!! It's time to reconcile node's state...")
|
||||
ok, err := ethereum.ValidateMasternode()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
if common.IsTestnet {
|
||||
ok, err = ethereum.ValidateMasternodeTestnet()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
}
|
||||
} else {
|
||||
ok, err = ethereum.ValidateMasternode()
|
||||
if err != nil {
|
||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
||||
}
|
||||
}
|
||||
if !ok {
|
||||
if started {
|
||||
|
|
|
|||
270
cmd/XDCclean/main.go
Normal file
270
cmd/XDCclean/main.go
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/eth"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/hashicorp/golang-lru"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/util"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
dir = flag.String("dir", "", "dir to mainet chain data")
|
||||
cacheSize = flag.Int("size", 1000000, "dir to mainet chain data")
|
||||
)
|
||||
|
||||
type TrieRoot struct {
|
||||
trie *trie.SecureTrie
|
||||
number uint64
|
||||
}
|
||||
type StateNode struct {
|
||||
node trie.Node
|
||||
path []byte
|
||||
}
|
||||
type ResultProcessNode struct {
|
||||
index int
|
||||
number int
|
||||
newNodes [17]*StateNode
|
||||
keys [17]*[]byte
|
||||
}
|
||||
|
||||
var sercureKey = []byte("secure-key-")
|
||||
var nWorker = runtime.NumCPU() / 2
|
||||
var cleanAddress = []common.Address{common.HexToAddress(common.BlockSigners)}
|
||||
var cache *lru.Cache
|
||||
var finish = int32(0)
|
||||
var running = true
|
||||
var stateRoots = make(chan TrieRoot)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
lddb, _ := ethdb.NewLDBDatabase(*dir, eth.DefaultConfig.DatabaseCache, utils.MakeDatabaseHandles())
|
||||
head := core.GetHeadBlockHash(lddb)
|
||||
currentHeader := core.GetHeader(lddb, head, core.GetBlockNumber(lddb, head))
|
||||
tridb := trie.NewDatabase(lddb)
|
||||
catchEventInterupt(lddb.LDB())
|
||||
cache, _ = lru.New(*cacheSize)
|
||||
go func() {
|
||||
for i := uint64(1); i <= currentHeader.Number.Uint64(); i++ {
|
||||
hash := core.GetCanonicalHash(lddb, i)
|
||||
root := core.GetHeader(lddb, hash, i).Root
|
||||
trieRoot, err := trie.NewSecure(root, tridb, 0)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if running {
|
||||
stateRoots <- TrieRoot{trieRoot, i}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if running {
|
||||
close(stateRoots)
|
||||
}
|
||||
}()
|
||||
for trieRoot := range stateRoots {
|
||||
atomic.StoreInt32(&finish, 1)
|
||||
if running {
|
||||
for _, address := range cleanAddress {
|
||||
enc := trieRoot.trie.Get(address.Bytes())
|
||||
var data state.Account
|
||||
rlp.DecodeBytes(enc, &data)
|
||||
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number)
|
||||
signerRoot, err := resolveHash(data.Root[:], lddb.LDB())
|
||||
if err != nil {
|
||||
fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at block ", trieRoot.number)
|
||||
continue
|
||||
}
|
||||
batch := new(leveldb.Batch)
|
||||
count := 1
|
||||
list := []*StateNode{{node: signerRoot}}
|
||||
for len(list) > 0 {
|
||||
newList, total := findNewNodes(list, lddb.LDB(), batch)
|
||||
count = count + 17*len(newList)
|
||||
list = removeNodesNil(newList, total)
|
||||
}
|
||||
fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at block ", trieRoot.number, " keys ", count)
|
||||
err = lddb.LDB().Write(batch, nil)
|
||||
if err != nil {
|
||||
fmt.Println(time.Now().Format(time.RFC3339), "Write batch leveldb error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
atomic.StoreInt32(&finish, 0)
|
||||
}
|
||||
fmt.Println(time.Now(), "compact")
|
||||
lddb.LDB().CompactRange(util.Range{})
|
||||
lddb.Close()
|
||||
fmt.Println(time.Now(), "end")
|
||||
}
|
||||
|
||||
func removeNodesNil(list [][17]*StateNode, length int) []*StateNode {
|
||||
results := make([]*StateNode, length)
|
||||
index := 0
|
||||
for _, nodes := range list {
|
||||
for _, node := range nodes {
|
||||
if node != nil {
|
||||
results[index] = node
|
||||
index++
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
func catchEventInterupt(db *leveldb.DB) {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
fmt.Println("catch event interrupt ", sig, running, finish)
|
||||
running = false
|
||||
if atomic.LoadInt32(&finish) == 0 {
|
||||
close(stateRoots)
|
||||
db.Close()
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
func resolveHash(n trie.HashNode, db *leveldb.DB) (trie.Node, error) {
|
||||
if cache.Contains(common.BytesToHash(n)) {
|
||||
return nil, &trie.MissingNodeError{}
|
||||
}
|
||||
enc, err := db.Get(n, nil)
|
||||
if err != nil || enc == nil {
|
||||
return nil, &trie.MissingNodeError{}
|
||||
}
|
||||
return trie.MustDecodeNode(n, enc, 0), nil
|
||||
}
|
||||
|
||||
func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) {
|
||||
childs := [17]*StateNode{}
|
||||
switch node := n.node.(type) {
|
||||
case *trie.FullNode:
|
||||
// Full Node, move to the first non-nil child.
|
||||
for i := 0; i < len(node.Children); i++ {
|
||||
child := node.Children[i]
|
||||
if child != nil {
|
||||
childNode := child
|
||||
var err error = nil
|
||||
if _, ok := child.(trie.HashNode); ok {
|
||||
childNode, err = resolveHash(child.(trie.HashNode), db)
|
||||
}
|
||||
if err == nil {
|
||||
childs[i] = &StateNode{node: childNode, path: append(n.path, byte(i))}
|
||||
} else if err != nil {
|
||||
_, ok := err.(*trie.MissingNodeError)
|
||||
if !ok {
|
||||
return childs, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case *trie.ShortNode:
|
||||
// Short Node, return the pointer singleton child
|
||||
childNode := node.Val
|
||||
var err error = nil
|
||||
if _, ok := node.Val.(trie.HashNode); ok {
|
||||
childNode, err = resolveHash(node.Val.(trie.HashNode), db)
|
||||
}
|
||||
if err == nil {
|
||||
childs[0] = &StateNode{node: childNode, path: append(n.path, node.Key...)}
|
||||
} else if err != nil {
|
||||
_, ok := err.(*trie.MissingNodeError)
|
||||
if !ok {
|
||||
return childs, err
|
||||
}
|
||||
}
|
||||
}
|
||||
return childs, nil
|
||||
}
|
||||
func processNodes(node StateNode, db *leveldb.DB) ([17]*StateNode, [17]*[]byte, int) {
|
||||
hash, _ := node.node.Cache()
|
||||
commonHash := common.BytesToHash(hash)
|
||||
newNodes := [17]*StateNode{}
|
||||
keys := [17]*[]byte{}
|
||||
number := 0
|
||||
if !cache.Contains(commonHash) {
|
||||
childNodes, err := getAllChilds(node, db)
|
||||
if err != nil {
|
||||
fmt.Println("Error when get all childs node : ", common.Bytes2Hex(node.path), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
for i, child := range childNodes {
|
||||
if child != nil {
|
||||
if _, ok := child.node.(trie.ValueNode); ok {
|
||||
buf := append(sercureKey, child.path...)
|
||||
keys[i] = &buf
|
||||
} else {
|
||||
hash, _ := child.node.Cache()
|
||||
var bytes []byte = hash
|
||||
keys[i] = &bytes
|
||||
newNodes[i] = child
|
||||
number++
|
||||
}
|
||||
}
|
||||
}
|
||||
cache.Add(commonHash, true)
|
||||
}
|
||||
return newNodes, keys, number
|
||||
}
|
||||
|
||||
func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch) ([][17]*StateNode, int) {
|
||||
length := len(nodes)
|
||||
chunkSize := length / nWorker
|
||||
if len(nodes)%nWorker != 0 {
|
||||
chunkSize++
|
||||
}
|
||||
childNodes := make([][17]*StateNode, length)
|
||||
results := make(chan ResultProcessNode)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(length)
|
||||
for i := 0; i < nWorker; i++ {
|
||||
from := i * chunkSize
|
||||
to := from + chunkSize
|
||||
if to > length {
|
||||
to = length
|
||||
}
|
||||
go func(from int, to int) {
|
||||
for j := from; j < to; j++ {
|
||||
childs, keys, number := processNodes(*nodes[j], db)
|
||||
go func(result ResultProcessNode) {
|
||||
results <- result
|
||||
}(ResultProcessNode{j, number, childs, keys})
|
||||
}
|
||||
}(from, to)
|
||||
}
|
||||
total := 0
|
||||
go func() {
|
||||
for result := range results {
|
||||
childNodes[result.index] = result.newNodes
|
||||
total = total + result.number
|
||||
for _, key := range result.keys {
|
||||
if key != nil {
|
||||
batchlvdb.Delete(*key)
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
wg.Wait()
|
||||
close(results)
|
||||
return childNodes, total
|
||||
}
|
||||
|
|
@ -40,7 +40,9 @@ var dashboardContent = `
|
|||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{.NetworkTitle}}: Ethereum Testnet</title>
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/gentelella/1.3.0/css/custom.min.css" rel="stylesheet">
|
||||
|
|
@ -62,6 +64,7 @@ var dashboardContent = `
|
|||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="nav-sm" style="overflow-x: hidden">
|
||||
<div class="container body">
|
||||
<div class="main_container">
|
||||
|
|
@ -260,11 +263,13 @@ var dashboardContent = `
|
|||
<pre>
|
||||
Enodes bootnodes = new Enodes();{{range .Bootnodes}}
|
||||
bootnodes.append(new Enode("{{.}}"));{{end}}
|
||||
|
||||
NodeConfig config = new NodeConfig();
|
||||
config.setBootstrapNodes(bootnodes);
|
||||
config.setEthereumNetworkID({{.NetworkID}});
|
||||
config.setEthereumGenesis(genesis);{{if .Ethstats}}
|
||||
config.setEthereumNetStats("{{.Ethstats}}");{{end}}
|
||||
|
||||
Node node = new Node(getFilesDir() + "/.{{.Network}}", config);
|
||||
node.start();
|
||||
</pre>
|
||||
|
|
@ -288,13 +293,16 @@ node.start();
|
|||
<pre>import Geth</pre>
|
||||
<pre>
|
||||
var error: NSError?
|
||||
|
||||
let bootnodes = GethNewEnodesEmpty(){{range .Bootnodes}}
|
||||
bootnodes?.append(GethNewEnode("{{.}}", &error)){{end}}
|
||||
|
||||
let config = GethNewNodeConfig()
|
||||
config?.setBootstrapNodes(bootnodes)
|
||||
config?.setEthereumNetworkID({{.NetworkID}})
|
||||
config?.setEthereumGenesis(genesis){{if .Ethstats}}
|
||||
config?.setEthereumNetStats("{{.Ethstats}}"){{end}}
|
||||
|
||||
let datadir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
||||
let node = GethNewNode(datadir + "/.{{.Network}}", config, &error);
|
||||
try! node?.start();
|
||||
|
|
@ -428,12 +436,14 @@ try! node?.start();
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/gentelella/1.3.0/js/custom.min.js"></script>
|
||||
<script>
|
||||
var load = function(hash) {
|
||||
window.location.hash = hash;
|
||||
|
||||
// Fade out all possible pages (yes, ugly, no, don't care)
|
||||
$("#geth").fadeOut(300)
|
||||
$("#mist").fadeOut(300)
|
||||
|
|
@ -441,6 +451,7 @@ try! node?.start();
|
|||
$("#other").fadeOut(300)
|
||||
$("#about").fadeOut(300)
|
||||
$("#frame-wrapper").fadeOut(300);
|
||||
|
||||
// Depending on the hash, resolve it into a local or remote URL
|
||||
var url = hash;
|
||||
switch (hash) {
|
||||
|
|
@ -472,6 +483,7 @@ try! node?.start();
|
|||
var sidebar = $($(".navbar")[0]).width();
|
||||
var limit = document.body.clientWidth - sidebar;
|
||||
var scale = limit / 1920;
|
||||
|
||||
$("#frame-wrapper").width(limit);
|
||||
$("#frame-wrapper").height(document.body.clientHeight / scale);
|
||||
$("#frame-wrapper").css({
|
||||
|
|
@ -480,6 +492,7 @@ try! node?.start();
|
|||
});
|
||||
};
|
||||
$(window).resize(resize);
|
||||
|
||||
if (window.location.hash == "") {
|
||||
var item = $(".side-menu").children()[0];
|
||||
$(item).children()[0].click();
|
||||
|
|
@ -504,6 +517,7 @@ var dashboardMascot = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x01s\x
|
|||
// to aggregate various private network services under one easily accessible page.
|
||||
var dashboardDockerfile = `
|
||||
FROM mhart/alpine-node:latest
|
||||
|
||||
RUN \
|
||||
npm install connect serve-static && \
|
||||
\
|
||||
|
|
@ -512,6 +526,7 @@ RUN \
|
|||
echo 'connect().use(serveStatic("/dashboard")).listen(80, function(){' >> server.js && \
|
||||
echo ' console.log("Server running on 80...");' >> server.js && \
|
||||
echo '});' >> server.js
|
||||
|
||||
ADD {{.Network}}.json /dashboard/{{.Network}}.json
|
||||
ADD {{.Network}}-cpp.json /dashboard/{{.Network}}-cpp.json
|
||||
ADD {{.Network}}-harmony.json /dashboard/{{.Network}}-harmony.json
|
||||
|
|
@ -519,7 +534,9 @@ ADD {{.Network}}-parity.json /dashboard/{{.Network}}-parity.json
|
|||
ADD {{.Network}}-python.json /dashboard/{{.Network}}-python.json
|
||||
ADD index.html /dashboard/index.html
|
||||
ADD puppeth.png /dashboard/puppeth.png
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["node", "/server.js"]
|
||||
`
|
||||
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ func (info *nodeInfos) Report() map[string]string {
|
|||
report["Miner account"] = info.etherbase
|
||||
}
|
||||
if info.keyJSON != "" {
|
||||
// XDPoS XinFin-DPoS signer
|
||||
// XDPoS delegated-proof-of-stake signer
|
||||
var key struct {
|
||||
Address string `json:"address"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ func (w *wizard) makeGenesis() {
|
|||
fmt.Println("Which consensus engine to use? (default = XDPoS)")
|
||||
fmt.Println(" 1. Ethash - proof-of-work")
|
||||
fmt.Println(" 2. Clique - proof-of-authority")
|
||||
fmt.Println(" 3. XDPoS - XinFin-DPoS")
|
||||
fmt.Println(" 3. XDPoS - delegated-proof-of-stake")
|
||||
|
||||
choice := w.read()
|
||||
switch {
|
||||
|
|
|
|||
|
|
@ -112,6 +112,12 @@ func NewApp(gitCommit, usage string) *cli.App {
|
|||
// are the same for all commands.
|
||||
|
||||
var (
|
||||
// XDC flags.
|
||||
RollbackFlag = cli.StringFlag{
|
||||
Name: "rollback",
|
||||
Usage: "Rollback chain at hash",
|
||||
Value: "",
|
||||
}
|
||||
// General settings
|
||||
AnnounceTxsFlag = cli.BoolFlag{
|
||||
Name: "announce-txs",
|
||||
|
|
@ -741,9 +747,9 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
|
|||
}
|
||||
}
|
||||
|
||||
// makeDatabaseHandles raises out the number of allowed file handles per process
|
||||
// MakeDatabaseHandles raises out the number of allowed file handles per process
|
||||
// for XDC and returns half of the allowance to assign to the database.
|
||||
func makeDatabaseHandles() int {
|
||||
func MakeDatabaseHandles() int {
|
||||
limit, err := fdlimit.Current()
|
||||
if err != nil {
|
||||
Fatalf("Failed to retrieve file descriptor allowance: %v", err)
|
||||
|
|
@ -1060,7 +1066,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
|||
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
|
||||
cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
|
||||
}
|
||||
cfg.DatabaseHandles = makeDatabaseHandles()
|
||||
cfg.DatabaseHandles = MakeDatabaseHandles()
|
||||
|
||||
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||
|
|
@ -1087,9 +1093,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
|
|||
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(StoreRewardFlag.Name) {
|
||||
cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
|
||||
if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) {
|
||||
os.Mkdir(cfg.StoreRewardFolder, os.ModePerm)
|
||||
common.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
|
||||
if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) {
|
||||
os.Mkdir(common.StoreRewardFolder, os.ModePerm)
|
||||
}
|
||||
}
|
||||
// Override any default configs for hard coded networks.
|
||||
|
|
@ -1206,7 +1212,7 @@ func SetupNetwork(ctx *cli.Context) {
|
|||
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
|
||||
var (
|
||||
cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
|
||||
handles = makeDatabaseHandles()
|
||||
handles = MakeDatabaseHandles()
|
||||
)
|
||||
name := "chaindata"
|
||||
if ctx.GlobalBool(LightModeFlag.Name) {
|
||||
|
|
@ -1256,6 +1262,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
|
|||
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
|
||||
})
|
||||
}
|
||||
Fatalf("Only support XDPoS consensus")
|
||||
}
|
||||
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||
|
|
|
|||
|
|
@ -27,4 +27,4 @@ var TIPSigning = big.NewInt(3000000)
|
|||
var IsTestnet bool = false
|
||||
var StoreRewardFolder string
|
||||
var RollbackHash Hash
|
||||
var MinGasPrice int64
|
||||
var MinGasPrice int64
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ const (
|
|||
RandomizeSMC = "0x0000000000000000000000000000000000000090"
|
||||
FoudationAddr = "0x0000000000000000000000000000000000000068"
|
||||
TeamAddr = "0x0000000000000000000000000000000000000099"
|
||||
VoteMethod = "0x6dd7d8ea"
|
||||
UnvoteMethod = "0x02aa9be2"
|
||||
ProposeMethod = "0x01267951"
|
||||
ResignMethod = "0xae6e43f5"
|
||||
SignMethod = "0xe341eaa4"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -45,6 +50,11 @@ var (
|
|||
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
||||
type Hash [HashLength]byte
|
||||
|
||||
type Vote struct {
|
||||
Masternode Address
|
||||
Voter Address
|
||||
}
|
||||
|
||||
func BytesToHash(b []byte) Hash {
|
||||
var h Hash
|
||||
h.SetBytes(b)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -29,7 +29,7 @@ type CompressionRleSuite struct{}
|
|||
var _ = checker.Suite(&CompressionRleSuite{})
|
||||
|
||||
func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
|
||||
exp := []byte{0xc5, 0xd2, 0x46, 0x1, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0XDC, 0xc7, 0x3, 0xc0, 0xe5, 0x0, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x4, 0x5d, 0x85, 0xa4, 0x70}
|
||||
exp := []byte{0xc5, 0xd2, 0x46, 0x1, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x3, 0xc0, 0xe5, 0x0, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x4, 0x5d, 0x85, 0xa4, 0x70}
|
||||
res, err := Decompress([]byte{token, 0xfd})
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(res, checker.DeepEquals, exp)
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package console
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
|
@ -155,33 +154,6 @@ func (env *tester) Close(t *testing.T) {
|
|||
os.RemoveAll(env.workspace)
|
||||
}
|
||||
|
||||
// Tests that the node lists the correct welcome message, notably that it contains
|
||||
// the instance name, coinbase account, block number, data directory and supported
|
||||
// console modules.
|
||||
func TestWelcome(t *testing.T) {
|
||||
tester := newTester(t, nil)
|
||||
defer tester.Close(t)
|
||||
|
||||
tester.console.Welcome()
|
||||
|
||||
output := tester.output.String()
|
||||
if want := "Welcome"; !strings.Contains(output, want) {
|
||||
t.Fatalf("console output missing welcome message: have\n%s\nwant also %s", output, want)
|
||||
}
|
||||
if want := fmt.Sprintf("instance: %s", testInstance); !strings.Contains(output, want) {
|
||||
t.Fatalf("console output missing instance: have\n%s\nwant also %s", output, want)
|
||||
}
|
||||
if want := fmt.Sprintf("coinbase: %s", testAddress); !strings.Contains(output, want) {
|
||||
t.Fatalf("console output missing coinbase: have\n%s\nwant also %s", output, want)
|
||||
}
|
||||
if want := "at block: 0"; !strings.Contains(output, want) {
|
||||
t.Fatalf("console output missing sync status: have\n%s\nwant also %s", output, want)
|
||||
}
|
||||
if want := fmt.Sprintf("datadir: %s", tester.workspace); !strings.Contains(output, want) {
|
||||
t.Fatalf("console output missing coinbase: have\n%s\nwant also %s", output, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that JavaScript statement evaluation works as intended.
|
||||
func TestEvaluate(t *testing.T) {
|
||||
tester := newTester(t, nil)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ package contracts
|
|||
// "randomSecret": 0,
|
||||
// "randomOpening": 1,
|
||||
// }
|
||||
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDC/chaindata"
|
||||
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDCchaindata"
|
||||
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
|
||||
//)
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import (
|
|||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/state"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
|
|
@ -85,7 +84,8 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
// Add tx signed to local tx pool.
|
||||
err = pool.AddLocal(txSigned)
|
||||
if err != nil {
|
||||
log.Warn("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||
log.Error("Fail to add tx sign to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||
return err
|
||||
}
|
||||
|
||||
// Create secret tx.
|
||||
|
|
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
err = pool.AddLocal(txSigned)
|
||||
if err != nil {
|
||||
log.Error("Fail to add tx secret to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||
return err
|
||||
}
|
||||
|
||||
// Put randomize key into chainDb.
|
||||
|
|
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
||||
if err != nil {
|
||||
log.Error("Fail to get randomize key from state db.", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
||||
|
|
@ -141,6 +143,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
|||
err = pool.AddLocal(txSigned)
|
||||
if err != nil {
|
||||
log.Error("Fail to add tx opening to local pool.", "error", err, "number", block.NumberU64(), "hash", block.Hash().Hex(), "from", account.Address, "nonce", nonce)
|
||||
return err
|
||||
}
|
||||
|
||||
// Clear randomize key in state db.
|
||||
|
|
@ -195,7 +198,12 @@ func BuildTxOpeningRandomize(nonce uint64, randomizeAddr common.Address, randomi
|
|||
}
|
||||
|
||||
// Get signers signed for blockNumber from blockSigner contract.
|
||||
func GetSignersFromContract(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
||||
func GetSignersFromContract(state *state.StateDB, block *types.Block) ([]common.Address, error) {
|
||||
return GetSigners(state, block), nil
|
||||
}
|
||||
|
||||
// Get signers signed for blockNumber from blockSigner contract.
|
||||
func GetSignersByExecutingEVM(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
||||
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
||||
if err != nil {
|
||||
log.Error("Fail get instance of blockSigner", "error", err)
|
||||
|
|
@ -207,7 +215,6 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
|
|||
log.Error("Fail get block signers", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return addrs, nil
|
||||
}
|
||||
|
||||
|
|
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
|||
intNumber, err := strconv.Atoi(decryptSecret)
|
||||
if err != nil {
|
||||
log.Error("Can not convert string to integer", "error", err)
|
||||
return -1, err
|
||||
}
|
||||
random = int64(intNumber)
|
||||
}
|
||||
|
|
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
|||
}
|
||||
|
||||
// Calculate reward for reward checkpoint.
|
||||
func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common.Address, number uint64, rCheckpoint uint64, client bind.ContractBackend, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
||||
func GetRewardForCheckpoint(c *XDPoS.XDPoS, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
||||
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
||||
number := header.Number.Uint64()
|
||||
prevCheckpoint := number - (rCheckpoint * 2)
|
||||
startBlockNumber := prevCheckpoint + 1
|
||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||
signers := make(map[common.Address]*rewardLog)
|
||||
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
|
||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
|
||||
mapBlkHash := map[uint64]common.Hash{}
|
||||
|
||||
if len(masternodes) > 0 {
|
||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||
block := chain.GetHeaderByNumber(i)
|
||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
||||
if err != nil {
|
||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
||||
return nil, err
|
||||
data := make(map[common.Hash][]common.Address)
|
||||
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||
header = chain.GetHeader(header.ParentHash, i)
|
||||
mapBlkHash[i] = header.Hash()
|
||||
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||
if !ok {
|
||||
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
|
||||
block := chain.GetBlock(header.Hash(), i)
|
||||
txs := block.Transactions()
|
||||
if !chain.Config().IsTIPSigning(header.Number) {
|
||||
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
|
||||
signData = c.CacheData(header, txs, receipts)
|
||||
} else {
|
||||
signData = c.CacheSigner(header.Hash(), txs)
|
||||
}
|
||||
}
|
||||
txs := signData.([]*types.Transaction)
|
||||
for _, tx := range txs {
|
||||
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
|
||||
from := *tx.From()
|
||||
data[blkHash] = append(data[blkHash], from)
|
||||
}
|
||||
}
|
||||
header = chain.GetHeader(header.ParentHash, prevCheckpoint)
|
||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(header)
|
||||
|
||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||
if i%common.MergeSignRange == 0 || !chain.Config().IsTIP2019(big.NewInt(int64(i))) {
|
||||
addrs := data[mapBlkHash[i]]
|
||||
// Filter duplicate address.
|
||||
if len(addrs) > 0 {
|
||||
addrSigners := make(map[common.Address]bool)
|
||||
|
|
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
|||
}
|
||||
|
||||
// Get candidate owner by address.
|
||||
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
||||
owner := signerAddr
|
||||
opts := new(bind.CallOpts)
|
||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
||||
if err != nil {
|
||||
log.Error("Fail get candidate owner", "error", err)
|
||||
return owner
|
||||
}
|
||||
|
||||
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||
owner := GetCandidateOwner(state, signerAddr)
|
||||
return owner
|
||||
}
|
||||
|
||||
// Calculate reward for holders.
|
||||
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.XDCValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
||||
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
|
||||
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward, blockNumber)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
if len(rewards) > 0 {
|
||||
for holder, reward := range rewards {
|
||||
state.AddBalance(holder, reward)
|
||||
}
|
||||
}
|
||||
return nil, rewards
|
||||
}
|
||||
|
||||
// Get reward balance rates for master node, founder and holders.
|
||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
||||
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
|
||||
owner := GetCandidatesOwnerBySigner(state, masterAddr)
|
||||
balances := make(map[common.Address]*big.Int)
|
||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||
balances[owner] = rewardMaster
|
||||
// Get voters for masternode.
|
||||
opts := new(bind.CallOpts)
|
||||
voters, err := validator.GetVoters(opts, masterAddr)
|
||||
if err != nil {
|
||||
log.Error("Fail to get voters", "error", err)
|
||||
return nil, err
|
||||
}
|
||||
voters := GetVoters(state, masterAddr)
|
||||
|
||||
if len(voters) > 0 {
|
||||
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||
|
|
@ -422,12 +432,10 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
|||
// Get voters capacities.
|
||||
voterCaps := make(map[common.Address]*big.Int)
|
||||
for _, voteAddr := range voters {
|
||||
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
|
||||
if err != nil {
|
||||
log.Error("Fail to get vote capacity", "error", err)
|
||||
return nil, err
|
||||
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
|
||||
continue
|
||||
}
|
||||
|
||||
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||
totalCap.Add(totalCap, voterCap)
|
||||
voterCaps[voteAddr] = voterCap
|
||||
}
|
||||
|
|
@ -447,9 +455,9 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
|||
}
|
||||
}
|
||||
|
||||
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
||||
balances[foudationWalletAddr] = foudationReward
|
||||
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||
balances[foundationWalletAddr] = foundationReward
|
||||
|
||||
jsonHolders, err := json.Marshal(balances)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ var twistB = &gfP2{
|
|||
var twistGen = &twistPoint{
|
||||
gfP2{
|
||||
gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b},
|
||||
gfP{0x8e83b5d102bc2026, 0XDCeb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b},
|
||||
gfP{0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b},
|
||||
},
|
||||
gfP2{
|
||||
gfP{0x64095b56c71856ee, 0XDC57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482},
|
||||
gfP{0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482},
|
||||
gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206},
|
||||
},
|
||||
gfP2{*newGFp(0), *newGFp(1)},
|
||||
|
|
|
|||
|
|
@ -1,191 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# vars from docker env
|
||||
# - IDENTITY (default to empty)
|
||||
# - PASSWORD (default to empty)
|
||||
# - PRIVATE_KEY (default to empty)
|
||||
# - BOOTNODES (default to empty)
|
||||
# - EXTIP (default to empty)
|
||||
# - VERBOSITY (default to 3)
|
||||
# - MAXPEERS (default to 25)
|
||||
# - SYNC_MODE (default to 'full')
|
||||
# - NETWORK_ID (default to '89')
|
||||
# - WS_SECRET (default to empty)
|
||||
# - NETSTATS_HOST (default to 'netstats-server:3000')
|
||||
# - NETSTATS_PORT (default to 'netstats-server:3000')
|
||||
|
||||
# constants
|
||||
DATA_DIR="data"
|
||||
KEYSTORE_DIR="keystore"
|
||||
|
||||
# variables
|
||||
genesisPath=""
|
||||
params=""
|
||||
accountsCount=$(
|
||||
XDC account list --datadir $DATA_DIR --keystore $KEYSTORE_DIR \
|
||||
2> /dev/null \
|
||||
| wc -l
|
||||
)
|
||||
|
||||
# file to env
|
||||
for env in IDENTITY PASSWORD PRIVATE_KEY BOOTNODES WS_SECRET NETSTATS_HOST \
|
||||
NETSTATS_PORT EXTIP SYNC_MODE NETWORK_ID ANNOUNCE_TXS STORE_REWARD DEBUG_MODE MAXPEERS; do
|
||||
file=$(eval echo "\$${env}_FILE")
|
||||
if [[ -f $file ]] && [[ ! -z $file ]]; then
|
||||
echo "Replacing $env by $file"
|
||||
export $env=$(cat $file)
|
||||
elif [[ "$env" == "BOOTNODES" ]] && [[ ! -z $file ]]; then
|
||||
echo "Bootnodes file is not available. Waiting for it to be provisioned..."
|
||||
while true ; do
|
||||
if [[ -f $file ]] && [[ $(grep -e enode $file) ]]; then
|
||||
echo "Fount bootnode file."
|
||||
break
|
||||
fi
|
||||
echo "Still no bootnodes file, sleeping..."
|
||||
sleep 5
|
||||
done
|
||||
export $env=$(cat $file)
|
||||
fi
|
||||
done
|
||||
|
||||
# networkid
|
||||
if [[ ! -z $NETWORK_ID ]]; then
|
||||
case $NETWORK_ID in
|
||||
88 )
|
||||
genesisPath="mainnet.json"
|
||||
;;
|
||||
89 )
|
||||
genesisPath="testnet.json"
|
||||
params="$params --XDC-testnet --gcmode archive --rpcapi db,eth,net,web3,personal,debug"
|
||||
;;
|
||||
90 )
|
||||
genesisPath="devnet.json"
|
||||
;;
|
||||
* )
|
||||
echo "network id not supported"
|
||||
;;
|
||||
esac
|
||||
params="$params --networkid $NETWORK_ID"
|
||||
fi
|
||||
|
||||
# data dir
|
||||
if [[ ! -d $DATA_DIR/XDC ]]; then
|
||||
echo "No blockchain data, creating genesis block."
|
||||
XDC init $genesisPath --datadir $DATA_DIR 2> /dev/null
|
||||
fi
|
||||
|
||||
# identity
|
||||
if [[ -z $IDENTITY ]]; then
|
||||
IDENTITY="unnamed_$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6)"
|
||||
fi
|
||||
|
||||
# password file
|
||||
if [[ ! -f ./password ]]; then
|
||||
if [[ ! -z $PASSWORD ]]; then
|
||||
echo "Password env is set. Writing into file."
|
||||
echo "$PASSWORD" > ./password
|
||||
else
|
||||
echo "No password set (or empty), generating a new one"
|
||||
$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-32} > password)
|
||||
fi
|
||||
fi
|
||||
|
||||
# private key
|
||||
if [[ $accountsCount -le 0 ]]; then
|
||||
echo "No accounts found"
|
||||
if [[ ! -z $PRIVATE_KEY ]]; then
|
||||
echo "Creating account from private key"
|
||||
echo "$PRIVATE_KEY" > ./private_key
|
||||
XDC account import ./private_key \
|
||||
--datadir $DATA_DIR \
|
||||
--keystore $KEYSTORE_DIR \
|
||||
--password ./password
|
||||
rm ./private_key
|
||||
else
|
||||
echo "Creating new account"
|
||||
XDC account new \
|
||||
--datadir $DATA_DIR \
|
||||
--keystore $KEYSTORE_DIR \
|
||||
--password ./password
|
||||
fi
|
||||
fi
|
||||
account=$(
|
||||
XDC account list --datadir $DATA_DIR --keystore $KEYSTORE_DIR \
|
||||
2> /dev/null \
|
||||
| head -n 1 \
|
||||
| cut -d"{" -f 2 | cut -d"}" -f 1
|
||||
)
|
||||
echo "Using account $account"
|
||||
params="$params --unlock $account"
|
||||
|
||||
# bootnodes
|
||||
if [[ ! -z $BOOTNODES ]]; then
|
||||
params="$params --bootnodes $BOOTNODES"
|
||||
fi
|
||||
|
||||
# extip
|
||||
if [[ ! -z $EXTIP ]]; then
|
||||
params="$params --nat extip:${EXTIP}"
|
||||
fi
|
||||
|
||||
# syncmode
|
||||
if [[ ! -z $SYNC_MODE ]]; then
|
||||
params="$params --syncmode ${SYNC_MODE}"
|
||||
fi
|
||||
|
||||
# netstats
|
||||
if [[ ! -z $WS_SECRET ]]; then
|
||||
echo "Will report to netstats server ${NETSTATS_HOST}:${NETSTATS_PORT}"
|
||||
params="$params --ethstats ${IDENTITY}:${WS_SECRET}@${NETSTATS_HOST}:${NETSTATS_PORT}"
|
||||
else
|
||||
echo "WS_SECRET not set, will not report to netstats server."
|
||||
fi
|
||||
|
||||
# annonce txs
|
||||
if [[ ! -z $ANNOUNCE_TXS ]]; then
|
||||
params="$params --announce-txs"
|
||||
fi
|
||||
|
||||
# store reward
|
||||
if [[ ! -z $STORE_REWARD ]]; then
|
||||
params="$params --store-reward"
|
||||
fi
|
||||
|
||||
# debug mode
|
||||
if [[ ! -z $DEBUG_MODE ]]; then
|
||||
params="$params --gcmode archive --rpcapi db,eth,net,web3,personal,debug"
|
||||
fi
|
||||
|
||||
# maxpeers
|
||||
if [[ -z $MAXPEERS ]]; then
|
||||
MAXPEERS=25
|
||||
fi
|
||||
|
||||
# dump
|
||||
echo "dump: $IDENTITY $account $BOOTNODES"
|
||||
|
||||
set -x
|
||||
|
||||
exec XDC $params \
|
||||
--verbosity $VERBOSITY \
|
||||
--datadir $DATA_DIR \
|
||||
--keystore $KEYSTORE_DIR \
|
||||
--identity $IDENTITY \
|
||||
--maxpeers $MAXPEERS \
|
||||
--password ./password \
|
||||
--port 30303 \
|
||||
--txpool.globalqueue 5000 \
|
||||
--txpool.globalslots 5000 \
|
||||
--rpc \
|
||||
--rpccorsdomain "*" \
|
||||
--rpcaddr 0.0.0.0 \
|
||||
--rpcport 8545 \
|
||||
--rpcvhosts "*" \
|
||||
--ws \
|
||||
--wsaddr 0.0.0.0 \
|
||||
--wsport 8546 \
|
||||
--wsorigins "*" \
|
||||
--mine \
|
||||
--gasprice "250000000" \
|
||||
--targetgaslimit "84000000" \
|
||||
"$@"
|
||||
Loading…
Reference in a new issue