mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
merge upstream
This commit is contained in:
commit
2cfae3e48a
26 changed files with 357 additions and 145 deletions
50
.travis.yml
50
.travis.yml
|
|
@ -2,10 +2,10 @@ sudo: required
|
||||||
language: go
|
language: go
|
||||||
go_import_path: github.com/ethereum/go-ethereum
|
go_import_path: github.com/ethereum/go-ethereum
|
||||||
services: skip
|
services: skip
|
||||||
before_install: skip
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
include:
|
include:
|
||||||
|
|
||||||
- stage: Lint
|
- stage: Lint
|
||||||
os: linux
|
os: linux
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
@ -15,6 +15,7 @@ jobs:
|
||||||
submodules: false
|
submodules: false
|
||||||
script:
|
script:
|
||||||
- go run build/ci.go lint
|
- go run build/ci.go lint
|
||||||
|
|
||||||
- stage: Build and test
|
- stage: Build and test
|
||||||
os: linux
|
os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
|
|
@ -38,28 +39,59 @@ jobs:
|
||||||
- while sleep 540; do echo "[ still running ]"; done &
|
- while sleep 540; do echo "[ still running ]"; done &
|
||||||
- go run build/ci.go test -coverage
|
- go run build/ci.go test -coverage
|
||||||
- kill %1
|
- kill %1
|
||||||
- stage: Build and push Docker image
|
|
||||||
|
- stage: Github release
|
||||||
|
script:
|
||||||
|
- make tomo
|
||||||
|
- mv build/bin/tomo build/bin/tomo-linux-amd64
|
||||||
|
deploy:
|
||||||
|
provider: releases
|
||||||
|
api_key: $GITHUB_TOKEN
|
||||||
|
file:
|
||||||
|
- "build/bin/tomo-linux-amd64"
|
||||||
|
skip_cleanup: true
|
||||||
|
on:
|
||||||
|
branch: master
|
||||||
|
tags: true
|
||||||
|
|
||||||
|
- stage: Build and push tomochain/tomochain image
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
before_install:
|
before_install:
|
||||||
- docker build -t tomochain/tomochain .
|
- docker build -t tomochain/tomochain .
|
||||||
- docker run tomochain/tomochain
|
- docker run tomochain/tomochain
|
||||||
|
install: skip
|
||||||
|
script: skip
|
||||||
deploy:
|
deploy:
|
||||||
provider: script
|
- provider: script
|
||||||
script: bash docker_push.sh
|
script:
|
||||||
|
- bash docker_push.sh latest
|
||||||
|
- bash docker_push.sh $TRAVIS_BUILD_ID
|
||||||
on:
|
on:
|
||||||
branch: master
|
branch: master
|
||||||
- stage: Trigger rebuild of infrastructure image
|
tags: false
|
||||||
|
- provider: script
|
||||||
|
script:
|
||||||
|
- bash docker_push.sh latest
|
||||||
|
- bash docker_push.sh $TRAVIS_TAG
|
||||||
|
on:
|
||||||
|
branch: master
|
||||||
|
tags: true
|
||||||
|
|
||||||
|
- stage: Trigger rebuild of tomochain/infra-tomochain image
|
||||||
sudo: false
|
sudo: false
|
||||||
|
install: skip
|
||||||
script: bash docker_rebuild.sh
|
script: bash docker_rebuild.sh
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- name: Lint
|
- name: Lint
|
||||||
- name: Build and test
|
- name: Build and test
|
||||||
- name: Build and push Docker image
|
- name: Github release
|
||||||
if: type != pull_request AND branch = master
|
if: type != pull_request AND branch = master AND tag = true AND repo = tomochain/tomochain
|
||||||
- name: Trigger rebuild of infrastructure image
|
- name: Build and push tomochain/tomochain image
|
||||||
if: type != pull_request AND branch = master
|
if: type != pull_request AND branch = master AND repo = tomochain/tomochain
|
||||||
|
- name: Trigger rebuild of tomochain/infra-tomochain image
|
||||||
|
if: type != pull_request AND branch = master AND repo = tomochain/tomochain
|
||||||
|
|
||||||
notifications:
|
notifications:
|
||||||
slack:
|
slack:
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,6 @@ RUN chmod +x /usr/local/bin/tomo
|
||||||
EXPOSE 8545
|
EXPOSE 8545
|
||||||
EXPOSE 30303
|
EXPOSE 30303
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/tomo", "--help"]
|
ENTRYPOINT ["/usr/local/bin/tomo"]
|
||||||
|
|
||||||
|
CMD ["--help"]
|
||||||
|
|
|
||||||
22
Dockerfile.bootnode
Normal file
22
Dockerfile.bootnode
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
FROM golang:1.10-alpine as builder
|
||||||
|
|
||||||
|
RUN apk add --no-cache make gcc musl-dev linux-headers
|
||||||
|
|
||||||
|
ADD . /tomochain
|
||||||
|
RUN cd /tomochain && make bootnode
|
||||||
|
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
LABEL maintainer="etienne@tomochain.com"
|
||||||
|
|
||||||
|
WORKDIR /tomochain
|
||||||
|
|
||||||
|
COPY --from=builder /tomochain/build/bin/bootnode /usr/local/bin/bootnode
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/bootnode
|
||||||
|
|
||||||
|
EXPOSE 30301
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/bootnode"]
|
||||||
|
|
||||||
|
CMD ["--help"]
|
||||||
5
Makefile
5
Makefile
|
|
@ -21,6 +21,11 @@ tomo:
|
||||||
@echo "Done building."
|
@echo "Done building."
|
||||||
@echo "Run \"$(GOBIN)/tomo\" to launch tomo."
|
@echo "Run \"$(GOBIN)/tomo\" to launch tomo."
|
||||||
|
|
||||||
|
bootnode:
|
||||||
|
build/env.sh go run build/ci.go install ./cmd/bootnode
|
||||||
|
@echo "Done building."
|
||||||
|
@echo "Run \"$(GOBIN)/bootnode\" to launch a bootnode."
|
||||||
|
|
||||||
swarm:
|
swarm:
|
||||||
build/env.sh go run build/ci.go install ./cmd/swarm
|
build/env.sh go run build/ci.go install ./cmd/swarm
|
||||||
@echo "Done building."
|
@echo "Done building."
|
||||||
|
|
|
||||||
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
|
|
||||||
|
|
@ -115,7 +115,8 @@ func (w *wizard) makeGenesis() {
|
||||||
|
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
fmt.Println("How many blocks per checkpoint? (default = 990)")
|
fmt.Println("How many blocks per checkpoint? (default = 990)")
|
||||||
genesis.Config.Clique.RewardCheckpoint = uint64(w.readDefaultInt(990))
|
genesis.Config.Clique.Epoch = uint64(w.readDefaultInt(990))
|
||||||
|
genesis.Config.Clique.RewardCheckpoint = genesis.Config.Clique.Epoch
|
||||||
|
|
||||||
case choice == "3":
|
case choice == "3":
|
||||||
genesis.Difficulty = big.NewInt(1)
|
genesis.Difficulty = big.NewInt(1)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// tomo is the official command-line client for Ethereum.
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -51,7 +50,7 @@ var (
|
||||||
// Git SHA1 commit hash of the release (set via linker flags)
|
// Git SHA1 commit hash of the release (set via linker flags)
|
||||||
gitCommit = ""
|
gitCommit = ""
|
||||||
// The app that holds all commands and flags.
|
// The app that holds all commands and flags.
|
||||||
app = utils.NewApp(gitCommit, "the go-ethereum command line interface")
|
app = utils.NewApp(gitCommit, "the tomochain command line interface")
|
||||||
// flags that configure the node
|
// flags that configure the node
|
||||||
nodeFlags = []cli.Flag{
|
nodeFlags = []cli.Flag{
|
||||||
utils.IdentityFlag,
|
utils.IdentityFlag,
|
||||||
|
|
@ -151,7 +150,7 @@ func init() {
|
||||||
// Initialize the CLI app and start tomo
|
// Initialize the CLI app and start tomo
|
||||||
app.Action = tomo
|
app.Action = tomo
|
||||||
app.HideVersion = true // we have a command to print the version
|
app.HideVersion = true // we have a command to print the version
|
||||||
app.Copyright = "Copyright 2013-2017 The go-ethereum Authors"
|
app.Copyright = "Copyright (c) 2018 Tomochain"
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
// See chaincmd.go:
|
// See chaincmd.go:
|
||||||
initCommand,
|
initCommand,
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import (
|
||||||
var AppHelpTemplate = `NAME:
|
var AppHelpTemplate = `NAME:
|
||||||
{{.App.Name}} - {{.App.Usage}}
|
{{.App.Name}} - {{.App.Usage}}
|
||||||
|
|
||||||
Copyright 2013-2017 The go-ethereum Authors
|
Copyright (c) 2018 Tomochain
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}
|
{{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ const (
|
||||||
inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory
|
inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory
|
||||||
inmemorySignatures = 4096 // Number of recent block signatures to keep in memory
|
inmemorySignatures = 4096 // Number of recent block signatures to keep in memory
|
||||||
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
|
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Masternode struct {
|
type Masternode struct {
|
||||||
|
|
@ -405,7 +404,9 @@ func (c *Clique) GetMasternodes(chain consensus.ChainReader, header *types.Heade
|
||||||
return masternodes
|
return masternodes
|
||||||
}
|
}
|
||||||
|
|
||||||
func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (bool, error) {
|
func (c *Clique) GetPeriod() uint64 { return c.config.Period }
|
||||||
|
|
||||||
|
func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (int, int, bool, error) {
|
||||||
pre := common.Address{}
|
pre := common.Address{}
|
||||||
// masternode[0] has chance to create block 1
|
// masternode[0] has chance to create block 1
|
||||||
var err error
|
var err error
|
||||||
|
|
@ -413,16 +414,19 @@ func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header
|
||||||
if header.Number.Uint64() != 0 {
|
if header.Number.Uint64() != 0 {
|
||||||
pre, err = ecrecover(header, snap.sigcache)
|
pre, err = ecrecover(header, snap.sigcache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return 0, 0, false, err
|
||||||
}
|
}
|
||||||
preIndex = position(masternodes, pre)
|
preIndex = position(masternodes, pre)
|
||||||
}
|
}
|
||||||
curIndex := position(masternodes, cur)
|
curIndex := position(masternodes, cur)
|
||||||
log.Info("Debugging info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
|
log.Info("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
|
||||||
for i, s := range masternodes {
|
for i, s := range masternodes {
|
||||||
fmt.Printf("%d - %s\n", i, s.String())
|
fmt.Printf("%d - %s\n", i, s.String())
|
||||||
}
|
}
|
||||||
return (preIndex+1)%len(masternodes) == curIndex, nil
|
if (preIndex+1)%len(masternodes) == curIndex {
|
||||||
|
return preIndex, curIndex, true, nil
|
||||||
|
}
|
||||||
|
return preIndex, curIndex, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// snapshot retrieves the authorization snapshot at a given point in time.
|
// snapshot retrieves the authorization snapshot at a given point in time.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package blocksigner
|
package blocksigner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package blocksigner
|
package blocksigner
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -11,6 +26,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"math/rand"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -39,7 +55,16 @@ func TestBlockSigner(t *testing.T) {
|
||||||
}
|
}
|
||||||
contractBackend.ForEachStorageAt(ctx, blockSignerAddress, nil, f)
|
contractBackend.ForEachStorageAt(ctx, blockSignerAddress, nil, f)
|
||||||
|
|
||||||
byte0 := [32]byte{}
|
byte0 := randomHash()
|
||||||
|
|
||||||
|
// Test sign.
|
||||||
|
tx, err := blockSigner.Sign(big.NewInt(50), byte0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("can't sign: %v", err)
|
||||||
|
}
|
||||||
|
contractBackend.Commit()
|
||||||
|
t.Log("tx", tx)
|
||||||
|
|
||||||
signers, err := blockSigner.GetSigners(byte0)
|
signers, err := blockSigner.GetSigners(byte0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't get candidates: %v", err)
|
t.Fatalf("can't get candidates: %v", err)
|
||||||
|
|
@ -47,11 +72,15 @@ func TestBlockSigner(t *testing.T) {
|
||||||
for _, it := range signers {
|
for _, it := range signers {
|
||||||
t.Log("signer", it.String())
|
t.Log("signer", it.String())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
s, err := blockSigner.Sign(big.NewInt(1), byte0)
|
|
||||||
if err != nil {
|
// Generate random string.
|
||||||
t.Fatalf("can't sign: %v", err)
|
func randomHash() common.Hash {
|
||||||
}
|
letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
|
||||||
t.Log("tx data", s)
|
var b common.Hash
|
||||||
contractBackend.Commit()
|
for i := range b {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
b[i] = letterBytes[rand.Intn(len(letterBytes))]
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ contract BlockSigner {
|
||||||
|
|
||||||
function sign(uint256 _blockNumber, bytes32 _blockHash) external {
|
function sign(uint256 _blockNumber, bytes32 _blockHash) external {
|
||||||
// consensus should validate all senders are validators, gas = 0
|
// consensus should validate all senders are validators, gas = 0
|
||||||
require(block.number >= _blockNumber);
|
//require(block.number >= _blockNumber);
|
||||||
require(block.number <= _blockNumber.add(epochNumber * 2));
|
//require(block.number <= _blockNumber.add(epochNumber * 2));
|
||||||
blocks[_blockNumber].push(_blockHash);
|
blocks[_blockNumber].push(_blockHash);
|
||||||
blockSigners[_blockHash].push(msg.sender);
|
blockSigners[_blockHash].push(msg.sender);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
const BlockSignerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"sign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"getSigners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"epochNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_epochNumber\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_signer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"Sign\",\"type\":\"event\"}]"
|
const BlockSignerABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"sign\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"getSigners\",\"outputs\":[{\"name\":\"\",\"type\":\"address[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"epochNumber\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"_epochNumber\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"_signer\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_blockNumber\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"_blockHash\",\"type\":\"bytes32\"}],\"name\":\"Sign\",\"type\":\"event\"}]"
|
||||||
|
|
||||||
// BlockSignerBin is the compiled bytecode used for deploying new contracts.
|
// BlockSignerBin is the compiled bytecode used for deploying new contracts.
|
||||||
const BlockSignerBin = `0x6060604052341561000f57600080fd5b604051602080610386833981016040528080516002555050610350806100366000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610076578063f4145a83146100df575b600080fd5b341561006657600080fd5b610074600435602435610104565b005b341561008157600080fd5b61008c600435610227565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100cb5780820151838201526020016100b3565b505050509050019250505060405180910390f35b34156100ea57600080fd5b6100f26102ac565b60405190815260200160405180910390f35b438290101561011257600080fd5b600280546101289184910263ffffffff6102b216565b43111561013457600080fd5b600082815260016020819052604090912080549091810161015583826102c8565b5060009182526020808320919091018390558282528190526040902080546001810161018183826102c8565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f5490838360405173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091526040808301919091526060909101905180910390a15050565b61022f6102f1565b600082815260208181526040918290208054909290918281020190519081016040528092919081815260200182805480156102a057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610275575b50505050509050919050565b60025481565b6000828201838110156102c157fe5b9392505050565b8154818355818115116102ec576000838152602090206102ec918101908301610303565b505050565b60206040519081016040526000815290565b61032191905b8082111561031d5760008155600101610309565b5090565b905600a165627a7a72305820a8ceddaea8e4ae00991e2ae81c8c88e160dd8770f255523282c24c2df4c30ec70029`
|
const BlockSignerBin = `0x6060604052341561000f57600080fd5b60405160208061034083398101604052808051600255505061030a806100366000396000f3006060604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663e341eaa4811461005b578063e7ec6aef14610076578063f4145a83146100df575b600080fd5b341561006657600080fd5b610074600435602435610104565b005b341561008157600080fd5b61008c6004356101f7565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100cb5780820151838201526020016100b3565b505050509050019250505060405180910390f35b34156100ea57600080fd5b6100f261027c565b60405190815260200160405180910390f35b60008281526001602081905260409091208054909181016101258382610282565b506000918252602080832091909101839055828252819052604090208054600181016101518382610282565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff19163373ffffffffffffffffffffffffffffffffffffffff8116919091179091557f62855fa22e051687c32ac285857751f6d3f2c100c72756d8d30cb7ecb1f64f5490838360405173ffffffffffffffffffffffffffffffffffffffff909316835260208301919091526040808301919091526060909101905180910390a15050565b6101ff6102ab565b6000828152602081815260409182902080549092909182810201905190810160405280929190818152602001828054801561027057602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610245575b50505050509050919050565b60025481565b8154818355818115116102a6576000838152602090206102a69181019083016102bd565b505050565b60206040519081016040526000815290565b6102db91905b808211156102d757600081556001016102c3565b5090565b905600a165627a7a72305820fd1c307716c14d8f8b179bb09b89555ec490e6b216e2c1018c7232361b947bc40029`
|
||||||
|
|
||||||
// DeployBlockSigner deploys a new Ethereum contract, binding an instance of BlockSigner to it.
|
// DeployBlockSigner deploys a new Ethereum contract, binding an instance of BlockSigner to it.
|
||||||
func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend, _epochNumber *big.Int) (common.Address, *types.Transaction, *BlockSigner, error) {
|
func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend, _epochNumber *big.Int) (common.Address, *types.Transaction, *BlockSigner, error) {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package randomize
|
package randomize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package randomize
|
package randomize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package contracts
|
package contracts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -5,6 +20,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
|
@ -16,7 +32,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HexSignMethod = "2fb1b25f"
|
HexSignMethod = "e341eaa4"
|
||||||
RewardMasterPercent = 30
|
RewardMasterPercent = 30
|
||||||
RewardVoterPercent = 60
|
RewardVoterPercent = 60
|
||||||
RewardFoundationPercent = 10
|
RewardFoundationPercent = 10
|
||||||
|
|
@ -43,7 +59,7 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
|
|
||||||
// Create and send tx to smart contract for sign validate block.
|
// Create and send tx to smart contract for sign validate block.
|
||||||
nonce := pool.State().GetNonce(account.Address)
|
nonce := pool.State().GetNonce(account.Address)
|
||||||
tx := CreateTxSign(block.Number(), nonce, common.HexToAddress(common.BlockSigners))
|
tx := CreateTxSign(block.Number(), block.Hash(), nonce, common.HexToAddress(common.BlockSigners))
|
||||||
txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId)
|
txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to create tx sign", "error", err)
|
log.Error("Fail to create tx sign", "error", err)
|
||||||
|
|
@ -58,27 +74,24 @@ func CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, m
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tx sign.
|
// Create tx sign.
|
||||||
func CreateTxSign(blockNumber *big.Int, nonce uint64, blockSigner common.Address) *types.Transaction {
|
func CreateTxSign(blockNumber *big.Int, blockHash common.Hash, nonce uint64, blockSigner common.Address) *types.Transaction {
|
||||||
blockHex := common.LeftPadBytes(blockNumber.Bytes(), 32)
|
|
||||||
data := common.Hex2Bytes(HexSignMethod)
|
data := common.Hex2Bytes(HexSignMethod)
|
||||||
inputData := append(data, blockHex...)
|
inputData := append(data, common.LeftPadBytes(blockNumber.Bytes(), 32)...)
|
||||||
tx := types.NewTransaction(nonce, blockSigner, big.NewInt(0), 100000, big.NewInt(0), inputData)
|
inputData = append(inputData, common.LeftPadBytes(blockHash.Bytes(), 32)...)
|
||||||
|
tx := types.NewTransaction(nonce, blockSigner, big.NewInt(0), 200000, big.NewInt(0), inputData)
|
||||||
|
|
||||||
return tx
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get signers signed for blockNumber from blockSigner contract.
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
func GetSignersFromContract(addrBlockSigner common.Address, client bind.ContractBackend, blockNumber uint64) ([]common.Address, error) {
|
func GetSignersFromContract(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)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
opts := new(bind.CallOpts)
|
opts := new(bind.CallOpts)
|
||||||
// TODO: let move from blockNumber to blockHash
|
addrs, err := blockSigner.GetSigners(opts, blockHash)
|
||||||
// addrs, err := blockSigner.GetSigners(opts, new(big.Int).SetUint64(blockNumber))
|
|
||||||
log.Error("Should replace blockNumber to blockHash", blockNumber)
|
|
||||||
addrs, err := blockSigner.GetSigners(opts, [32]byte{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get block signers", "error", err)
|
log.Error("Fail get block signers", "error", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -88,14 +101,15 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate reward for reward checkpoint.
|
// Calculate reward for reward checkpoint.
|
||||||
func GetRewardForCheckpoint(blockSignerAddr common.Address, number uint64, rCheckpoint uint64, client bind.ContractBackend, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
|
func GetRewardForCheckpoint(chain consensus.ChainReader, blockSignerAddr common.Address, number uint64, rCheckpoint uint64, client bind.ContractBackend, 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.
|
||||||
startBlockNumber := number - (rCheckpoint * 2) + 1
|
startBlockNumber := number - (rCheckpoint * 2) + 1
|
||||||
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
endBlockNumber := startBlockNumber + rCheckpoint - 1
|
||||||
signers := make(map[common.Address]*rewardLog)
|
signers := make(map[common.Address]*rewardLog)
|
||||||
|
|
||||||
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
for i := startBlockNumber; i <= endBlockNumber; i++ {
|
||||||
addrs, err := GetSignersFromContract(blockSignerAddr, client, i)
|
block := chain.GetHeaderByNumber(i)
|
||||||
|
addrs, err := GetSignersFromContract(blockSignerAddr, client, block.Hash())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package contracts
|
package contracts
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
@ -10,10 +25,10 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSendTxSign(t *testing.T) {
|
func TestSendTxSign(t *testing.T) {
|
||||||
|
|
@ -42,41 +57,46 @@ func TestSendTxSign(t *testing.T) {
|
||||||
backend.Commit()
|
backend.Commit()
|
||||||
|
|
||||||
nonces := make(map[*ecdsa.PrivateKey]int)
|
nonces := make(map[*ecdsa.PrivateKey]int)
|
||||||
oldBlock := make([]common.Address, 100)
|
oldBlocks := make(map[common.Hash]common.Address)
|
||||||
|
|
||||||
signTx := func(ctx context.Context, backend *backends.SimulatedBackend, signer types.HomesteadSigner, nonces map[*ecdsa.PrivateKey]int, accKey *ecdsa.PrivateKey, i uint64) {
|
signTx := func(ctx context.Context, backend *backends.SimulatedBackend, signer types.HomesteadSigner, nonces map[*ecdsa.PrivateKey]int, accKey *ecdsa.PrivateKey, blockNumber *big.Int, blockHash common.Hash) *types.Transaction {
|
||||||
tx, _ := types.SignTx(CreateTxSign(new(big.Int).SetUint64(i), uint64(nonces[accKey]), blockSignerAddr), signer, accKey)
|
tx, _ := types.SignTx(CreateTxSign(blockNumber, blockHash, uint64(nonces[accKey]), blockSignerAddr), signer, accKey)
|
||||||
backend.SendTransaction(ctx, tx)
|
backend.SendTransaction(ctx, tx)
|
||||||
backend.Commit()
|
backend.Commit()
|
||||||
nonces[accKey]++
|
nonces[accKey]++
|
||||||
|
|
||||||
|
return tx
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx sign for signer.
|
// Tx sign for signer.
|
||||||
signCount := uint64(0)
|
signCount := int64(0)
|
||||||
for i := uint64(0); i < 100; i++ {
|
blockHashes := make([]common.Hash, 10)
|
||||||
|
for i := int64(0); i < 10; i++ {
|
||||||
|
blockHash := randomHash()
|
||||||
|
blockHashes[i] = blockHash
|
||||||
randIndex := rand.Intn(len(keys))
|
randIndex := rand.Intn(len(keys))
|
||||||
accKey := keys[randIndex]
|
accKey := keys[randIndex]
|
||||||
signTx(ctx, backend, signer, nonces, accKey, i)
|
signTx(ctx, backend, signer, nonces, accKey, new(big.Int).SetInt64(i), blockHash)
|
||||||
oldBlock[i] = accounts[randIndex]
|
oldBlocks[blockHash] = accounts[randIndex]
|
||||||
signCount++
|
signCount++
|
||||||
|
|
||||||
// Tx sign for validators.
|
// Tx sign for validators.
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
if key != accKey {
|
if key != accKey {
|
||||||
signTx(ctx, backend, signer, nonces, key, i)
|
signTx(ctx, backend, signer, nonces, key, new(big.Int).SetInt64(i), blockHash)
|
||||||
signCount++
|
signCount++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := uint64(0); i < 100; i++ {
|
for _, blockHash := range blockHashes {
|
||||||
signers, err := blockSigner.GetSigners(new(big.Int).SetUint64(i))
|
signers, err := blockSigner.GetSigners(blockHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Can't get signers: %v", err)
|
t.Fatalf("Can't get signers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if signers[0].String() != oldBlock[i].String() {
|
if signers[0].String() != oldBlocks[blockHash].String() {
|
||||||
t.Errorf("Tx sign for block signer not match %v - %v", signers[0].String(), oldBlock[i].String())
|
t.Errorf("Tx sign for block signer not match %v - %v", signers[0].String(), oldBlocks[blockHash].String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(signers) != len(keys) {
|
if len(signers) != len(keys) {
|
||||||
|
|
@ -85,33 +105,44 @@ func TestSendTxSign(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unit test for reward checkpoint.
|
// Unit test for reward checkpoint.
|
||||||
rCheckpoint := uint64(5)
|
//rCheckpoint := uint64(5)
|
||||||
chainReward := new(big.Int).SetUint64(15 * params.Ether)
|
//chainReward := new(big.Int).SetUint64(15 * params.Ether)
|
||||||
total := new(uint64)
|
//total := new(uint64)
|
||||||
for i := uint64(0); i < 100; i++ {
|
//for i := uint64(0); i < 100; i++ {
|
||||||
if i > 0 && i%rCheckpoint == 0 && i-rCheckpoint > 0 {
|
// if i > 0 && i%rCheckpoint == 0 && i-rCheckpoint > 0 {
|
||||||
_, err := GetRewardForCheckpoint(blockSignerAddr, i, rCheckpoint, backend, total)
|
// _, err := GetRewardForCheckpoint(blockSignerAddr, i, rCheckpoint, backend, total)
|
||||||
if err != nil {
|
// if err != nil {
|
||||||
t.Errorf("Fail to get signers for reward checkpoint: %v", err)
|
// t.Errorf("Fail to get signers for reward checkpoint: %v", err)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
signers := make(map[common.Address]*rewardLog)
|
//signers := make(map[common.Address]*rewardLog)
|
||||||
totalSigner := uint64(17)
|
//totalSigner := uint64(17)
|
||||||
signers[common.HexToAddress("0x12f588d7d03bb269b382b842fc15d874e8c055a7")] = &rewardLog{5, new(big.Int).SetUint64(0)}
|
//signers[common.HexToAddress("0x12f588d7d03bb269b382b842fc15d874e8c055a7")] = &rewardLog{5, new(big.Int).SetUint64(0)}
|
||||||
signers[common.HexToAddress("0x1f9e122c0921a4504fc116d967baf7a7bf2604ef")] = &rewardLog{6, new(big.Int).SetUint64(0)}
|
//signers[common.HexToAddress("0x1f9e122c0921a4504fc116d967baf7a7bf2604ef")] = &rewardLog{6, new(big.Int).SetUint64(0)}
|
||||||
signers[common.HexToAddress("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)}
|
//signers[common.HexToAddress("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)}
|
||||||
rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner)
|
//rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
t.Errorf("Fail to calculate reward for signers: %v", err)
|
// t.Errorf("Fail to calculate reward for signers: %v", err)
|
||||||
}
|
//}
|
||||||
//t.Error("Reward", rewardSigners)
|
////t.Error("Reward", rewardSigners)
|
||||||
rewards := new(big.Int)
|
//rewards := new(big.Int)
|
||||||
for _, reward := range rewardSigners {
|
//for _, reward := range rewardSigners {
|
||||||
rewards.Add(rewards, reward)
|
// rewards.Add(rewards, reward)
|
||||||
}
|
//}
|
||||||
if rewards.Cmp(new(big.Int).SetUint64(14999999999999999996)) != 0 {
|
//if rewards.Cmp(new(big.Int).SetUint64(14999999999999999996)) != 0 {
|
||||||
t.Errorf("Total reward not same reward checkpoint: %v - %v", chainReward, rewards)
|
// t.Errorf("Total reward not same reward checkpoint: %v - %v", chainReward, rewards)
|
||||||
}
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate random string.
|
||||||
|
func randomHash() common.Hash {
|
||||||
|
letterBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789"
|
||||||
|
var b common.Hash
|
||||||
|
for i := range b {
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
b[i] = letterBytes[rand.Intn(len(letterBytes))]
|
||||||
|
}
|
||||||
|
return b
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright (c) 2018 Tomochain
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program 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 Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package validator
|
package validator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ const (
|
||||||
|
|
||||||
// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
|
// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
|
||||||
BlockChainVersion = 3
|
BlockChainVersion = 3
|
||||||
M1Gap = 3
|
M1Gap = 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// CacheConfig contains the configuration values for the trie caching/pruning
|
// CacheConfig contains the configuration values for the trie caching/pruning
|
||||||
|
|
@ -1243,7 +1243,6 @@ func (st *insertStats) report(chain []*types.Block, index int, cache common.Stor
|
||||||
context = append(context, []interface{}{"ignored", st.ignored}...)
|
context = append(context, []interface{}{"ignored", st.ignored}...)
|
||||||
}
|
}
|
||||||
log.Info("Imported new chain segment", context...)
|
log.Info("Imported new chain segment", context...)
|
||||||
|
|
||||||
*st = insertStats{startTime: now, lastIndex: index + 1}
|
*st = insertStats{startTime: now, lastIndex: index + 1}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
docker_push.sh
Normal file → Executable file
6
docker_push.sh
Normal file → Executable file
|
|
@ -1,7 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
|
echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
|
||||||
docker tag tomochain/tomochain tomochain/tomochain:latest
|
docker tag tomochain/tomochain tomochain/tomochain:$1
|
||||||
docker tag tomochain/tomochain tomochain/tomochain:$TRAVIS_BUILD_ID
|
docker push tomochain/tomochain:$1
|
||||||
docker push tomochain/tomochain:latest
|
|
||||||
docker push tomochain/tomochain:$TRAVIS_BUILD_ID
|
|
||||||
|
|
|
||||||
0
docker_rebuild.sh
Normal file → Executable file
0
docker_rebuild.sh
Normal file → Executable file
|
|
@ -213,10 +213,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
client, err := eth.GetClient()
|
client, err := eth.GetClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to connect IPC client for blockSigner", "error", err)
|
log.Error("Fail to connect IPC client for blockSigner", "error", err)
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
rCheckpoint := chain.Config().Clique.RewardCheckpoint
|
rCheckpoint := chain.Config().Clique.RewardCheckpoint
|
||||||
if number > 0 && number-rCheckpoint > 0 {
|
if number > 0 && number-rCheckpoint > 0 {
|
||||||
|
|
@ -224,7 +221,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
addr := common.HexToAddress(common.BlockSigners)
|
addr := common.HexToAddress(common.BlockSigners)
|
||||||
chainReward := new(big.Int).SetUint64(chain.Config().Clique.Reward * params.Ether)
|
chainReward := new(big.Int).SetUint64(chain.Config().Clique.Reward * params.Ether)
|
||||||
totalSigner := new(uint64)
|
totalSigner := new(uint64)
|
||||||
signers, err := contracts.GetRewardForCheckpoint(addr, number, rCheckpoint, client, totalSigner)
|
signers, err := contracts.GetRewardForCheckpoint(chain, addr, number, rCheckpoint, client, totalSigner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get signers for reward checkpoint", "error", err)
|
log.Error("Fail to get signers for reward checkpoint", "error", err)
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +229,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to calculate reward for signers", "error", err)
|
log.Error("Fail to calculate reward for signers", "error", err)
|
||||||
}
|
}
|
||||||
//// Get validator.
|
// Get validator.
|
||||||
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
|
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of Tomo Validator", "error", err)
|
log.Error("Fail get instance of Tomo Validator", "error", err)
|
||||||
|
|
@ -439,11 +436,7 @@ func (s *Ethereum) UpdateMasternodes(ms []clique.Masternode) error {
|
||||||
return errors.New("not clique")
|
return errors.New("not clique")
|
||||||
}
|
}
|
||||||
c := s.engine.(*clique.Clique)
|
c := s.engine.(*clique.Clique)
|
||||||
err := c.UpdateMasternodes(s.blockchain, s.blockchain.CurrentHeader(), ms)
|
return c.UpdateMasternodes(s.blockchain, s.blockchain.CurrentHeader(), ms)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Ethereum) StartStaking(local bool) error {
|
func (s *Ethereum) StartStaking(local bool) error {
|
||||||
|
|
|
||||||
|
|
@ -315,7 +315,7 @@ func (s *Service) readLoop(conn *websocket.Conn) {
|
||||||
// Make sure the request is valid and doesn't crash us
|
// Make sure the request is valid and doesn't crash us
|
||||||
request, ok := msg["emit"][1].(map[string]interface{})
|
request, ok := msg["emit"][1].(map[string]interface{})
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Warn("Invalid stats history request", "msg", msg["emit"][1])
|
log.Debug("Invalid stats history request", "msg", msg["emit"][1])
|
||||||
s.histCh <- nil
|
s.histCh <- nil
|
||||||
continue // Ethstats sometime sends invalid history requests, ignore those
|
continue // Ethstats sometime sends invalid history requests, ignore those
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ const (
|
||||||
chainHeadChanSize = 10
|
chainHeadChanSize = 10
|
||||||
// chainSideChanSize is the size of channel listening to ChainSideEvent.
|
// chainSideChanSize is the size of channel listening to ChainSideEvent.
|
||||||
chainSideChanSize = 10
|
chainSideChanSize = 10
|
||||||
|
// Timeout waiting for M1
|
||||||
|
m1Timeout = 1
|
||||||
)
|
)
|
||||||
|
|
||||||
// Agent can register themself with the worker
|
// Agent can register themself with the worker
|
||||||
|
|
@ -415,6 +417,24 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func abs(x int64) int64 {
|
||||||
|
if x < 0 {
|
||||||
|
return -x
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func hop(len, pre, cur int) int {
|
||||||
|
switch {
|
||||||
|
case pre < cur:
|
||||||
|
return cur - (pre + 1)
|
||||||
|
case pre > cur:
|
||||||
|
return (len - pre) + (cur - 1)
|
||||||
|
default:
|
||||||
|
return len - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *worker) commitNewWork() {
|
func (self *worker) commitNewWork() {
|
||||||
self.mu.Lock()
|
self.mu.Lock()
|
||||||
defer self.mu.Unlock()
|
defer self.mu.Unlock()
|
||||||
|
|
@ -439,15 +459,35 @@ func (self *worker) commitNewWork() {
|
||||||
log.Error("Failed when trying to commit new work", "err", err)
|
log.Error("Failed when trying to commit new work", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ok, err := clique.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
|
preIndex, curIndex, ok, err := clique.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed when trying to commit new work", "err", err)
|
log.Error("Failed when trying to commit new work", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Info("Not our turn to commit block. Wait for next time")
|
log.Info("Not my turn to commit block. Waiting...")
|
||||||
|
// in case some nodes are down
|
||||||
|
if preIndex == -1 {
|
||||||
|
// first block
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
h := hop(len(masternodes), preIndex, curIndex)
|
||||||
|
gap := int64(c.GetPeriod()) * int64(h)
|
||||||
|
log.Info("Distance from the parent block", "seconds", gap, "hops", h)
|
||||||
|
L:
|
||||||
|
select {
|
||||||
|
case newBlock := <-self.chainHeadCh:
|
||||||
|
if newBlock.Block.NumberU64() > parent.NumberU64() {
|
||||||
|
log.Info("New block has came already. Skip this turn", "new block", newBlock.Block.NumberU64(), "current block", parent.NumberU64())
|
||||||
|
self.chainHeadCh <- newBlock
|
||||||
|
return
|
||||||
|
}
|
||||||
|
case <-time.After(time.Duration(gap+m1Timeout) * time.Second):
|
||||||
|
// wait enough. It's my turn
|
||||||
|
log.Info("Wait enough. It's my turn", "waited seconds", gap+m1Timeout)
|
||||||
|
break L
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VersionMajor = 1 // Major version component of the current release
|
VersionMajor = 0 // Major version component of the current release
|
||||||
VersionMinor = 8 // Minor version component of the current release
|
VersionMinor = 1 // Minor version component of the current release
|
||||||
VersionPatch = 4 // Patch version component of the current release
|
VersionPatch = 0 // Patch version component of the current release
|
||||||
VersionMeta = "unstable" // Version metadata to append to the version string
|
VersionMeta = "unstable" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue