merge upstream

This commit is contained in:
Nguyen Sy Thanh Son 2018-07-27 08:15:21 +00:00
commit 2cfae3e48a
26 changed files with 357 additions and 145 deletions

View file

@ -2,10 +2,10 @@ sudo: required
language: go
go_import_path: github.com/ethereum/go-ethereum
services: skip
before_install: skip
jobs:
include:
- stage: Lint
os: linux
sudo: false
@ -15,6 +15,7 @@ jobs:
submodules: false
script:
- go run build/ci.go lint
- stage: Build and test
os: linux
dist: trusty
@ -38,28 +39,59 @@ jobs:
- while sleep 540; do echo "[ still running ]"; done &
- go run build/ci.go test -coverage
- 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:
- docker
before_install:
- docker build -t tomochain/tomochain .
- docker run tomochain/tomochain
install: skip
script: skip
deploy:
provider: script
script: bash docker_push.sh
- provider: script
script:
- bash docker_push.sh latest
- bash docker_push.sh $TRAVIS_BUILD_ID
on:
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
install: skip
script: bash docker_rebuild.sh
stages:
- name: Lint
- name: Build and test
- name: Build and push Docker image
if: type != pull_request AND branch = master
- name: Trigger rebuild of infrastructure image
if: type != pull_request AND branch = master
- name: Github release
if: type != pull_request AND branch = master AND tag = true AND repo = tomochain/tomochain
- name: Build and push tomochain/tomochain image
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:
slack:

View file

@ -18,4 +18,6 @@ RUN chmod +x /usr/local/bin/tomo
EXPOSE 8545
EXPOSE 30303
ENTRYPOINT ["/usr/local/bin/tomo", "--help"]
ENTRYPOINT ["/usr/local/bin/tomo"]
CMD ["--help"]

22
Dockerfile.bootnode Normal file
View 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"]

View file

@ -21,6 +21,11 @@ tomo:
@echo "Done building."
@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:
build/env.sh go run build/ci.go install ./cmd/swarm
@echo "Done building."

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

