mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 02:40:45 +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
|
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
|
||||||
|
|
@ -8,7 +7,7 @@ RUN cd /XDCchain && make XDC
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
LABEL maintainer="admin@xinfin.org"
|
LABEL maintainer="anil@xinfin.org"
|
||||||
|
|
||||||
WORKDIR /XDCchain
|
WORKDIR /XDCchain
|
||||||
|
|
||||||
|
|
@ -22,4 +21,3 @@ EXPOSE 30303
|
||||||
ENTRYPOINT ["/usr/local/bin/XDC"]
|
ENTRYPOINT ["/usr/local/bin/XDC"]
|
||||||
|
|
||||||
CMD ["--help"]
|
CMD ["--help"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ RUN chmod +x /XDCchain/build/bin/bootnode
|
||||||
|
|
||||||
FROM alpine:latest
|
FROM alpine:latest
|
||||||
|
|
||||||
LABEL maintainer="admin@xinfin.org"
|
LABEL maintainer="anil@xinfin.org"
|
||||||
|
|
||||||
WORKDIR /XDCchain
|
WORKDIR /XDCchain
|
||||||
|
|
||||||
|
|
@ -21,4 +21,4 @@ EXPOSE 30301
|
||||||
|
|
||||||
ENTRYPOINT ["./entrypoint.sh"]
|
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 \
|
RUN cd /XDChain \
|
||||||
&& make XDC \
|
&& make XDC\
|
||||||
&& chmod +x /XDCchain/build/bin/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 PASSWORD ''
|
||||||
ENV PRIVATE_KEY ''
|
ENV PRIVATE_KEY ''
|
||||||
ENV BOOTNODES ''
|
ENV BOOTNODES ''
|
||||||
|
|
@ -29,11 +29,11 @@ ENV NETSTATS_HOST 'netstats-server'
|
||||||
ENV NETSTATS_PORT '3000'
|
ENV NETSTATS_PORT '3000'
|
||||||
ENV ANNOUNCE_TXS ''
|
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/ ./
|
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"
|
||||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
"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/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/console"
|
"github.com/ethereum/go-ethereum/console"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -123,6 +124,7 @@ var (
|
||||||
configFileFlag,
|
configFileFlag,
|
||||||
utils.AnnounceTxsFlag,
|
utils.AnnounceTxsFlag,
|
||||||
utils.StoreRewardFlag,
|
utils.StoreRewardFlag,
|
||||||
|
utils.RollbackFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcFlags = []cli.Flag{
|
rpcFlags = []cli.Flag{
|
||||||
|
|
@ -291,9 +293,18 @@ func startNode(ctx *cli.Context, stack *node.Node, cfg XDCConfig) {
|
||||||
if _, ok := ethereum.Engine().(*XDPoS.XDPoS); ok {
|
if _, ok := ethereum.Engine().(*XDPoS.XDPoS); ok {
|
||||||
go func() {
|
go func() {
|
||||||
started := false
|
started := false
|
||||||
ok, err := ethereum.ValidateMasternode()
|
ok := false
|
||||||
if err != nil {
|
var err error
|
||||||
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 ok {
|
||||||
log.Info("Masternode found. Enabling staking mode...")
|
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)
|
defer close(core.CheckpointCh)
|
||||||
for range core.CheckpointCh {
|
for range core.CheckpointCh {
|
||||||
log.Info("Checkpoint!!! It's time to reconcile node's state...")
|
log.Info("Checkpoint!!! It's time to reconcile node's state...")
|
||||||
ok, err := ethereum.ValidateMasternode()
|
if common.IsTestnet {
|
||||||
if err != nil {
|
ok, err = ethereum.ValidateMasternodeTestnet()
|
||||||
utils.Fatalf("Can't verify masternode permission: %v", err)
|
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 !ok {
|
||||||
if started {
|
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 charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>{{.NetworkTitle}}: Ethereum Testnet</title>
|
<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/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/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">
|
<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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="nav-sm" style="overflow-x: hidden">
|
<body class="nav-sm" style="overflow-x: hidden">
|
||||||
<div class="container body">
|
<div class="container body">
|
||||||
<div class="main_container">
|
<div class="main_container">
|
||||||
|
|
@ -260,11 +263,13 @@ var dashboardContent = `
|
||||||
<pre>
|
<pre>
|
||||||
Enodes bootnodes = new Enodes();{{range .Bootnodes}}
|
Enodes bootnodes = new Enodes();{{range .Bootnodes}}
|
||||||
bootnodes.append(new Enode("{{.}}"));{{end}}
|
bootnodes.append(new Enode("{{.}}"));{{end}}
|
||||||
|
|
||||||
NodeConfig config = new NodeConfig();
|
NodeConfig config = new NodeConfig();
|
||||||
config.setBootstrapNodes(bootnodes);
|
config.setBootstrapNodes(bootnodes);
|
||||||
config.setEthereumNetworkID({{.NetworkID}});
|
config.setEthereumNetworkID({{.NetworkID}});
|
||||||
config.setEthereumGenesis(genesis);{{if .Ethstats}}
|
config.setEthereumGenesis(genesis);{{if .Ethstats}}
|
||||||
config.setEthereumNetStats("{{.Ethstats}}");{{end}}
|
config.setEthereumNetStats("{{.Ethstats}}");{{end}}
|
||||||
|
|
||||||
Node node = new Node(getFilesDir() + "/.{{.Network}}", config);
|
Node node = new Node(getFilesDir() + "/.{{.Network}}", config);
|
||||||
node.start();
|
node.start();
|
||||||
</pre>
|
</pre>
|
||||||
|
|
@ -288,13 +293,16 @@ node.start();
|
||||||
<pre>import Geth</pre>
|
<pre>import Geth</pre>
|
||||||
<pre>
|
<pre>
|
||||||
var error: NSError?
|
var error: NSError?
|
||||||
|
|
||||||
let bootnodes = GethNewEnodesEmpty(){{range .Bootnodes}}
|
let bootnodes = GethNewEnodesEmpty(){{range .Bootnodes}}
|
||||||
bootnodes?.append(GethNewEnode("{{.}}", &error)){{end}}
|
bootnodes?.append(GethNewEnode("{{.}}", &error)){{end}}
|
||||||
|
|
||||||
let config = GethNewNodeConfig()
|
let config = GethNewNodeConfig()
|
||||||
config?.setBootstrapNodes(bootnodes)
|
config?.setBootstrapNodes(bootnodes)
|
||||||
config?.setEthereumNetworkID({{.NetworkID}})
|
config?.setEthereumNetworkID({{.NetworkID}})
|
||||||
config?.setEthereumGenesis(genesis){{if .Ethstats}}
|
config?.setEthereumGenesis(genesis){{if .Ethstats}}
|
||||||
config?.setEthereumNetStats("{{.Ethstats}}"){{end}}
|
config?.setEthereumNetStats("{{.Ethstats}}"){{end}}
|
||||||
|
|
||||||
let datadir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
let datadir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
|
||||||
let node = GethNewNode(datadir + "/.{{.Network}}", config, &error);
|
let node = GethNewNode(datadir + "/.{{.Network}}", config, &error);
|
||||||
try! node?.start();
|
try! node?.start();
|
||||||
|
|
@ -428,12 +436,14 @@ try! node?.start();
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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/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/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 src="https://cdnjs.cloudflare.com/ajax/libs/gentelella/1.3.0/js/custom.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
var load = function(hash) {
|
var load = function(hash) {
|
||||||
window.location.hash = hash;
|
window.location.hash = hash;
|
||||||
|
|
||||||
// Fade out all possible pages (yes, ugly, no, don't care)
|
// Fade out all possible pages (yes, ugly, no, don't care)
|
||||||
$("#geth").fadeOut(300)
|
$("#geth").fadeOut(300)
|
||||||
$("#mist").fadeOut(300)
|
$("#mist").fadeOut(300)
|
||||||
|
|
@ -441,6 +451,7 @@ try! node?.start();
|
||||||
$("#other").fadeOut(300)
|
$("#other").fadeOut(300)
|
||||||
$("#about").fadeOut(300)
|
$("#about").fadeOut(300)
|
||||||
$("#frame-wrapper").fadeOut(300);
|
$("#frame-wrapper").fadeOut(300);
|
||||||
|
|
||||||
// Depending on the hash, resolve it into a local or remote URL
|
// Depending on the hash, resolve it into a local or remote URL
|
||||||
var url = hash;
|
var url = hash;
|
||||||
switch (hash) {
|
switch (hash) {
|
||||||
|
|
@ -472,6 +483,7 @@ try! node?.start();
|
||||||
var sidebar = $($(".navbar")[0]).width();
|
var sidebar = $($(".navbar")[0]).width();
|
||||||
var limit = document.body.clientWidth - sidebar;
|
var limit = document.body.clientWidth - sidebar;
|
||||||
var scale = limit / 1920;
|
var scale = limit / 1920;
|
||||||
|
|
||||||
$("#frame-wrapper").width(limit);
|
$("#frame-wrapper").width(limit);
|
||||||
$("#frame-wrapper").height(document.body.clientHeight / scale);
|
$("#frame-wrapper").height(document.body.clientHeight / scale);
|
||||||
$("#frame-wrapper").css({
|
$("#frame-wrapper").css({
|
||||||
|
|
@ -480,6 +492,7 @@ try! node?.start();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
$(window).resize(resize);
|
$(window).resize(resize);
|
||||||
|
|
||||||
if (window.location.hash == "") {
|
if (window.location.hash == "") {
|
||||||
var item = $(".side-menu").children()[0];
|
var item = $(".side-menu").children()[0];
|
||||||
$(item).children()[0].click();
|
$(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.
|
// to aggregate various private network services under one easily accessible page.
|
||||||
var dashboardDockerfile = `
|
var dashboardDockerfile = `
|
||||||
FROM mhart/alpine-node:latest
|
FROM mhart/alpine-node:latest
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
npm install connect serve-static && \
|
npm install connect serve-static && \
|
||||||
\
|
\
|
||||||
|
|
@ -512,6 +526,7 @@ RUN \
|
||||||
echo 'connect().use(serveStatic("/dashboard")).listen(80, function(){' >> server.js && \
|
echo 'connect().use(serveStatic("/dashboard")).listen(80, function(){' >> server.js && \
|
||||||
echo ' console.log("Server running on 80...");' >> server.js && \
|
echo ' console.log("Server running on 80...");' >> server.js && \
|
||||||
echo '});' >> server.js
|
echo '});' >> server.js
|
||||||
|
|
||||||
ADD {{.Network}}.json /dashboard/{{.Network}}.json
|
ADD {{.Network}}.json /dashboard/{{.Network}}.json
|
||||||
ADD {{.Network}}-cpp.json /dashboard/{{.Network}}-cpp.json
|
ADD {{.Network}}-cpp.json /dashboard/{{.Network}}-cpp.json
|
||||||
ADD {{.Network}}-harmony.json /dashboard/{{.Network}}-harmony.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 {{.Network}}-python.json /dashboard/{{.Network}}-python.json
|
||||||
ADD index.html /dashboard/index.html
|
ADD index.html /dashboard/index.html
|
||||||
ADD puppeth.png /dashboard/puppeth.png
|
ADD puppeth.png /dashboard/puppeth.png
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
CMD ["node", "/server.js"]
|
CMD ["node", "/server.js"]
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,7 @@ func (info *nodeInfos) Report() map[string]string {
|
||||||
report["Miner account"] = info.etherbase
|
report["Miner account"] = info.etherbase
|
||||||
}
|
}
|
||||||
if info.keyJSON != "" {
|
if info.keyJSON != "" {
|
||||||
// XDPoS XinFin-DPoS signer
|
// XDPoS delegated-proof-of-stake signer
|
||||||
var key struct {
|
var key struct {
|
||||||
Address string `json:"address"`
|
Address string `json:"address"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ func (w *wizard) makeGenesis() {
|
||||||
fmt.Println("Which consensus engine to use? (default = XDPoS)")
|
fmt.Println("Which consensus engine to use? (default = XDPoS)")
|
||||||
fmt.Println(" 1. Ethash - proof-of-work")
|
fmt.Println(" 1. Ethash - proof-of-work")
|
||||||
fmt.Println(" 2. Clique - proof-of-authority")
|
fmt.Println(" 2. Clique - proof-of-authority")
|
||||||
fmt.Println(" 3. XDPoS - XinFin-DPoS")
|
fmt.Println(" 3. XDPoS - delegated-proof-of-stake")
|
||||||
|
|
||||||
choice := w.read()
|
choice := w.read()
|
||||||
switch {
|
switch {
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,12 @@ func NewApp(gitCommit, usage string) *cli.App {
|
||||||
// are the same for all commands.
|
// are the same for all commands.
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
// XDC flags.
|
||||||
|
RollbackFlag = cli.StringFlag{
|
||||||
|
Name: "rollback",
|
||||||
|
Usage: "Rollback chain at hash",
|
||||||
|
Value: "",
|
||||||
|
}
|
||||||
// General settings
|
// General settings
|
||||||
AnnounceTxsFlag = cli.BoolFlag{
|
AnnounceTxsFlag = cli.BoolFlag{
|
||||||
Name: "announce-txs",
|
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.
|
// for XDC and returns half of the allowance to assign to the database.
|
||||||
func makeDatabaseHandles() int {
|
func MakeDatabaseHandles() int {
|
||||||
limit, err := fdlimit.Current()
|
limit, err := fdlimit.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("Failed to retrieve file descriptor allowance: %v", err)
|
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) {
|
if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
|
||||||
cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
|
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" {
|
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
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)
|
cfg.EnablePreimageRecording = ctx.GlobalBool(VMEnableDebugFlag.Name)
|
||||||
}
|
}
|
||||||
if ctx.GlobalIsSet(StoreRewardFlag.Name) {
|
if ctx.GlobalIsSet(StoreRewardFlag.Name) {
|
||||||
cfg.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
|
common.StoreRewardFolder = filepath.Join(stack.DataDir(), "XDC", "rewards")
|
||||||
if _, err := os.Stat(cfg.StoreRewardFolder); os.IsNotExist(err) {
|
if _, err := os.Stat(common.StoreRewardFolder); os.IsNotExist(err) {
|
||||||
os.Mkdir(cfg.StoreRewardFolder, os.ModePerm)
|
os.Mkdir(common.StoreRewardFolder, os.ModePerm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Override any default configs for hard coded networks.
|
// 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 {
|
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
|
||||||
var (
|
var (
|
||||||
cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
|
cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
|
||||||
handles = makeDatabaseHandles()
|
handles = MakeDatabaseHandles()
|
||||||
)
|
)
|
||||||
name := "chaindata"
|
name := "chaindata"
|
||||||
if ctx.GlobalBool(LightModeFlag.Name) {
|
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,
|
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Fatalf("Only support XDPoS consensus")
|
||||||
}
|
}
|
||||||
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,4 @@ var TIPSigning = big.NewInt(3000000)
|
||||||
var IsTestnet bool = false
|
var IsTestnet bool = false
|
||||||
var StoreRewardFolder string
|
var StoreRewardFolder string
|
||||||
var RollbackHash Hash
|
var RollbackHash Hash
|
||||||
var MinGasPrice int64
|
var MinGasPrice int64
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,11 @@ const (
|
||||||
RandomizeSMC = "0x0000000000000000000000000000000000000090"
|
RandomizeSMC = "0x0000000000000000000000000000000000000090"
|
||||||
FoudationAddr = "0x0000000000000000000000000000000000000068"
|
FoudationAddr = "0x0000000000000000000000000000000000000068"
|
||||||
TeamAddr = "0x0000000000000000000000000000000000000099"
|
TeamAddr = "0x0000000000000000000000000000000000000099"
|
||||||
|
VoteMethod = "0x6dd7d8ea"
|
||||||
|
UnvoteMethod = "0x02aa9be2"
|
||||||
|
ProposeMethod = "0x01267951"
|
||||||
|
ResignMethod = "0xae6e43f5"
|
||||||
|
SignMethod = "0xe341eaa4"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -45,6 +50,11 @@ var (
|
||||||
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
// Hash represents the 32 byte Keccak256 hash of arbitrary data.
|
||||||
type Hash [HashLength]byte
|
type Hash [HashLength]byte
|
||||||
|
|
||||||
|
type Vote struct {
|
||||||
|
Masternode Address
|
||||||
|
Voter Address
|
||||||
|
}
|
||||||
|
|
||||||
func BytesToHash(b []byte) Hash {
|
func BytesToHash(b []byte) Hash {
|
||||||
var h Hash
|
var h Hash
|
||||||
h.SetBytes(b)
|
h.SetBytes(b)
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -29,7 +29,7 @@ type CompressionRleSuite struct{}
|
||||||
var _ = checker.Suite(&CompressionRleSuite{})
|
var _ = checker.Suite(&CompressionRleSuite{})
|
||||||
|
|
||||||
func (s *CompressionRleSuite) TestDecompressSimple(c *checker.C) {
|
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})
|
res, err := Decompress([]byte{token, 0xfd})
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Assert(res, checker.DeepEquals, exp)
|
c.Assert(res, checker.DeepEquals, exp)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package console
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -155,33 +154,6 @@ func (env *tester) Close(t *testing.T) {
|
||||||
os.RemoveAll(env.workspace)
|
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.
|
// Tests that JavaScript statement evaluation works as intended.
|
||||||
func TestEvaluate(t *testing.T) {
|
func TestEvaluate(t *testing.T) {
|
||||||
tester := newTester(t, nil)
|
tester := newTester(t, nil)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ package contracts
|
||||||
// "randomSecret": 0,
|
// "randomSecret": 0,
|
||||||
// "randomOpening": 1,
|
// "randomOpening": 1,
|
||||||
// }
|
// }
|
||||||
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDC/chaindata"
|
// datadir = "/mnt/sgp1_tuna_chaindata3/data/XDCchaindata"
|
||||||
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
|
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
|
||||||
//)
|
//)
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
"github.com/ethereum/go-ethereum/consensus/XDPoS"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/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"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"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.
|
// Add tx signed to local tx pool.
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
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.
|
// Create secret tx.
|
||||||
|
|
@ -114,6 +114,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
err = pool.AddLocal(txSigned)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
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)
|
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.
|
// Put randomize key into chainDb.
|
||||||
|
|
@ -125,6 +126,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
randomizeKeyValue, err := chainDb.Get(randomizeKeyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get randomize key from state db.", "error", err)
|
log.Error("Fail to get randomize key from state db.", "error", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := BuildTxOpeningRandomize(nonce+1, common.HexToAddress(common.RandomizeSMC), randomizeKeyValue)
|
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)
|
err = pool.AddLocal(txSigned)
|
||||||
if err != nil {
|
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)
|
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.
|
// 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.
|
// 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)
|
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of blockSigner", "error", err)
|
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)
|
log.Error("Fail get block signers", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return addrs, nil
|
return addrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,6 +296,7 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
intNumber, err := strconv.Atoi(decryptSecret)
|
intNumber, err := strconv.Atoi(decryptSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Can not convert string to integer", "error", err)
|
log.Error("Can not convert string to integer", "error", err)
|
||||||
|
return -1, err
|
||||||
}
|
}
|
||||||
random = int64(intNumber)
|
random = int64(intNumber)
|
||||||
}
|
}
|
||||||
|
|
@ -299,23 +307,44 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for reward checkpoint.
|
// 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.
|
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
|
||||||
|
number := header.Number.Uint64()
|
||||||
prevCheckpoint := number - (rCheckpoint * 2)
|
prevCheckpoint := number - (rCheckpoint * 2)
|
||||||
startBlockNumber := prevCheckpoint + 1
|
startBlockNumber := prevCheckpoint + 1
|
||||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||||
signers := make(map[common.Address]*rewardLog)
|
signers := make(map[common.Address]*rewardLog)
|
||||||
prevHeaderCheckpoint := chain.GetHeaderByNumber(prevCheckpoint)
|
mapBlkHash := map[uint64]common.Hash{}
|
||||||
masternodes := XDPoS.GetMasternodesFromCheckpointHeader(prevHeaderCheckpoint)
|
|
||||||
|
|
||||||
if len(masternodes) > 0 {
|
data := make(map[common.Hash][]common.Address)
|
||||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
for i := prevCheckpoint + (rCheckpoint * 2) - 1; i >= startBlockNumber; i-- {
|
||||||
block := chain.GetHeaderByNumber(i)
|
header = chain.GetHeader(header.ParentHash, i)
|
||||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
mapBlkHash[i] = header.Hash()
|
||||||
if err != nil {
|
signData, ok := c.BlockSigners.Get(header.Hash())
|
||||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
if !ok {
|
||||||
return nil, err
|
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.
|
// Filter duplicate address.
|
||||||
if len(addrs) > 0 {
|
if len(addrs) > 0 {
|
||||||
addrSigners := make(map[common.Address]bool)
|
addrSigners := make(map[common.Address]bool)
|
||||||
|
|
@ -374,46 +403,27 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get candidate owner by address.
|
// Get candidate owner by address.
|
||||||
func GetCandidatesOwnerBySigner(validator *contractValidator.XDCValidator, signerAddr common.Address) common.Address {
|
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||||
owner := signerAddr
|
owner := GetCandidateOwner(state, signerAddr)
|
||||||
opts := new(bind.CallOpts)
|
|
||||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail get candidate owner", "error", err)
|
|
||||||
return owner
|
|
||||||
}
|
|
||||||
|
|
||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for holders.
|
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int, blockNumber uint64) (error, map[common.Address]*big.Int) {
|
||||||
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(foundationWalletAddr, state, signer, calcReward, blockNumber)
|
||||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
if len(rewards) > 0 {
|
|
||||||
for holder, reward := range rewards {
|
|
||||||
state.AddBalance(holder, reward)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, rewards
|
return nil, rewards
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reward balance rates for master node, founder and holders.
|
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int, blockNumber uint64) (map[common.Address]*big.Int, error) {
|
||||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.XDCValidator) (map[common.Address]*big.Int, error) {
|
owner := GetCandidatesOwnerBySigner(state, masterAddr)
|
||||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
|
||||||
balances := make(map[common.Address]*big.Int)
|
balances := make(map[common.Address]*big.Int)
|
||||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
balances[owner] = rewardMaster
|
balances[owner] = rewardMaster
|
||||||
// Get voters for masternode.
|
// Get voters for masternode.
|
||||||
opts := new(bind.CallOpts)
|
voters := GetVoters(state, masterAddr)
|
||||||
voters, err := validator.GetVoters(opts, masterAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to get voters", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(voters) > 0 {
|
if len(voters) > 0 {
|
||||||
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
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.
|
// Get voters capacities.
|
||||||
voterCaps := make(map[common.Address]*big.Int)
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
for _, voteAddr := range voters {
|
for _, voteAddr := range voters {
|
||||||
voterCap, err := validator.GetVoterCap(opts, masterAddr, voteAddr)
|
if _, ok := voterCaps[voteAddr]; ok && common.TIP2019Block.Uint64() <= blockNumber {
|
||||||
if err != nil {
|
continue
|
||||||
log.Error("Fail to get vote capacity", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||||
totalCap.Add(totalCap, voterCap)
|
totalCap.Add(totalCap, voterCap)
|
||||||
voterCaps[voteAddr] = 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))
|
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||||
balances[foudationWalletAddr] = foudationReward
|
balances[foundationWalletAddr] = foundationReward
|
||||||
|
|
||||||
jsonHolders, err := json.Marshal(balances)
|
jsonHolders, err := json.Marshal(balances)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ var twistB = &gfP2{
|
||||||
var twistGen = &twistPoint{
|
var twistGen = &twistPoint{
|
||||||
gfP2{
|
gfP2{
|
||||||
gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b},
|
gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b},
|
||||||
gfP{0x8e83b5d102bc2026, 0XDCeb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b},
|
gfP{0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b},
|
||||||
},
|
},
|
||||||
gfP2{
|
gfP2{
|
||||||
gfP{0x64095b56c71856ee, 0XDC57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482},
|
gfP{0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482},
|
||||||
gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206},
|
gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206},
|
||||||
},
|
},
|
||||||
gfP2{*newGFp(0), *newGFp(1)},
|
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