From 59fc2e13e79f6630e86854bfa609c1524722e608 Mon Sep 17 00:00:00 2001 From: Raul Jordan Date: Sat, 21 Jul 2018 12:20:00 -0500 Subject: [PATCH] client: Fix P2P Linter Error (#307) Former-commit-id: 5f673dffed4267c1aca8ebfb4fe182798b9b2d2a [formerly 3fd494231ba5a350ab59a86fcf60ae9f56f1da00] Former-commit-id: 1506dd418121884a8c7a727f8cf03c12e4c93cc3 --- beacon-chain/blockchain/BUILD.bazel | 4 +++ beacon-chain/blockchain/core.go | 37 ++++++++++++++++++++++++++++ beacon-chain/blockchain/core_test.go | 25 +++++++++++++++++++ beacon-chain/params/config.go | 2 +- client/p2p/service_test.go | 8 +++--- contracts/deployVRC/README.md | 29 +++++++++++++--------- 6 files changed, 89 insertions(+), 16 deletions(-) diff --git a/beacon-chain/blockchain/BUILD.bazel b/beacon-chain/blockchain/BUILD.bazel index 6a405d14e..f5f64c8a8 100644 --- a/beacon-chain/blockchain/BUILD.bazel +++ b/beacon-chain/blockchain/BUILD.bazel @@ -10,11 +10,14 @@ go_library( visibility = ["//beacon-chain:__subpackages__"], deps = [ "//beacon-chain/database:go_default_library", + "//beacon-chain/params:go_default_library", "//beacon-chain/types:go_default_library", + "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_ethereum_go_ethereum//ethdb:go_default_library", "@com_github_ethereum_go_ethereum//rlp:go_default_library", "@com_github_sirupsen_logrus//:go_default_library", "@com_github_syndtr_goleveldb//leveldb/errors:go_default_library", + "@org_golang_x_crypto//blake2s:go_default_library", ], ) @@ -27,6 +30,7 @@ go_test( embed = [":go_default_library"], deps = [ "//beacon-chain/database:go_default_library", + "//beacon-chain/params:go_default_library", "//beacon-chain/types:go_default_library", "@com_github_ethereum_go_ethereum//common:go_default_library", "@com_github_sirupsen_logrus//hooks/test:go_default_library", diff --git a/beacon-chain/blockchain/core.go b/beacon-chain/blockchain/core.go index ac6f31f2d..66eb4b5e3 100644 --- a/beacon-chain/blockchain/core.go +++ b/beacon-chain/blockchain/core.go @@ -1,14 +1,18 @@ package blockchain import ( + "errors" "fmt" "sync" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" + "github.com/prysmaticlabs/prysm/beacon-chain/params" "github.com/prysmaticlabs/prysm/beacon-chain/types" log "github.com/sirupsen/logrus" leveldberrors "github.com/syndtr/goleveldb/leveldb/errors" + "golang.org/x/crypto/blake2s" ) var stateLookupKey = "beaconchainstate" @@ -85,3 +89,36 @@ func (b *BeaconChain) persist() error { } return b.db.Put([]byte(stateLookupKey), encodedState) } + +// Shuffle returns a list of pseudorandomly sampled +// indices to use to select attesters and proposers. +func Shuffle(seed common.Hash, validatorCount int) ([]int, error) { + if validatorCount > params.MaxValidators { + return nil, errors.New("Validator count has exceeded MaxValidator Count") + } + + // construct a list of indices up to MaxValidators + validatorList := make([]int, validatorCount) + for i := range validatorList { + validatorList[i] = i + } + + hashSeed, err := blake2s.New256(seed[:]) + if err != nil { + return nil, err + } + + hashSeedByte := hashSeed.Sum(nil) + + // shuffle stops at the second to last index + for i := 0; i < validatorCount-1; i++ { + // convert every 3 bytes to random number, replace validator index with that number + for j := 0; j+3 < len(hashSeedByte); j += 3 { + swapNum := int(hashSeedByte[j] + hashSeedByte[j+1] + hashSeedByte[j+2]) + remaining := validatorCount - i + swapPos := swapNum%remaining + i + validatorList[i], validatorList[swapPos] = validatorList[swapPos], validatorList[i] + } + } + return validatorList, nil +} diff --git a/beacon-chain/blockchain/core_test.go b/beacon-chain/blockchain/core_test.go index 761e887fc..8dbeed8dc 100644 --- a/beacon-chain/blockchain/core_test.go +++ b/beacon-chain/blockchain/core_test.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/prysmaticlabs/prysm/beacon-chain/database" + "github.com/prysmaticlabs/prysm/beacon-chain/params" "github.com/prysmaticlabs/prysm/beacon-chain/types" logTest "github.com/sirupsen/logrus/hooks/test" ) @@ -119,3 +120,27 @@ func TestMutateCrystallizedState(t *testing.T) { t.Errorf("crystallized state current checkpoint incorrect. wanted %v, got %v", crystallized.CurrentCheckpoint.Hex(), newBeaconChain.state.CrystallizedState.CurrentCheckpoint.Hex()) } } + +func TestFaultyShuffle(t *testing.T) { + if _, err := Shuffle(common.Hash{'a'}, params.MaxValidators+1); err == nil { + t.Error("Shuffle should have failed when validator count exceeds MaxValidators") + } +} + +func TestShuffle(t *testing.T) { + hash1 := common.BytesToHash([]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'c', 'd', 'e', 'f', 'g'}) + hash2 := common.BytesToHash([]byte{'1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7'}) + + list1, err := Shuffle(hash1, 100) + if err != nil { + t.Errorf("Shuffle failed with: %v", err) + } + + list2, err := Shuffle(hash2, 100) + if err != nil { + t.Errorf("Shuffle failed with: %v", err) + } + if reflect.DeepEqual(list1, list2) { + t.Errorf("2 shuffled lists shouldn't be equal") + } +} diff --git a/beacon-chain/params/config.go b/beacon-chain/params/config.go index 747b9bb6d..4c0701acb 100644 --- a/beacon-chain/params/config.go +++ b/beacon-chain/params/config.go @@ -14,7 +14,7 @@ const ( // DefaultSwitchDynasty value. DefaultSwitchDynasty = 9999999999999999999 // MaxValidators in the protocol. - MaxValidators = 2 ^ 24 + MaxValidators = 4194304 // NotariesPerCrosslink fixed to 100. NotariesPerCrosslink = 100 ) diff --git a/client/p2p/service_test.go b/client/p2p/service_test.go index e212d47dd..70f6864e7 100644 --- a/client/p2p/service_test.go +++ b/client/p2p/service_test.go @@ -36,16 +36,16 @@ func TestLifecycle(t *testing.T) { } s.Start() - msg := hook.Entries[0] + msg := hook.Entries[0].Message want := "Starting shardp2p server" - if msg == nil || msg.Message != want { + if msg != want { t.Errorf("incorrect log. wanted: %s. got: %v", want, msg) } s.Stop() - msg = hook.LastEntry() + msg = hook.LastEntry().Message want = "Stopping shardp2p server" - if msg == nil || msg.Message != want { + if msg != want { t.Errorf("incorrect log. wanted: %s. got: %v", want, msg) } diff --git a/contracts/deployVRC/README.md b/contracts/deployVRC/README.md index ace3ca881..cd09146f2 100644 --- a/contracts/deployVRC/README.md +++ b/contracts/deployVRC/README.md @@ -11,13 +11,13 @@ This is a utility to help users deploy validator registration contract for runni deployVRC [global options] command [command options] [arguments...] *Flags:* - **--keystoreUTCPath** Keystore UTC file to unlock account (default: "./datadir/keystore/UTC...") - **--ipcPath** Filename for IPC socket/pipe within the datadir (default: "./geth.ipc") - **--httpPath** HTTP-RPC server listening interface (default: "http://localhost:8545/") - **--passwordFile** Password file for unlock account (default: "./password.txt") - **--privKey** Private key to unlock account - **--help, -h** show help - **--version, -v** print the version + **--keystoreUTCPath** Keystore UTC file to unlock account (default: "./datadir/keystore/UTC...") + **--ipcPath** Filename for IPC socket/pipe within the datadir (default: "./geth.ipc") + **--httpPath** HTTP-RPC server listening interface (default: "http://localhost:8545/") + **--passwordFile** Password file for unlock account (default: "./password.txt") + **--privKey** Private key to unlock account + **--help, -h** show help + **--version, -v** print the version ### Example To use private key with default RPC: @@ -27,16 +27,23 @@ bazel run //deployVRC --privKey yourPrivateKey To use UTC JSON with IPC: ``` -bazel run //deployVRC --ipcPath /path/to/your/geth.ipc --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt +bazel run //deployVRC --\ + --ipcPath /path/to/your/geth.ipc \ + --UTCPath /path/to/your/keystore/UTCJSON \ + --passwordFile /path/to/your/password.txt ``` To use UTC JSON with RPC: ``` -bazel run //deployVRC --httpPath http://localhost:8545/ --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt +bazel run //deployVRC --\ + --httpPath http://localhost:8545/ \ + --UTCPath /path/to/your/keystore/UTCJSON \ + --passwordFile /path/to/your/password.txt ``` or ``` -bazel run //deployVRC --UTCPath /path/to/your/keystore/UTCJSON --passwordFile /path/to/your/password.txt - +bazel run //deployVRC --\ + --UTCPath /path/to/your/keystore/UTCJSON \ + --passwordFile /path/to/your/password.txt ``` ### Output