@ -115,7 +115,8 @@ func (w *wizard) makeGenesis() {
fmt.Println()
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":
genesis.Difficulty = big.NewInt(1)

View file

@ -14,7 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
// tomo is the official command-line client for Ethereum.
package main
import (
@ -51,7 +50,7 @@ var (
// Git SHA1 commit hash of the release (set via linker flags)
gitCommit = ""
// 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
nodeFlags = []cli.Flag{
utils.IdentityFlag,
@ -151,7 +150,7 @@ func init() {
// Initialize the CLI app and start tomo
app.Action = tomo
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{
// See chaincmd.go:
initCommand,

View file

@ -33,7 +33,7 @@ import (
var AppHelpTemplate = `NAME:
{{.App.Name}} - {{.App.Usage}}
Copyright 2013-2017 The go-ethereum Authors
Copyright (c) 2018 Tomochain
USAGE:
{{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}

View file

@ -48,7 +48,6 @@ const (
inmemorySnapshots = 128 // Number of recent vote snapshots 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
)
type Masternode struct {
@ -405,7 +404,9 @@ func (c *Clique) GetMasternodes(chain consensus.ChainReader, header *types.Heade
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{}
// masternode[0] has chance to create block 1
var err error
@ -413,16 +414,19 @@ func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header
if header.Number.Uint64() != 0 {
pre, err = ecrecover(header, snap.sigcache)
if err != nil {
return false, err
return 0, 0, false, err
}
preIndex = position(masternodes, pre)
}
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 {
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.

View file

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

View file

@ -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
import (
@ -11,6 +26,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
"math/rand"
)
var (
@ -39,7 +55,16 @@ func TestBlockSigner(t *testing.T) {
}
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)
if err != nil {
t.Fatalf("can't get candidates: %v", err)
@ -47,11 +72,15 @@ func TestBlockSigner(t *testing.T) {
for _, it := range signers {
t.Log("signer", it.String())
}
}
s, err := blockSigner.Sign(big.NewInt(1), byte0)
if err != nil {
t.Fatalf("can't sign: %v", err)
// 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))]
}
t.Log("tx data", s)
contractBackend.Commit()
return b
}

View file

@ -17,8 +17,8 @@ contract BlockSigner {
function sign(uint256 _blockNumber, bytes32 _blockHash) external {
// consensus should validate all senders are validators, gas = 0
require(block.number >= _blockNumber);
require(block.number <= _blockNumber.add(epochNumber * 2));
//require(block.number >= _blockNumber);
//require(block.number <= _blockNumber.add(epochNumber * 2));
blocks[_blockNumber].push(_blockHash);
blockSigners[_blockHash].push(msg.sender);

View file

@ -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\"}]"
// 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.
func DeployBlockSigner(auth *bind.TransactOpts, backend bind.ContractBackend, _epochNumber *big.Int) (common.Address, *types.Transaction, *BlockSigner, error) {

View file

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

View file

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

View file

@ -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
import (
@ -5,6 +20,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
"github.com/ethereum/go-ethereum/core"
@ -16,7 +32,7 @@ import (
)
const (
HexSignMethod = "2fb1b25f"
HexSignMethod = "e341eaa4"
RewardMasterPercent = 30
RewardVoterPercent = 60
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.
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)
if err != nil {
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.
func CreateTxSign(blockNumber *big.Int, nonce uint64, blockSigner common.Address) *types.Transaction {
blockHex := common.LeftPadBytes(blockNumber.Bytes(), 32)
func CreateTxSign(blockNumber *big.Int, blockHash common.Hash, nonce uint64, blockSigner common.Address) *types.Transaction {
data := common.Hex2Bytes(HexSignMethod)
inputData := append(data, blockHex...)
tx := types.NewTransaction(nonce, blockSigner, big.NewInt(0), 100000, big.NewInt(0), inputData)
inputData := append(data, common.LeftPadBytes(blockNumber.Bytes(), 32)...)
inputData = append(inputData, common.LeftPadBytes(blockHash.Bytes(), 32)...)
tx := types.NewTransaction(nonce, blockSigner, big.NewInt(0), 200000, big.NewInt(0), inputData)
return tx
}
// 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)
if err != nil {
log.Error("Fail get instance of blockSigner", "error", err)
return nil, err
}
opts := new(bind.CallOpts)
// TODO: let move from blockNumber to 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{})
addrs, err := blockSigner.GetSigners(opts, blockHash)
if err != nil {
log.Error("Fail get block signers", "error", err)
return nil, err
@ -88,14 +101,15 @@ func GetSignersFromContract(addrBlockSigner common.Address, client bind.Contract
}
// 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.
startBlockNumber := number - (rCheckpoint * 2) + 1
endBlockNumber := startBlockNumber + rCheckpoint - 1
signers := make(map[common.Address]*rewardLog)
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 {
log.Error("Fail to get signers from smartcontract.", "error", err, "blockNumber", i)
return nil, err

View file

@ -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
import (
@ -10,10 +25,10 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"math/big"
"math/rand"
"testing"
"time"
)
func TestSendTxSign(t *testing.T) {
@ -42,41 +57,46 @@ func TestSendTxSign(t *testing.T) {
backend.Commit()
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) {
tx, _ := types.SignTx(CreateTxSign(new(big.Int).SetUint64(i), uint64(nonces[accKey]), blockSignerAddr), signer, accKey)
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(blockNumber, blockHash, uint64(nonces[accKey]), blockSignerAddr), signer, accKey)
backend.SendTransaction(ctx, tx)
backend.Commit()
nonces[accKey]++
return tx
}
// Tx sign for signer.
signCount := uint64(0)
for i := uint64(0); i < 100; i++ {
signCount := int64(0)
blockHashes := make([]common.Hash, 10)
for i := int64(0); i < 10; i++ {
blockHash := randomHash()
blockHashes[i] = blockHash
randIndex := rand.Intn(len(keys))
accKey := keys[randIndex]
signTx(ctx, backend, signer, nonces, accKey, i)
oldBlock[i] = accounts[randIndex]
signTx(ctx, backend, signer, nonces, accKey, new(big.Int).SetInt64(i), blockHash)
oldBlocks[blockHash] = accounts[randIndex]
signCount++
// Tx sign for validators.
for _, key := range keys {
if key != accKey {
signTx(ctx, backend, signer, nonces, key, i)
signTx(ctx, backend, signer, nonces, key, new(big.Int).SetInt64(i), blockHash)
signCount++
}
}
}
for i := uint64(0); i < 100; i++ {
signers, err := blockSigner.GetSigners(new(big.Int).SetUint64(i))
for _, blockHash := range blockHashes {
signers, err := blockSigner.GetSigners(blockHash)
if err != nil {
t.Fatalf("Can't get signers: %v", err)
}
if signers[0].String() != oldBlock[i].String() {
t.Errorf("Tx sign for block signer not match %v - %v", 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(), oldBlocks[blockHash].String())
}
if len(signers) != len(keys) {
@ -85,33 +105,44 @@ func TestSendTxSign(t *testing.T) {
}
// Unit test for reward checkpoint.
rCheckpoint := uint64(5)
chainReward := new(big.Int).SetUint64(15 * params.Ether)
total := new(uint64)
for i := uint64(0); i < 100; i++ {
if i > 0 && i%rCheckpoint == 0 && i-rCheckpoint > 0 {
_, err := GetRewardForCheckpoint(blockSignerAddr, i, rCheckpoint, backend, total)
if err != nil {
t.Errorf("Fail to get signers for reward checkpoint: %v", err)
}
}
//rCheckpoint := uint64(5)
//chainReward := new(big.Int).SetUint64(15 * params.Ether)
//total := new(uint64)
//for i := uint64(0); i < 100; i++ {
// if i > 0 && i%rCheckpoint == 0 && i-rCheckpoint > 0 {
// _, err := GetRewardForCheckpoint(blockSignerAddr, i, rCheckpoint, backend, total)
// if err != nil {
// t.Errorf("Fail to get signers for reward checkpoint: %v", err)
// }
// }
//}
//
//signers := make(map[common.Address]*rewardLog)
//totalSigner := uint64(17)
//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("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)}
//rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner)
//if err != nil {
// t.Errorf("Fail to calculate reward for signers: %v", err)
//}
////t.Error("Reward", rewardSigners)
//rewards := new(big.Int)
//for _, reward := range rewardSigners {
// rewards.Add(rewards, reward)
//}
//if rewards.Cmp(new(big.Int).SetUint64(14999999999999999996)) != 0 {
// t.Errorf("Total reward not same reward checkpoint: %v - %v", chainReward, rewards)
//}
}
signers := make(map[common.Address]*rewardLog)
totalSigner := uint64(17)
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("0xea489e4e673c25ff0614617ebe88efd853efe00c")] = &rewardLog{6, new(big.Int).SetUint64(0)}
rewardSigners, err := CalculateRewardForSigner(chainReward, signers, totalSigner)
if err != nil {
t.Errorf("Fail to calculate reward for signers: %v", err)
}
//t.Error("Reward", rewardSigners)
rewards := new(big.Int)
for _, reward := range rewardSigners {
rewards.Add(rewards, reward)
}
if rewards.Cmp(new(big.Int).SetUint64(14999999999999999996)) != 0 {
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
}

View file

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

View file

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

View file

@ -62,7 +62,7 @@ const (
// BlockChainVersion ensures that an incompatible database forces a resync from scratch.
BlockChainVersion = 3
M1Gap = 3
M1Gap = 5
)
// 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}...)
}
log.Info("Imported new chain segment", context...)
*st = insertStats{startTime: now, lastIndex: index + 1}
}
}

6
docker_push.sh Normal file → Executable file
View file

@ -1,7 +1,5 @@
#!/bin/bash
echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_USERNAME" --password-stdin
docker tag tomochain/tomochain tomochain/tomochain:latest
docker tag tomochain/tomochain tomochain/tomochain:$TRAVIS_BUILD_ID
docker push tomochain/tomochain:latest
docker push tomochain/tomochain:$TRAVIS_BUILD_ID
docker tag tomochain/tomochain tomochain/tomochain:$1
docker push tomochain/tomochain:$1

0
docker_rebuild.sh Normal file → Executable file
View file

View file

@ -213,10 +213,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
client, err := eth.GetClient()
if err != nil {
log.Error("Fail to connect IPC client for blockSigner", "error", err)
return err
}
number := header.Number.Uint64()
rCheckpoint := chain.Config().Clique.RewardCheckpoint
if number > 0 && number-rCheckpoint > 0 {
@ -224,7 +221,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
addr := common.HexToAddress(common.BlockSigners)
chainReward := new(big.Int).SetUint64(chain.Config().Clique.Reward * params.Ether)
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 {
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 {
log.Error("Fail to calculate reward for signers", "error", err)
}
//// Get validator.
// Get validator.
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
if err != nil {
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")
}
c := s.engine.(*clique.Clique)
err := c.UpdateMasternodes(s.blockchain, s.blockchain.CurrentHeader(), ms)
if err != nil {
return err
}
return nil
return c.UpdateMasternodes(s.blockchain, s.blockchain.CurrentHeader(), ms)
}
func (s *Ethereum) StartStaking(local bool) error {

View file

@ -315,7 +315,7 @@ func (s *Service) readLoop(conn *websocket.Conn) {
// Make sure the request is valid and doesn't crash us
request, ok := msg["emit"][1].(map[string]interface{})
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
continue // Ethstats sometime sends invalid history requests, ignore those
}

View file

@ -51,6 +51,8 @@ const (
chainHeadChanSize = 10
// chainSideChanSize is the size of channel listening to ChainSideEvent.
chainSideChanSize = 10
// Timeout waiting for M1
m1Timeout = 1
)
// Agent can register themself with the worker
@ -415,6 +417,24 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error
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() {
self.mu.Lock()
defer self.mu.Unlock()
@ -439,15 +459,35 @@ func (self *worker) commitNewWork() {
log.Error("Failed when trying to commit new work", "err", err)
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 {
log.Error("Failed when trying to commit new work", "err", err)
return
}
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
}
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
}
}
}
}

View file

@ -21,9 +21,9 @@ import (
)
const (
VersionMajor = 1 // Major version component of the current release
VersionMinor = 8 // Minor version component of the current release
VersionPatch = 4 // Patch version component of the current release
VersionMajor = 0 // Major version component of the current release
VersionMinor = 1 // Minor 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
)