Skip to content

Commit

Permalink
Merge pull request #22 from haloplatform/develop
Browse files Browse the repository at this point in the history
CoinSplit harkfork
  • Loading branch information
quocneo authored Dec 19, 2018
2 parents 28382a8 + 5e51ad3 commit 62f4353
Show file tree
Hide file tree
Showing 48 changed files with 1,973 additions and 292 deletions.
35 changes: 35 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: Bug report
about: Create a report to help us improve

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.1
2.2.0
20 changes: 19 additions & 1 deletion cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"bufio"
"crypto/ecdsa"
"errors"
"fmt"
"io"
Expand All @@ -30,6 +31,7 @@ import (
"time"

"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/dashboard"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/node"
Expand Down Expand Up @@ -144,6 +146,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {

// Set reward value: 38 Halos
params.MasterNodeReward.SetString(params.MasterNodeRewardString, 10)
// Set reward value: 30400 Halos for coin-split hard-fork
params.MasterNodeSplitReward.SetString(params.MasterNodeSplitRewardString, 10)

return stack, cfg
}
Expand Down Expand Up @@ -220,6 +224,20 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth
maxTxsPerAccount := ctx.GlobalInt(utils.MaxTxsPerAccountFlag.Name)
rewardMinutes := ctx.GlobalInt(utils.RaftRewardTimeFlag.Name)

if !ctx.GlobalIsSet(utils.RaftSignKeyFlag.Name) {
utils.Fatalf("Raft requires sign key, option: %q", utils.RaftSignKeyFlag.Name)
}

var (
file = ctx.GlobalString(utils.RaftSignKeyFlag.Name)
key *ecdsa.PrivateKey
err error
)

if key, err = crypto.LoadECDSA(file); err != nil {
utils.Fatalf("Load ping key file, option %q: %v", utils.RaftSignKeyFlag.Name, err)
}

if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
privkey := cfg.Node.NodeKey()
strId := discover.PubkeyID(&privkey.PublicKey).String()
Expand Down Expand Up @@ -257,7 +275,7 @@ func RegisterRaftService(stack *node.Node, ctx *cli.Context, cfg gethConfig, eth

ethereum := <-ethChan

return raft.New(ctx, ethereum.ChainConfig(), myId, raftPort, joinExisting, blockTimeNanos, electionTick, rewardTime, maxTxsPerBlock, maxTxsPerAccount, ethereum, peers, datadir)
return raft.New(ctx, ethereum.ChainConfig(), myId, raftPort, joinExisting, blockTimeNanos, electionTick, rewardTime, key, maxTxsPerBlock, maxTxsPerAccount, ethereum, peers, datadir)
}); err != nil {
utils.Fatalf("Failed to register the Raft service: %v", err)
}
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ var (
utils.MNRewardAddrFlag,
utils.PingKeyFlag,
utils.RaftRewardTimeFlag,
utils.RaftSignKeyFlag,
utils.ClientPubKeyFlag,
}

rpcFlags = []cli.Flag{
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ var AppHelpFlagGroups = []flagGroup{
// utils.LightServFlag,
// utils.LightPeersFlag,
// utils.LightKDFFlag,
utils.ClientPubKeyFlag,
},
},
// {Name: "DEVELOPER CHAIN",
Expand Down Expand Up @@ -155,6 +156,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.RaftPortFlag,
utils.ElectionTickFlag,
utils.RaftRewardTimeFlag,
utils.RaftSignKeyFlag,
},
},
{
Expand Down
41 changes: 37 additions & 4 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -604,12 +604,22 @@ var (
Value: 4,
}

RaftSignKeyFlag = cli.StringFlag{
Name: "raftkey",
Usage: "Private key for signing a block",
}

// Quorum
EnableNodePermissionFlag = cli.BoolFlag{
Name: "permissioned",
Usage: "If enabled, the node will allow only a defined list of nodes to connect",
}

ClientPubKeyFlag = cli.StringFlag{
Name: "pubkey",
Usage: "Public key for block validation, hex string",
}

// Masternode
MNInstanceAddrFlag = cli.StringFlag{
Name: "mn",
Expand Down Expand Up @@ -690,8 +700,7 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
} else {
urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
}
case ctx.GlobalBool(TestnetFlag.Name):
case ctx.GlobalUint64(NetworkIdFlag.Name) == params.HaloTestnetNetworkId:
case ctx.GlobalBool(TestnetFlag.Name) || ctx.GlobalUint64(NetworkIdFlag.Name) == params.HaloTestnetNetworkId:
urls = params.TestnetBootnodes
log.Debug("Testnet bootnode", "boot", urls)
// case ctx.GlobalBool(RinkebyFlag.Name):
Expand Down Expand Up @@ -960,7 +969,13 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
cfg.DiscoveryV5 = false
}
/// NetworkID for filtering P2P messages
cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
cfg.NetworkId = params.HaloMainnetNetworkId
if ctx.GlobalIsSet(NetworkIdFlag.Name) {
cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
}
if ctx.GlobalBool(TestnetFlag.Name) {
cfg.NetworkId = params.HaloTestnetNetworkId
}

