Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add keccak mining #369

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/devp2p/nodesetcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ func ethFilter(args []string) (nodeFilter, error) {
filter = forkid.NewStaticFilter(params.KottiChainConfig, params.KottiGenesisHash)
case "mordor":
filter = forkid.NewStaticFilter(params.MordorChainConfig, params.MordorGenesisHash)
case "astor":
filter = forkid.NewStaticFilter(params.AstorChainConfig, params.AstorGenesisHash)
case "mintme":
filter = forkid.NewStaticFilter(params.MintMeChainConfig, params.MintMeGenesisHash)
default:
Expand Down
1 change: 1 addition & 0 deletions cmd/echainspec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ var defaultChainspecValues = map[string]ctypes.Configurator{
"classic": params.DefaultClassicGenesisBlock(),
"kotti": params.DefaultKottiGenesisBlock(),
"mordor": params.DefaultMordorGenesisBlock(),
"astor": params.DefaultAstorGenesisBlock(),

"foundation": params.DefaultGenesisBlock(),
"ropsten": params.DefaultRopstenGenesisBlock(),
Expand Down
4 changes: 4 additions & 0 deletions cmd/faucet/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ var (
foundationFlag = flag.Bool("chain.foundation", false, "Configure genesis and bootnodes for foundation chain defaults")
classicFlag = flag.Bool("chain.classic", false, "Configure genesis and bootnodes for classic chain defaults")
mordorFlag = flag.Bool("chain.mordor", false, "Configure genesis and bootnodes for mordor chain defaults")
astorFlag = flag.Bool("chain.astor", false, "Configure genesis and bootnodes for astor chain defaults")
kottiFlag = flag.Bool("chain.kotti", false, "Configure genesis and bootnodes for kotti chain defaults")
testnetFlag = flag.Bool("chain.testnet", false, "Configure genesis and bootnodes for testnet chain defaults")
rinkebyFlag = flag.Bool("chain.rinkeby", false, "Configure genesis and bootnodes for rinkeby chain defaults")
Expand Down Expand Up @@ -146,6 +147,8 @@ func faucetDirFromChainIndicators(chainID uint64, genesisHash common.Hash) strin
return filepath.Join(datadir, "kotti")
case params.MordorGenesisHash:
return filepath.Join(datadir, "mordor")
case params.AstorGenesisHash:
return filepath.Join(datadir, "astor")
}
return datadir
}
Expand All @@ -159,6 +162,7 @@ func parseChainFlags() (gs *genesisT.Genesis, bs string, netid uint64) {
{*foundationFlag, params.DefaultGenesisBlock(), nil},
{*classicFlag, params.DefaultClassicGenesisBlock(), nil},
{*mordorFlag, params.DefaultMordorGenesisBlock(), nil},
{*astorFlag, params.DefaultAstorGenesisBlock(), nil},
{*testnetFlag, params.DefaultRopstenGenesisBlock(), nil},
{*rinkebyFlag, params.DefaultRinkebyGenesisBlock(), nil},
{*kottiFlag, params.DefaultKottiGenesisBlock(), nil},
Expand Down
2 changes: 2 additions & 0 deletions cmd/geth/consolecmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ func remoteConsole(ctx *cli.Context) error {
path = filepath.Join(path, "classic")
} else if ctx.GlobalBool(utils.MordorFlag.Name) {
path = filepath.Join(path, "mordor")
} else if ctx.GlobalBool(utils.AstorFlag.Name) {
path = filepath.Join(path, "astor")
} else if ctx.GlobalBool(utils.GoerliFlag.Name) {
path = filepath.Join(path, "goerli")
} else if ctx.GlobalBool(utils.YoloV3Flag.Name) {
Expand Down
3 changes: 2 additions & 1 deletion cmd/geth/consolecmd_cg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ func TestConsoleCmdNetworkIdentities(t *testing.T) {
{[]string{"--kotti"}, 6, 6, params.KottiGenesisHash.Hex()},
{[]string{"--mordor"}, 7, 63, params.MordorGenesisHash.Hex()},
{[]string{"--yolov3"}, int(params.YoloV3ChainConfig.ChainID.Uint64()), int(params.YoloV3ChainConfig.ChainID.Uint64()), params.YoloV3GenesisHash.Hex()},
{[]string{"--astor"}, 212, 212, params.AstorGenesisHash.Hex()},
{[]string{"--mintme"}, 37480, 24734, params.MintMeGenesisHash.Hex()},
}
}
for i, p := range chainIdentityCases {

// Disable networking, preventing false-negatives if in an environment without networking service
Expand Down
4 changes: 4 additions & 0 deletions cmd/geth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ var (
utils.MintMeFlag,
utils.ClassicFlag,
utils.MordorFlag,
utils.AstorFlag,
utils.KottiFlag,
utils.VMEnableDebugFlag,
utils.NetworkIdFlag,
Expand Down Expand Up @@ -300,6 +301,9 @@ func checkMainnet(ctx *cli.Context) bool {
case ctx.GlobalIsSet(utils.MordorFlag.Name):
log.Info("Starting Geth on Mordor testnet...")

case ctx.GlobalIsSet(utils.AstorFlag.Name):
log.Info("Starting Geth on Astor testnet...")

case ctx.GlobalIsSet(utils.KottiFlag.Name):
log.Info("Starting Geth on Kotti testnet...")

Expand Down
1 change: 1 addition & 0 deletions cmd/geth/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
utils.MainnetFlag,
utils.ClassicFlag,
utils.MordorFlag,
utils.AstorFlag,
utils.KottiFlag,
utils.GoerliFlag,
utils.RinkebyFlag,
Expand Down
14 changes: 13 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ var (
Name: "mordor",
Usage: "Mordor network: Ethereum Classic's cross-client proof-of-work test network",
}
AstorFlag = cli.BoolFlag{
Name: "astor",
Usage: "Astor network: Ethereum Classic's cross-client Keccak mining test network",
}
GoerliFlag = cli.BoolFlag{
Name: "goerli",
Usage: "Görli network: pre-configured proof-of-authority test network",
Expand Down Expand Up @@ -876,6 +880,8 @@ func setBootstrapNodes(ctx *cli.Context, cfg *p2p.Config) {
urls = params.ClassicBootnodes
case ctx.GlobalBool(MordorFlag.Name):
urls = params.MordorBootnodes
case ctx.GlobalBool(AstorFlag.Name):
urls = params.AstorBootnodes
case ctx.GlobalBool(RopstenFlag.Name):
urls = params.RopstenBootnodes
case ctx.GlobalBool(RinkebyFlag.Name):
Expand Down Expand Up @@ -916,6 +922,8 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
urls = params.ClassicBootnodes
case ctx.GlobalIsSet(MordorFlag.Name):
urls = params.MordorBootnodes
case ctx.GlobalIsSet(AstorFlag.Name):
urls = params.AstorBootnodes
case ctx.GlobalBool(RopstenFlag.Name):
urls = params.RopstenBootnodes
case ctx.GlobalBool(RinkebyFlag.Name):
Expand Down Expand Up @@ -1330,6 +1338,8 @@ func dataDirPathForCtxChainConfig(ctx *cli.Context, baseDataDirPath string) stri
return filepath.Join(baseDataDirPath, "classic")
case ctx.GlobalBool(MordorFlag.Name):
return filepath.Join(baseDataDirPath, "mordor")
case ctx.GlobalBool(AstorFlag.Name):
return filepath.Join(baseDataDirPath, "astor")
case ctx.GlobalBool(RinkebyFlag.Name):
return filepath.Join(baseDataDirPath, "rinkeby")
case ctx.GlobalBool(KottiFlag.Name):
Expand Down Expand Up @@ -1588,7 +1598,7 @@ func CheckExclusive(ctx *cli.Context, args ...interface{}) {
// SetEthConfig applies eth-related command line flags to the config.
func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
// Avoid conflicting network flags
CheckExclusive(ctx, DeveloperFlag, DeveloperPoWFlag, MainnetFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV3Flag, ClassicFlag, KottiFlag, MordorFlag, MintMeFlag)
CheckExclusive(ctx, DeveloperFlag, DeveloperPoWFlag, MainnetFlag, RopstenFlag, RinkebyFlag, GoerliFlag, YoloV3Flag, ClassicFlag, KottiFlag, MordorFlag, AstorFlag, MintMeFlag)
CheckExclusive(ctx, LightServeFlag, SyncModeFlag, "light")
CheckExclusive(ctx, DeveloperFlag, DeveloperPoWFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer
CheckExclusive(ctx, GCModeFlag, "archive", TxLookupLimitFlag)
Expand Down Expand Up @@ -2020,6 +2030,8 @@ func genesisForCtxChainConfig(ctx *cli.Context) *genesisT.Genesis {
genesis = params.DefaultClassicGenesisBlock()
case ctx.GlobalBool(MordorFlag.Name):
genesis = params.DefaultMordorGenesisBlock()
case ctx.GlobalBool(AstorFlag.Name):
genesis = params.DefaultAstorGenesisBlock()
case ctx.GlobalBool(RopstenFlag.Name):
genesis = params.DefaultRopstenGenesisBlock()
case ctx.GlobalBool(RinkebyFlag.Name):
Expand Down
108 changes: 108 additions & 0 deletions consensus/keccak/algorithm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library 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.
//
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package keccak

import (
"encoding/binary"
"hash"

"github.com/ethereum/go-ethereum/crypto"
"golang.org/x/crypto/sha3"
)

const (
epochLengthDefault = 30000 // Default epoch length (blocks per epoch)
epochLengthECIP1099 = 60000 // Blocks per epoch if ECIP-1099 is activated
)

// calcEpochLength returns the epoch length for a given block number (ECIP-1099)
func calcEpochLength(block uint64, ecip1099FBlock *uint64) uint64 {
if ecip1099FBlock != nil {
if block >= *ecip1099FBlock {
return epochLengthECIP1099
}
}
return epochLengthDefault
}

// calcEpoch returns the epoch for a given block number (ECIP-1099)
func calcEpoch(block uint64, epochLength uint64) uint64 {
epoch := block / epochLength
return epoch
}

// calcEpochBlock returns the epoch start block for a given epoch (ECIP-1099)
func calcEpochBlock(epoch uint64, epochLength uint64) uint64 {
return epoch*epochLength + 1
}

// hasher is a repetitive hasher allowing the same hash data structures to be
// 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!
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) {
rh.Reset()
rh.Write(data)
rh.Read(dest[:outputLen])
}
}

// seedHash is the seed to use for generating a verification cache and the mining
// dataset. The block number passed should be pre-rounded to an epoch boundary + 1
// e.g: seedHash(calcEpochBlock(epoch, epochLength))
func seedHash(epoch uint64, epochLength uint64) []byte {
block := calcEpochBlock(epoch, epochLength)

seed := make([]byte, 32)
if block < epochLengthDefault {
return seed
}

keccak256 := makeHasher(sha3.NewLegacyKeccak256())
for i := 0; i < int(block/epochLengthDefault); i++ {
keccak256(seed, seed)
}
return seed
}

// keccakHasher produces a hash from combining the hash of the block header contents
// combined with a nonce.
func keccakHasher(hash []byte, nonce uint64) ([]byte, []byte) {

// Combine hash+nonce into a 64 byte seed
seed := make([]byte, 40)
copy(seed, hash)
binary.BigEndian.PutUint64(seed[32:], nonce)

solution := crypto.Keccak256(seed)
return solution, solution
}
43 changes: 43 additions & 0 deletions consensus/keccak/algorithm_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library 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.
//
// The go-ethereum library 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 the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package keccak

import (
"bytes"
"testing"

"github.com/ethereum/go-ethereum/common/hexutil"
)

// Unit test for keccakHasher function.
func TestKeccakHasher(t *testing.T) {

// Create a block to verify
hash := hexutil.MustDecode("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef")
nonce := uint64(12345678)

wantDigest := hexutil.MustDecode("0xeffd292d6666dba4d6a4c221dd6d4b34b4ec3972a4cb0d944a8a8936cceca713")
wantResult := hexutil.MustDecode("0xeffd292d6666dba4d6a4c221dd6d4b34b4ec3972a4cb0d944a8a8936cceca713")

digest, result := keccakHasher(hash, nonce)
if !bytes.Equal(digest, wantDigest) {
t.Errorf("keccak digest mismatch: have %x, want %x", digest, wantDigest)
}
if !bytes.Equal(result, wantResult) {
t.Errorf("keccak result mismatch: have %x, want %x", result, wantResult)
}
}
Loading