Minor error fixed.

This commit is contained in:
AnilChinchawale 2019-03-16 16:02:10 +05:30
parent bf626ddc95
commit a638d2adc0
21 changed files with 415 additions and 451 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "tests"]
path = tests/testdata
url = https://github.com/ethereum/tests

View file

@ -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"]

View file

@ -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"]

View file

@ -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"]

View file

@ -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

View file

@ -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()
}
}

View file

@ -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
View 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
}

View file

@ -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"]
`

View file

@ -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"`
}

View file

@ -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 {

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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"
//)
//

View file

@ -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 {

View file

@ -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)},

View file

@ -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" \
"$@"