if ctx.GlobalBool(RaftModeFlag.Name) {
cfg.PeerType = p2p.NODE_TYPE_RAFT
Expand Down Expand Up @@ -997,7 +1012,7 @@ func setMasternodeConfig(ctx *cli.Context, cfg *mn.Config) {

cfg.InstAddr = common.HexToAddress(inst_addr)
cfg.RewardAddr = common.HexToAddress(reward_addr)
cfg.PingInterVal = 10 // Fixed at 10 minutes
cfg.PingInterVal = 60 // Fixed at 60 minutes

if !ctx.GlobalIsSet(PingKeyFlag.Name) {
Fatalf("PING requires private key, option: %q", PingKeyFlag.Name)
Expand All @@ -1024,6 +1039,24 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) {
setWS(ctx, cfg)
setNodeUserIdent(ctx, cfg)

/// Public key
switch {
// Mainnet
case cfg.P2P.NetworkId == params.HaloMainnetNetworkId:
params.HaloPublicKey = params.HaloMainnetPublicKey
// Testnet
case cfg.P2P.NetworkId == params.HaloTestnetNetworkId:
params.HaloPublicKey = params.HaloTestnetPublicKey
default:
{
// Using the setting from cmd. Otherwise, using the default
if ctx.GlobalIsSet(ClientPubKeyFlag.Name) {
// Validate the hex string in Ethash. Don't do here
params.HaloPublicKey = ctx.GlobalString(ClientPubKeyFlag.Name)
}
}
}

switch {
case ctx.GlobalIsSet(DataDirFlag.Name):
cfg.DataDir = ctx.GlobalString(DataDirFlag.Name)
Expand Down
23 changes: 17 additions & 6 deletions consensus/ethash/algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,25 @@ const (
// reused between hash runs instead of requiring new ones to be created.
type hasher func(dest []byte, data []byte)

// makeHasher creates a repetitive hasher, allowing the same hash data structures
// to be reused between hash runs instead of requiring new ones to be created.
// The returned function is not thread safe!
// makeHasher creates a repetitive hasher, allowing the same hash data structures to
// be reused between hash runs instead of requiring new ones to be created. The returned
// function is not thread safe!
func makeHasher(h hash.Hash) hasher {
// sha3.state supports Read to get the sum, use it to avoid the overhead of Sum.
// Read alters the state but we reset the hash before every operation.
type readerHash interface {
hash.Hash
Read([]byte) (int, error)
}
rh, ok := h.(readerHash)
if !ok {
panic("can't find Read method on hash")
}
outputLen := rh.Size()
return func(dest []byte, data []byte) {
h.Write(data)
h.Sum(dest[:0])
h.Reset()
rh.Reset()
rh.Write(data)
rh.Read(dest[:outputLen])
}
}

Expand Down
68 changes: 58 additions & 10 deletions consensus/ethash/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package ethash

import (
"bytes"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
Expand All @@ -30,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/consensus/misc"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
set "gopkg.in/fatih/set.v0"
)
Expand Down Expand Up @@ -58,6 +60,7 @@ var (
errInvalidDifficulty = errors.New("non-positive difficulty")
errInvalidMixDigest = errors.New("invalid mix digest")
errInvalidPoW = errors.New("invalid proof-of-work")
errInvalidBlockSig = errors.New("invalid block signature")
)

func mustParseRfc3339(str string) time.Time {
Expand All @@ -77,6 +80,15 @@ func (ethash *Ethash) Author(header *types.Header) (common.Address, error) {
// VerifyHeader checks whether a header conforms to the consensus rules of the
// stock Ethereum ethash engine.
func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.Header, seal bool) error {
// Verify block signature in MixHash/MixDigestHash
if chain.Config().IsCoinSplitFork(header.Number) {
// Verify block signature in MixHash/MixDigestHash
res := ValidateSignedHeader(ethash.haloPublicKey, header)
if !res {
return errInvalidBlockSig
}
}

// If we're running a full engine faking, accept any input as valid
if ethash.config.PowMode == ModeFullFake {
return nil
Expand All @@ -98,14 +110,14 @@ func (ethash *Ethash) VerifyHeader(chain consensus.ChainReader, header *types.He
// concurrently. The method returns a quit channel to abort the operations and
// a results channel to retrieve the async verifications.
func (ethash *Ethash) VerifyHeaders(chain consensus.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
// If we're running a full engine faking, accept any input as valid
if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
abort, results := make(chan struct{}), make(chan error, len(headers))
for i := 0; i < len(headers); i++ {
results <- nil
}
return abort, results
}
// // If we're running a full engine faking, accept any input as valid
// if ethash.config.PowMode == ModeFullFake || len(headers) == 0 {
// abort, results := make(chan struct{}), make(chan error, len(headers))
// for i := 0; i < len(headers); i++ {
// results <- nil
// }
// return abort, results
// }

// Spawn as many workers as allowed threads
workers := runtime.GOMAXPROCS(0)
Expand Down Expand Up @@ -231,6 +243,19 @@ func (ethash *Ethash) VerifyUncles(chain consensus.ChainReader, block *types.Blo
// stock Ethereum ethash engine.
// See YP section 4.3.4. "Block Header Validity"
func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
if chain.Config().IsCoinSplitFork(header.Number) {
// Verify block signature in MixHash/MixDigestHash
res := ValidateSignedHeader(ethash.haloPublicKey, header)
if !res {
return errInvalidBlockSig
}
}

// If we're running a full engine faking, accept any input as valid
if ethash.config.PowMode == ModeFullFake {
return nil
}

// Ensure that the header's extra-data section is of a reasonable size
maximumExtraDataSize := params.GetMaximumExtraDataSize(chain.Config().IsQuorum)
if uint64(len(header.Extra)) > maximumExtraDataSize {
Expand Down Expand Up @@ -265,6 +290,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainReader, header, parent *
if header.Time.Cmp(parent.Time) <= 0 {
return errZeroBlockTime
}

// Verify the block's difficulty based in it's timestamp and parent's difficulty
expected := ethash.CalcDifficulty(chain, header.Time.Uint64(), parent)

Expand Down Expand Up @@ -570,7 +596,29 @@ var (
func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header *types.Header, uncles []*types.Header) {
zeroAddr := common.HexToAddress("0x0000000000000000000000000000000000000000")
if bytes.Compare(zeroAddr.Bytes(), header.Coinbase.Bytes()) != 0 {
// Send to address where masternode rewards are accumulated
state.AddBalance(header.Coinbase, params.MasterNodeReward)
if config.IsCoinSplitFork(header.Number) {
// Add reward after coin-split hard-fork
state.AddBalance(header.Coinbase, params.MasterNodeSplitReward)
} else {
// Send to address where masternode rewards are accumulated
state.AddBalance(header.Coinbase, params.MasterNodeReward)
}
}
}

func SignHeader(privateKey *ecdsa.PrivateKey, header *types.Header) ([]byte, error) {
sig, err := crypto.Sign(header.HashForSign().Bytes(), privateKey)
if sig == nil {
return nil, err
}
return sig, nil
}

func ValidateSignedHeader(publicKey []byte, header *types.Header) (result bool) {
if len(header.Extra) != 65 {
/// Invalid length
return false
}
res := crypto.VerifySignature(publicKey, header.HashForSign().Bytes(), header.Extra[:64])
return res
}
Loading

0 comments on commit 62f4353

Please sign in to comment.