[project] Remove over complicated packages, useless tests, dead functions (#2780)

* [project] Dead test

* [node] If fields always same, then just use the constant

* [project] Remove overcomplicated ctxerror

* [project] Remove more dead tests, adjust error replacing ctxerror

* [project] More dead tests, fix travis complaint on Errorf

* [node.sh] Remove is-genesis
pull/2784/head
Edgar Aroutiounian 5 years ago committed by GitHub
parent 7178eabbf1
commit 2836f0f620
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      api/service/syncing/syncing.go
  2. 39
      consensus/consensus_service.go
  3. 10
      consensus/consensus_v2.go
  4. 6
      consensus/construct_test.go
  5. 28
      core/block_validator.go
  6. 56
      core/blockchain.go
  7. 159
      core/rawdb/accessors_chain_test.go
  8. 36
      core/rawdb/accessors_offchain.go
  9. 2
      core/rawdb/interfaces.go
  10. 137
      core/rawdb/mock/mock.go
  11. 91
      core/staking_verifier_test.go
  12. 34
      core/state_processor.go
  13. 10
      core/types/cx_receipt.go
  14. 13
      crypto/bls/bls.go
  15. 35
      gomock_matchers/path.go
  16. 51
      gomock_matchers/path_test.go
  17. 39
      gomock_matchers/slice.go
  18. 114
      gomock_matchers/slice_test.go
  19. 53
      gomock_matchers/struct.go
  20. 113
      gomock_matchers/struct_test.go
  21. 12
      gomock_matchers/util.go
  22. 110
      internal/chain/engine.go
  23. 33
      internal/chain/reward.go
  24. 81
      internal/configs/node/config_test.go
  25. 41
      internal/configs/sharding/instance.go
  26. 341
      internal/configs/sharding/mock/shardingconfig.go
  27. 2
      internal/configs/sharding/shardingconfig.go
  28. 163
      internal/ctxerror/ctxerror.go
  29. 363
      internal/ctxerror/ctxerror_test.go
  30. 125
      internal/ctxerror/mock/ctxerror.go
  31. 14
      internal/shardchain/shardchains.go
  32. 89
      internal/utils/logging_test.go
  33. 49
      internal/utils/mock/testing.go
  34. 48
      internal/utils/mock_log/handler.go
  35. 180
      internal/utils/mock_log/logger.go
  36. 69
      internal/utils/testing.go
  37. 106
      internal/utils/testing_test.go
  38. 17
      node/node.go
  39. 54
      node/node_cross_link.go
  40. 35
      node/node_cross_shard.go
  41. 37
      node/node_handler.go
  42. 4
      node/node_syncing.go
  43. 5
      node/worker/worker.go
  44. 6
      numeric/decimal_test.go
  45. 2
      p2p/host.go
  46. 2
      p2p/host/hostv2/hostv2.go
  47. 152
      p2p/host/hostv2/hostv2_mock_for_test.go
  48. 299
      p2p/host/hostv2/hostv2_test.go
  49. 162
      p2p/host/mock/host_mock.go
  50. 92
      p2p/mock_stream.go
  51. 2
      p2p/stream.go
  52. 1
      scripts/node.sh
  53. 9
      shard/shard_state.go
  54. 33
      staking/availability/measure.go
  55. 26
      staking/types/validator.go
  56. 54
      staking/types/validator_test.go

@ -10,20 +10,19 @@ import (
"sync" "sync"
"time" "time"
"github.com/harmony-one/harmony/consensus/engine"
"github.com/Workiva/go-datastructures/queue" "github.com/Workiva/go-datastructures/queue"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/api/service/syncing/downloader" "github.com/harmony-one/harmony/api/service/syncing/downloader"
pb "github.com/harmony-one/harmony/api/service/syncing/downloader/proto" pb "github.com/harmony-one/harmony/api/service/syncing/downloader/proto"
"github.com/harmony-one/harmony/consensus" "github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/node/worker" "github.com/harmony-one/harmony/node/worker"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/pkg/errors"
) )
// Constants for syncing. // Constants for syncing.
@ -232,7 +231,7 @@ func (ss *StateSync) CreateSyncConfig(peers []p2p.Peer, isBeacon bool) error {
Msg("[SYNC] CreateSyncConfig: len of peers") Msg("[SYNC] CreateSyncConfig: len of peers")
if len(peers) == 0 { if len(peers) == 0 {
return ctxerror.New("[SYNC] no peers to connect to") return errors.New("[SYNC] no peers to connect to")
} }
if ss.syncConfig != nil { if ss.syncConfig != nil {
ss.syncConfig.CloseConnections() ss.syncConfig.CloseConnections()

@ -15,7 +15,6 @@ import (
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/internal/chain" "github.com/harmony-one/harmony/internal/chain"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
@ -367,50 +366,46 @@ func (consensus *Consensus) getLogger() *zerolog.Logger {
} }
// retrieve corresponding blsPublicKey from Coinbase Address // retrieve corresponding blsPublicKey from Coinbase Address
func (consensus *Consensus) getLeaderPubKeyFromCoinbase(header *block.Header) (*bls.PublicKey, error) { func (consensus *Consensus) getLeaderPubKeyFromCoinbase(
header *block.Header,
) (*bls.PublicKey, error) {
shardState, err := consensus.ChainReader.ReadShardState(header.Epoch()) shardState, err := consensus.ChainReader.ReadShardState(header.Epoch())
if err != nil { if err != nil {
return nil, ctxerror.New("cannot read shard state", return nil, errors.Wrapf(err, "cannot read shard state %v %s",
"epoch", header.Epoch(), header.Epoch(),
"coinbaseAddr", header.Coinbase(), header.Coinbase().Hash().Hex(),
).WithCause(err) )
} }
committee, err := shardState.FindCommitteeByID(header.ShardID()) committee, err := shardState.FindCommitteeByID(header.ShardID())
if err != nil { if err != nil {
return nil, ctxerror.New("cannot find shard in the shard state", return nil, err
"blockNum", header.Number(),
"shardID", header.ShardID(),
"coinbaseAddr", header.Coinbase(),
)
} }
committerKey := new(bls.PublicKey) committerKey := new(bls.PublicKey)
isStaking := consensus.ChainReader.Config().IsStaking(header.Epoch()) isStaking := consensus.ChainReader.Config().IsStaking(header.Epoch())
for _, member := range committee.Slots { for _, member := range committee.Slots {
if isStaking { if isStaking {
// After staking the coinbase address will be the address of bls public key // After staking the coinbase address will be the address of bls public key
if utils.GetAddressFromBLSPubKeyBytes(member.BLSPublicKey[:]) == header.Coinbase() { if utils.GetAddressFromBLSPubKeyBytes(member.BLSPublicKey[:]) == header.Coinbase() {
err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey) if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
if err != nil { return nil, err
return nil, ctxerror.New("cannot convert BLS public key",
"blsPublicKey", member.BLSPublicKey,
"coinbaseAddr", header.Coinbase()).WithCause(err)
} }
return committerKey, nil return committerKey, nil
} }
} else { } else {
if member.EcdsaAddress == header.Coinbase() { if member.EcdsaAddress == header.Coinbase() {
err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey) if err := member.BLSPublicKey.ToLibBLSPublicKey(committerKey); err != nil {
if err != nil { return nil, err
return nil, ctxerror.New("cannot convert BLS public key",
"blsPublicKey", member.BLSPublicKey,
"coinbaseAddr", header.Coinbase()).WithCause(err)
} }
return committerKey, nil return committerKey, nil
} }
} }
} }
return nil, ctxerror.New("cannot find corresponding BLS Public Key", "coinbaseAddr", header.Coinbase().Hex()) return nil, errors.Errorf(
"cannot find corresponding BLS Public Key coinbase %s",
header.Coinbase().Hex(),
)
} }
// UpdateConsensusInformation will update shard information (epoch, publicKeys, blockNum, viewID) // UpdateConsensusInformation will update shard information (epoch, publicKeys, blockNum, viewID)

@ -12,10 +12,10 @@ import (
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
vrf_bls "github.com/harmony-one/harmony/crypto/vrf/bls" vrf_bls "github.com/harmony-one/harmony/crypto/vrf/bls"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/p2p/host" "github.com/harmony-one/harmony/p2p/host"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/vdf/src/vdf_go" "github.com/harmony-one/vdf/src/vdf_go"
"github.com/pkg/errors"
) )
// handlemessageupdate will update the consensus state according to received message // handlemessageupdate will update the consensus state according to received message
@ -202,12 +202,16 @@ func (consensus *Consensus) LastCommitSig() ([]byte, []byte, error) {
lastCommits, err := consensus.ChainReader.ReadLastCommits() lastCommits, err := consensus.ChainReader.ReadLastCommits()
if err != nil || if err != nil ||
len(lastCommits) < shard.BLSSignatureSizeInBytes { len(lastCommits) < shard.BLSSignatureSizeInBytes {
msgs := consensus.FBFTLog.GetMessagesByTypeSeq(msg_pb.MessageType_COMMITTED, consensus.blockNum-1) msgs := consensus.FBFTLog.GetMessagesByTypeSeq(
msg_pb.MessageType_COMMITTED, consensus.blockNum-1,
)
if len(msgs) != 1 { if len(msgs) != 1 {
consensus.getLogger().Error(). consensus.getLogger().Error().
Int("numCommittedMsg", len(msgs)). Int("numCommittedMsg", len(msgs)).
Msg("GetLastCommitSig failed with wrong number of committed message") Msg("GetLastCommitSig failed with wrong number of committed message")
return nil, nil, ctxerror.New("GetLastCommitSig failed with wrong number of committed message", "numCommittedMsg", len(msgs)) return nil, nil, errors.Errorf(
"GetLastCommitSig failed with wrong number of committed message %d", len(msgs),
)
} }
lastCommits = msgs[0].Payload lastCommits = msgs[0].Payload
} }

@ -7,12 +7,12 @@ import (
msg_pb "github.com/harmony-one/harmony/api/proto/message" msg_pb "github.com/harmony-one/harmony/api/proto/message"
"github.com/harmony-one/harmony/consensus/quorum" "github.com/harmony-one/harmony/consensus/quorum"
"github.com/harmony-one/harmony/crypto/bls" "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
"github.com/harmony-one/harmony/p2p/p2pimpl" "github.com/harmony-one/harmony/p2p/p2pimpl"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/pkg/errors"
) )
func TestConstructAnnounceMessage(test *testing.T) { func TestConstructAnnounceMessage(test *testing.T) {
@ -85,10 +85,10 @@ func TestConstructPreparedMessage(test *testing.T) {
// According to RJ these failures are benign. // According to RJ these failures are benign.
if err := consensus.prepareBitmap.SetKey(leaderPubKey, true); err != nil { if err := consensus.prepareBitmap.SetKey(leaderPubKey, true); err != nil {
test.Log(ctxerror.New("prepareBitmap.SetKey").WithCause(err)) test.Log(errors.New("prepareBitmap.SetKey"))
} }
if err := consensus.prepareBitmap.SetKey(validatorPubKey, true); err != nil { if err := consensus.prepareBitmap.SetKey(validatorPubKey, true); err != nil {
test.Log(ctxerror.New("prepareBitmap.SetKey").WithCause(err)) test.Log(errors.New("prepareBitmap.SetKey"))
} }
network, err := consensus.construct(msg_pb.MessageType_PREPARED, nil, blsPriKey.GetPublicKey(), blsPriKey) network, err := consensus.construct(msg_pb.MessageType_PREPARED, nil, blsPriKey.GetPublicKey(), blsPriKey)

@ -26,12 +26,11 @@ import (
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/internal/ctxerror"
consensus_engine "github.com/harmony-one/harmony/consensus/engine" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/pkg/errors"
) )
// BlockValidator is responsible for validating block headers, uncles and // BlockValidator is responsible for validating block headers, uncles and
@ -183,12 +182,12 @@ func CalcGasLimit(parent *types.Block, gasFloor, gasCeil uint64) uint64 {
// ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself // ValidateCXReceiptsProof checks whether the given CXReceiptsProof is consistency with itself
func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error { func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) error {
if !v.config.AcceptsCrossTx(cxp.Header.Epoch()) { if !v.config.AcceptsCrossTx(cxp.Header.Epoch()) {
return ctxerror.New("[ValidateCXReceiptsProof] cross shard receipt received before cx fork") return errors.New("[ValidateCXReceiptsProof] cross shard receipt received before cx fork")
} }
toShardID, err := cxp.GetToShardID() toShardID, err := cxp.GetToShardID()
if err != nil { if err != nil {
return ctxerror.New("[ValidateCXReceiptsProof] invalid shardID").WithCause(err) return errors.Wrapf(err, "[ValidateCXReceiptsProof] invalid shardID")
} }
merkleProof := cxp.MerkleProof merkleProof := cxp.MerkleProof
@ -209,17 +208,15 @@ func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) err
} }
if !foundMatchingShardID { if !foundMatchingShardID {
return ctxerror.New("[ValidateCXReceiptsProof] Didn't find matching toShardID (no receipts for my shard)") return errors.New("[ValidateCXReceiptsProof] Didn't find matching toShardID (no receipts for my shard)")
} }
sourceShardID := merkleProof.ShardID
sourceBlockNum := merkleProof.BlockNum
sha := types.DeriveSha(cxp.Receipts) sha := types.DeriveSha(cxp.Receipts)
// (1) verify the CXReceipts trie root match // (1) verify the CXReceipts trie root match
if sha != shardRoot { if sha != shardRoot {
return ctxerror.New("[ValidateCXReceiptsProof] Trie Root of ReadCXReceipts Not Match", "sourceShardID", sourceShardID, "sourceBlockNum", sourceBlockNum, "calculated", sha, "got", shardRoot) return errors.New(
"[ValidateCXReceiptsProof] Trie Root of ReadCXReceipts Not Match",
)
} }
// (2) verify the outgoingCXReceiptsHash match // (2) verify the outgoingCXReceiptsHash match
@ -228,12 +225,17 @@ func (v *BlockValidator) ValidateCXReceiptsProof(cxp *types.CXReceiptsProof) err
outgoingHashFromSourceShard = types.EmptyRootHash outgoingHashFromSourceShard = types.EmptyRootHash
} }
if outgoingHashFromSourceShard != merkleProof.CXReceiptHash { if outgoingHashFromSourceShard != merkleProof.CXReceiptHash {
return ctxerror.New("[ValidateCXReceiptsProof] IncomingReceiptRootHash from source shard not match", "sourceShardID", sourceShardID, "sourceBlockNum", sourceBlockNum, "calculated", outgoingHashFromSourceShard, "got", merkleProof.CXReceiptHash) return errors.New(
"[ValidateCXReceiptsProof] IncomingReceiptRootHash from source shard not match",
)
} }
// (3) verify the block hash matches // (3) verify the block hash matches
if cxp.Header.Hash() != merkleProof.BlockHash || cxp.Header.OutgoingReceiptHash() != merkleProof.CXReceiptHash { if cxp.Header.Hash() != merkleProof.BlockHash ||
return ctxerror.New("[ValidateCXReceiptsProof] BlockHash or OutgoingReceiptHash not match in block Header", "blockHash", cxp.Header.Hash(), "merkleProofBlockHash", merkleProof.BlockHash, "headerOutReceiptHash", cxp.Header.OutgoingReceiptHash(), "merkleOutReceiptHash", merkleProof.CXReceiptHash) cxp.Header.OutgoingReceiptHash() != merkleProof.CXReceiptHash {
return errors.New(
"[ValidateCXReceiptsProof] BlockHash or OutgoingReceiptHash not match in block Header",
)
} }
// (4) verify blockHeader with seal // (4) verify blockHeader with seal

@ -35,7 +35,6 @@ import (
"github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/event"
"github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
consensus_engine "github.com/harmony-one/harmony/consensus/engine" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/consensus/reward"
@ -44,7 +43,6 @@ import (
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
@ -439,29 +437,6 @@ func (bc *BlockChain) SetHead(head uint64) error {
return bc.loadLastState() return bc.loadLastState()
} }
// FastSyncCommitHead sets the current head block to the one defined by the hash
// irrelevant what the chain contents were prior.
func (bc *BlockChain) FastSyncCommitHead(hash common.Hash) error {
// Make sure that both the block as well at its state trie exists
block := bc.GetBlockByHash(hash)
if block == nil {
return fmt.Errorf("non existent block [%x…]", hash[:4])
}
if _, err := trie.NewSecure(block.Root(), bc.stateCache.TrieDB(), 0); err != nil {
return err
}
// If all checks out, manually set the head block
bc.mu.Lock()
bc.currentBlock.Store(block)
bc.mu.Unlock()
utils.Logger().Info().
Str("number", block.Number().String()).
Str("hash", hash.Hex()).
Msg("Committed new head block")
return nil
}
// ShardID returns the shard Id of the blockchain. // ShardID returns the shard Id of the blockchain.
// TODO: use a better solution before resharding shuffle nodes to different shards // TODO: use a better solution before resharding shuffle nodes to different shards
func (bc *BlockChain) ShardID() uint32 { func (bc *BlockChain) ShardID() uint32 {
@ -1765,9 +1740,9 @@ func (bc *BlockChain) GetEpochBlockNumber(epoch *big.Int) (*big.Int, error) {
} }
blockNum, err := rawdb.ReadEpochBlockNumber(bc.db, epoch) blockNum, err := rawdb.ReadEpochBlockNumber(bc.db, epoch)
if err != nil { if err != nil {
return nil, ctxerror.New("cannot read epoch block number from database", return nil, errors.Wrapf(
"epoch", epoch, err, "cannot read epoch block number from database",
).WithCause(err) )
} }
cachedValue := []byte(blockNum.Bytes()) cachedValue := []byte(blockNum.Bytes())
bc.epochCache.Add(cacheKey, cachedValue) bc.epochCache.Add(cacheKey, cachedValue)
@ -1782,10 +1757,9 @@ func (bc *BlockChain) StoreEpochBlockNumber(
cachedValue := []byte(blockNum.Bytes()) cachedValue := []byte(blockNum.Bytes())
bc.epochCache.Add(cacheKey, cachedValue) bc.epochCache.Add(cacheKey, cachedValue)
if err := rawdb.WriteEpochBlockNumber(bc.db, epoch, blockNum); err != nil { if err := rawdb.WriteEpochBlockNumber(bc.db, epoch, blockNum); err != nil {
return ctxerror.New("cannot write epoch block number to database", return errors.Wrapf(
"epoch", epoch, err, "cannot write epoch block number to database",
"epochBlockNum", blockNum, )
).WithCause(err)
} }
return nil return nil
} }
@ -2702,18 +2676,15 @@ func (bc *BlockChain) GetECDSAFromCoinbase(header *block.Header) (common.Address
shardState, err := bc.ReadShardState(header.Epoch()) shardState, err := bc.ReadShardState(header.Epoch())
if err != nil { if err != nil {
return common.Address{}, ctxerror.New("cannot read shard state", return common.Address{}, errors.Wrapf(
"epoch", header.Epoch(), err, "cannot read shard state",
"coinbaseAddr", coinbase, )
).WithCause(err)
} }
committee, err := shardState.FindCommitteeByID(header.ShardID()) committee, err := shardState.FindCommitteeByID(header.ShardID())
if err != nil { if err != nil {
return common.Address{}, ctxerror.New("cannot find shard in the shard state", return common.Address{}, errors.Wrapf(
"blockNum", header.Number(), err, "cannot find shard in the shard state",
"shardID", header.ShardID(),
"coinbaseAddr", coinbase,
) )
} }
for _, member := range committee.Slots { for _, member := range committee.Slots {
@ -2726,7 +2697,10 @@ func (bc *BlockChain) GetECDSAFromCoinbase(header *block.Header) (common.Address
return member.EcdsaAddress, nil return member.EcdsaAddress, nil
} }
} }
return common.Address{}, ctxerror.New("cannot find corresponding ECDSA Address", "coinbaseAddr", header.Coinbase()) return common.Address{}, errors.Errorf(
"cannot find corresponding ECDSA Address for coinbase %s",
header.Coinbase().Hash().Hex(),
)
} }
// SuperCommitteeForNextEpoch ... // SuperCommitteeForNextEpoch ...

@ -19,21 +19,15 @@ package rawdb
import ( import (
"bytes" "bytes"
"math/big" "math/big"
"os"
"reflect"
"testing" "testing"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/golang/mock/gomock"
"github.com/syndtr/goleveldb/leveldb"
"golang.org/x/crypto/sha3"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
blockfactory "github.com/harmony-one/harmony/block/factory" blockfactory "github.com/harmony-one/harmony/block/factory"
mock "github.com/harmony-one/harmony/core/rawdb/mock"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"golang.org/x/crypto/sha3"
) )
// Tests block header storage and retrieval operations. // Tests block header storage and retrieval operations.
@ -335,154 +329,3 @@ func TestBlockReceiptStorage(t *testing.T) {
t.Fatalf("deleted receipts returned: %v", rs) t.Fatalf("deleted receipts returned: %v", rs)
} }
} }
func TestReadEpochBlockNumber(t *testing.T) {
type args struct {
// db is mocked
epoch *big.Int
}
type dbCall struct {
key []byte
data []byte
error error
}
tests := []struct {
name string
args args
dbCall dbCall
want *big.Int
wantErr bool
}{
{
"0",
args{epoch: big.NewInt(0)},
dbCall{
key: []byte{},
data: []byte{},
error: nil,
},
big.NewInt(0),
false,
},
{
"1",
args{epoch: big.NewInt(1)},
dbCall{
key: []byte{0x01},
data: []byte{0x64},
error: nil,
},
big.NewInt(100),
false,
},
{
"1000",
args{epoch: big.NewInt(1000)},
dbCall{
key: []byte{0x03, 0xe8},
data: []byte{0x01, 0x86, 0xa0},
error: nil,
},
big.NewInt(100000),
false,
},
{
"error",
args{epoch: big.NewInt(0)},
dbCall{
key: []byte{},
data: []byte{},
error: leveldb.ErrNotFound,
},
nil,
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
db := mock.NewMockDatabaseReader(ctrl)
fullKey := append(epochBlockNumberPrefix, tt.dbCall.key...)
db.EXPECT().Get(fullKey).Return(tt.dbCall.data, tt.dbCall.error)
got, err := ReadEpochBlockNumber(db, tt.args.epoch)
if (err != nil) != tt.wantErr {
t.Errorf("ReadEpochBlockNumber() error = %v, wantErr %v", err, tt.wantErr)
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ReadEpochBlockNumber() = %v, want %v", got, tt.want)
}
})
}
}
func TestWriteEpochBlockNumber(t *testing.T) {
type args struct {
epoch *big.Int
blockNum *big.Int
}
type dbCall struct {
key []byte
data []byte
error error
}
tests := []struct {
name string
args args
dbCall dbCall
wantErr bool
}{
{
"0",
args{epoch: big.NewInt(0), blockNum: big.NewInt(0)},
dbCall{
key: []byte{},
data: []byte{},
error: nil,
},
false,
},
{
"1",
args{epoch: big.NewInt(1), blockNum: big.NewInt(100)},
dbCall{
key: []byte{0x01},
data: []byte{0x64},
error: nil,
},
false,
},
{
"1000",
args{epoch: big.NewInt(1000), blockNum: big.NewInt(100000)},
dbCall{
key: []byte{0x03, 0xe8},
data: []byte{0x01, 0x86, 0xa0},
error: nil,
},
false,
},
{
"error",
args{epoch: big.NewInt(1000), blockNum: big.NewInt(100000)},
dbCall{
key: []byte{0x03, 0xe8},
data: []byte{0x01, 0x86, 0xa0},
error: os.ErrClosed,
},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
db := mock.NewMockDatabaseWriter(ctrl)
fullKey := append(epochBlockNumberPrefix, tt.dbCall.key...)
db.EXPECT().Put(fullKey, tt.dbCall.data).Return(tt.dbCall.error)
if err := WriteEpochBlockNumber(db, tt.args.epoch, tt.args.blockNum); (err != nil) != tt.wantErr {
t.Errorf("WriteEpochBlockNumber() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

@ -6,10 +6,10 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/pkg/errors"
) )
// ReadShardState retrieves shard state of a specific epoch. // ReadShardState retrieves shard state of a specific epoch.
@ -18,27 +18,27 @@ func ReadShardState(
) (*shard.State, error) { ) (*shard.State, error) {
data, err := db.Get(shardStateKey(epoch)) data, err := db.Get(shardStateKey(epoch))
if err != nil { if err != nil {
return nil, ctxerror.New(MsgNoShardStateFromDB, return nil, errors.New(MsgNoShardStateFromDB)
"epoch", epoch,
).WithCause(err)
} }
ss, err2 := shard.DecodeWrapper(data) ss, err2 := shard.DecodeWrapper(data)
if err2 != nil { if err2 != nil {
return nil, ctxerror.New("cannot decode sharding state", return nil, errors.Wrapf(
"epoch", epoch, err2, "cannot decode sharding state",
).WithCause(err2) )
} }
return ss, nil return ss, nil
} }
// WriteShardStateBytes stores sharding state into database. // WriteShardStateBytes stores sharding state into database.
func WriteShardStateBytes(db DatabaseWriter, epoch *big.Int, data []byte) (err error) { func WriteShardStateBytes(db DatabaseWriter, epoch *big.Int, data []byte) error {
if err = db.Put(shardStateKey(epoch), data); err != nil { if err := db.Put(shardStateKey(epoch), data); err != nil {
return ctxerror.New("cannot write sharding state", return errors.Wrapf(
"epoch", epoch, err, "cannot write sharding state",
).WithCause(err) )
} }
utils.Logger().Info().Str("epoch", epoch.String()).Int("size", len(data)).Msg("wrote sharding state") utils.Logger().Info().
Str("epoch", epoch.String()).
Int("size", len(data)).Msg("wrote sharding state")
return nil return nil
} }
@ -47,7 +47,7 @@ func ReadLastCommits(db DatabaseReader) ([]byte, error) {
var data []byte var data []byte
data, err := db.Get(lastCommitsKey) data, err := db.Get(lastCommitsKey)
if err != nil { if err != nil {
return nil, ctxerror.New("cannot read last commits from rawdb").WithCause(err) return nil, errors.New("cannot read last commits from rawdb")
} }
return data, nil return data, nil
} }
@ -57,7 +57,7 @@ func WriteLastCommits(
db DatabaseWriter, data []byte, db DatabaseWriter, data []byte,
) (err error) { ) (err error) {
if err = db.Put(lastCommitsKey, data); err != nil { if err = db.Put(lastCommitsKey, data); err != nil {
return ctxerror.New("cannot write last commits").WithCause(err) return errors.New("cannot write last commits")
} }
utils.Logger().Info(). utils.Logger().Info().
Int("size", len(data)). Int("size", len(data)).
@ -66,7 +66,9 @@ func WriteLastCommits(
} }
// ReadCrossLinkShardBlock retrieves the blockHash given shardID and blockNum // ReadCrossLinkShardBlock retrieves the blockHash given shardID and blockNum
func ReadCrossLinkShardBlock(db DatabaseReader, shardID uint32, blockNum uint64) ([]byte, error) { func ReadCrossLinkShardBlock(
db DatabaseReader, shardID uint32, blockNum uint64,
) ([]byte, error) {
return db.Get(crosslinkKey(shardID, blockNum)) return db.Get(crosslinkKey(shardID, blockNum))
} }
@ -147,7 +149,7 @@ func WriteCXReceipts(db DatabaseWriter, shardID uint32, number uint64, hash comm
func ReadCXReceiptsProofSpent(db DatabaseReader, shardID uint32, number uint64) (byte, error) { func ReadCXReceiptsProofSpent(db DatabaseReader, shardID uint32, number uint64) (byte, error) {
data, err := db.Get(cxReceiptSpentKey(shardID, number)) data, err := db.Get(cxReceiptSpentKey(shardID, number))
if err != nil || len(data) == 0 { if err != nil || len(data) == 0 {
return NAByte, ctxerror.New("[ReadCXReceiptsProofSpent] Cannot find the key", "shardID", shardID, "number", number).WithCause(err) return NAByte, errors.New("[ReadCXReceiptsProofSpent] Cannot find the key")
} }
return data[0], nil return data[0], nil
} }

@ -16,8 +16,6 @@
package rawdb package rawdb
//go:generate mockgen -source interfaces.go -destination mock/mock.go
// DatabaseReader wraps the Has and Get method of a backing data store. // DatabaseReader wraps the Has and Get method of a backing data store.
type DatabaseReader interface { type DatabaseReader interface {
Has(key []byte) (bool, error) Has(key []byte) (bool, error)

@ -1,137 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: interfaces.go
// Package mock_rawdb is a generated GoMock package.
package mock_rawdb
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockDatabaseReader is a mock of DatabaseReader interface
type MockDatabaseReader struct {
ctrl *gomock.Controller
recorder *MockDatabaseReaderMockRecorder
}
// MockDatabaseReaderMockRecorder is the mock recorder for MockDatabaseReader
type MockDatabaseReaderMockRecorder struct {
mock *MockDatabaseReader
}
// NewMockDatabaseReader creates a new mock instance
func NewMockDatabaseReader(ctrl *gomock.Controller) *MockDatabaseReader {
mock := &MockDatabaseReader{ctrl: ctrl}
mock.recorder = &MockDatabaseReaderMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockDatabaseReader) EXPECT() *MockDatabaseReaderMockRecorder {
return m.recorder
}
// Has mocks base method
func (m *MockDatabaseReader) Has(key []byte) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Has", key)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Has indicates an expected call of Has
func (mr *MockDatabaseReaderMockRecorder) Has(key interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockDatabaseReader)(nil).Has), key)
}
// Get mocks base method
func (m *MockDatabaseReader) Get(key []byte) ([]byte, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Get", key)
ret0, _ := ret[0].([]byte)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Get indicates an expected call of Get
func (mr *MockDatabaseReaderMockRecorder) Get(key interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDatabaseReader)(nil).Get), key)
}
// MockDatabaseWriter is a mock of DatabaseWriter interface
type MockDatabaseWriter struct {
ctrl *gomock.Controller
recorder *MockDatabaseWriterMockRecorder
}
// MockDatabaseWriterMockRecorder is the mock recorder for MockDatabaseWriter
type MockDatabaseWriterMockRecorder struct {
mock *MockDatabaseWriter
}
// NewMockDatabaseWriter creates a new mock instance
func NewMockDatabaseWriter(ctrl *gomock.Controller) *MockDatabaseWriter {
mock := &MockDatabaseWriter{ctrl: ctrl}
mock.recorder = &MockDatabaseWriterMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockDatabaseWriter) EXPECT() *MockDatabaseWriterMockRecorder {
return m.recorder
}
// Put mocks base method
func (m *MockDatabaseWriter) Put(key, value []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Put", key, value)
ret0, _ := ret[0].(error)
return ret0
}
// Put indicates an expected call of Put
func (mr *MockDatabaseWriterMockRecorder) Put(key, value interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockDatabaseWriter)(nil).Put), key, value)
}
// MockDatabaseDeleter is a mock of DatabaseDeleter interface
type MockDatabaseDeleter struct {
ctrl *gomock.Controller
recorder *MockDatabaseDeleterMockRecorder
}
// MockDatabaseDeleterMockRecorder is the mock recorder for MockDatabaseDeleter
type MockDatabaseDeleterMockRecorder struct {
mock *MockDatabaseDeleter
}
// NewMockDatabaseDeleter creates a new mock instance
func NewMockDatabaseDeleter(ctrl *gomock.Controller) *MockDatabaseDeleter {
mock := &MockDatabaseDeleter{ctrl: ctrl}
mock.recorder = &MockDatabaseDeleterMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockDatabaseDeleter) EXPECT() *MockDatabaseDeleterMockRecorder {
return m.recorder
}
// Delete mocks base method
func (m *MockDatabaseDeleter) Delete(key []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", key)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete
func (mr *MockDatabaseDeleterMockRecorder) Delete(key interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDatabaseDeleter)(nil).Delete), key)
}

@ -11,7 +11,6 @@ import (
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
@ -105,96 +104,6 @@ func TestCV3(t *testing.T) {
} }
} }
// Test CV5: identity longer than 140 characters
func TestCV5(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK)
// identity length: 200 characters
msg.Identity = "adsfwryuiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwiewwerfhuwefiuewfhuewhfiuewhfefhshfrhfhifhwbfvberhbvihfwuoefhusioehfeuwiafhaiobcfwfhceirui"
identitylengthCtxError := ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(msg.Identity), "maxIdentityLen", staking.MaxIdentityLength)
var err error
if _, err = VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg,
); err == nil {
t.Errorf("expected non null error")
}
ctxerr, ok := err.(ctxerror.CtxError)
if !ok {
t.Errorf("expected context aware error")
}
if ctxerr.Message() != identitylengthCtxError.Message() {
t.Error("expected", identitylengthCtxError, "got", err)
}
}
// Test CV6: website longer than 140 characters
func TestCV6(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK)
// Website length: 200 characters
msg.Website = "https://www.iwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwiewwerfhuwefiuewfwwwwwfiuewhfefhshfrheterhbvihfwuoefhusioehfeuwiafhaiobcfwfhceirui.com"
websiteLengthCtxError := ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(msg.Website), "maxWebsiteLen", staking.MaxWebsiteLength)
_, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg,
)
if err == nil {
t.Errorf("expected non null error")
}
ctxerr, ok := err.(ctxerror.CtxError)
if !ok {
t.Errorf("expected context aware error")
}
if ctxerr.Message() != websiteLengthCtxError.Message() {
t.Error("expected", websiteLengthCtxError, "got", err)
}
}
// Test CV7: security contact longer than 140 characters
func TestCV7(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK)
// Security Contact length: 200 characters
msg.SecurityContact = "HelloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwiewwerfhuwefiuewfwwwwwfiuewhfefhshfrheterhbvihfwuoefhusioehfeuwiafhaiobcfwfhceiruiHellodfdfdf"
securityContactLengthError := ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(msg.SecurityContact), "maxSecurityContactLen", staking.MaxSecurityContactLength)
_, err := VerifyAndCreateValidatorFromMsg(statedb, postStakingEpoch, big.NewInt(0), msg)
if err == nil {
t.Errorf("expected non null error")
}
ctxerr, ok := err.(ctxerror.CtxError)
if !ok {
t.Errorf("expected context aware error")
}
if ctxerr.Message() != securityContactLengthError.Message() {
t.Error("expected", securityContactLengthError, "got", err)
}
}
// Test CV8: details longer than 280 characters
func TestCV8(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))
msg := createValidator()
statedb.AddBalance(msg.ValidatorAddress, tenK)
// Details length: 300 characters
msg.Details = "HelloiwfhwifbwfbcerghveugbviuscbhwiefbcusidbcifwefhgciwefherhbfiwuehfciwiuebfcuyiewfhwieufwiweifhcwefhwefhwiewwerfhuwefiuewfwwwwwfiuewhfefhshfrheterhbvihfwuoefhusioehfeuwiafhaiobcfwfhceiruiHellodfdfdfjiusngognoherugbounviesrbgufhuoshcofwevusguahferhgvuervurehniwjvseivusehvsghjvorsugjvsiovjpsevsvvvvv"
detailsLenCtxError := ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(msg.Details), "maxDetailsLen", staking.MaxDetailsLength)
_, err := VerifyAndCreateValidatorFromMsg(
statedb, postStakingEpoch, big.NewInt(0), msg,
)
if err == nil {
t.Errorf("Expected non null error")
}
ctxerr, ok := err.(ctxerror.CtxError)
if !ok {
t.Errorf("expected context aware error")
}
if ctxerr.Message() != detailsLenCtxError.Message() {
t.Error("expected", detailsLenCtxError, "got", err)
}
}
// Test CV9: name == 140 characters // Test CV9: name == 140 characters
func TestCV9(t *testing.T) { func TestCV9(t *testing.T) {
statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase())) statedb, _ := state.New(common.Hash{}, state.NewDatabase(ethdb.NewMemDatabase()))

@ -17,7 +17,6 @@
package core package core
import ( import (
"fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
@ -29,12 +28,12 @@ import (
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/pkg/errors"
) )
// StateProcessor is a basic Processor, which takes care of transitioning // StateProcessor is a basic Processor, which takes care of transitioning
@ -124,16 +123,16 @@ func (p *StateProcessor) Process(
p.config, statedb, header, cx, p.config, statedb, header, cx,
); err != nil { ); err != nil {
return nil, nil, return nil, nil,
nil, 0, nil, ctxerror.New("[Process] Cannot apply incoming receipts").WithCause(err) nil, 0, nil, errors.New("[Process] Cannot apply incoming receipts")
} }
} }
slashes := slash.Records{} slashes := slash.Records{}
if s := header.Slashes(); len(s) > 0 { if s := header.Slashes(); len(s) > 0 {
if err := rlp.DecodeBytes(s, &slashes); err != nil { if err := rlp.DecodeBytes(s, &slashes); err != nil {
return nil, nil, nil, 0, nil, ctxerror.New( return nil, nil, nil, 0, nil, errors.New(
"[Process] Cannot finalize block", "[Process] Cannot finalize block",
).WithCause(err) )
} }
} }
@ -143,7 +142,7 @@ func (p *StateProcessor) Process(
receipts, outcxs, incxs, block.StakingTransactions(), slashes, receipts, outcxs, incxs, block.StakingTransactions(), slashes,
) )
if err != nil { if err != nil {
return nil, nil, nil, 0, nil, ctxerror.New("[Process] Cannot finalize block").WithCause(err) return nil, nil, nil, 0, nil, errors.New("[Process] Cannot finalize block")
} }
return receipts, outcxs, allLogs, *usedGas, payout, nil return receipts, outcxs, allLogs, *usedGas, payout, nil
@ -175,13 +174,14 @@ func getTransactionType(
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, uint64, error) { func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.DB, header *block.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, *types.CXReceipt, uint64, error) {
txType := getTransactionType(config, header, tx) txType := getTransactionType(config, header, tx)
if txType == types.InvalidTx { if txType == types.InvalidTx {
return nil, nil, 0, fmt.Errorf("Invalid Transaction Type") return nil, nil, 0, errors.New("Invalid Transaction Type")
} }
if txType != types.SameShardTx && !config.AcceptsCrossTx(header.Epoch()) { if txType != types.SameShardTx && !config.AcceptsCrossTx(header.Epoch()) {
return nil, nil, 0, fmt.Errorf( return nil, nil, 0, errors.Errorf(
"cannot handle cross-shard transaction until after epoch %v (now %v)", "cannot handle cross-shard transaction until after epoch %v (now %v)",
config.CrossTxEpoch, header.Epoch()) config.CrossTxEpoch, header.Epoch(),
)
} }
msg, err := tx.AsMessage(types.MakeSigner(config, header.Epoch())) msg, err := tx.AsMessage(types.MakeSigner(config, header.Epoch()))
@ -286,16 +286,22 @@ func ApplyStakingTransaction(
} }
// ApplyIncomingReceipt will add amount into ToAddress in the receipt // ApplyIncomingReceipt will add amount into ToAddress in the receipt
func ApplyIncomingReceipt(config *params.ChainConfig, db *state.DB, header *block.Header, cxp *types.CXReceiptsProof) error { func ApplyIncomingReceipt(
config *params.ChainConfig, db *state.DB,
header *block.Header, cxp *types.CXReceiptsProof,
) error {
if cxp == nil { if cxp == nil {
return nil return nil
} }
for _, cx := range cxp.Receipts { for _, cx := range cxp.Receipts {
if cx == nil || cx.To == nil { // should not happend if cx == nil || cx.To == nil { // should not happend
return ctxerror.New("ApplyIncomingReceipts: Invalid incomingReceipt!", "receipt", cx) return errors.Errorf(
"ApplyIncomingReceipts: Invalid incomingReceipt! %v", cx,
)
} }
utils.Logger().Info().Interface("receipt", cx).Msgf("ApplyIncomingReceipts: ADDING BALANCE %d", cx.Amount) utils.Logger().Info().Interface("receipt", cx).
Msgf("ApplyIncomingReceipts: ADDING BALANCE %d", cx.Amount)
if !db.Exist(*cx.To) { if !db.Exist(*cx.To) {
db.CreateAccount(*cx.To) db.CreateAccount(*cx.To)
@ -309,7 +315,9 @@ func ApplyIncomingReceipt(config *params.ChainConfig, db *state.DB, header *bloc
// StakingToMessage returns the staking transaction as a core.Message. // StakingToMessage returns the staking transaction as a core.Message.
// requires a signer to derive the sender. // requires a signer to derive the sender.
// put it here to avoid cyclic import // put it here to avoid cyclic import
func StakingToMessage(tx *staking.StakingTransaction, blockNum *big.Int) (types.Message, error) { func StakingToMessage(
tx *staking.StakingTransaction, blockNum *big.Int,
) (types.Message, error) {
payload, err := tx.RLPEncodeStakeMsg() payload, err := tx.RLPEncodeStakeMsg()
if err != nil { if err != nil {
return types.Message{}, err return types.Message{}, err

@ -5,13 +5,11 @@ import (
"encoding/binary" "encoding/binary"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/internal/ctxerror" "github.com/pkg/errors"
) )
// CXReceipt represents a receipt for cross-shard transaction // CXReceipt represents a receipt for cross-shard transaction
@ -203,7 +201,7 @@ func (cs CXReceiptsProofs) MaxToShardID() uint32 {
func (cxp *CXReceiptsProof) GetToShardID() (uint32, error) { func (cxp *CXReceiptsProof) GetToShardID() (uint32, error) {
var shardID uint32 var shardID uint32
if cxp == nil || len(cxp.Receipts) == 0 { if cxp == nil || len(cxp.Receipts) == 0 {
return uint32(0), ctxerror.New("[GetShardID] CXReceiptsProof or its receipts is NIL") return uint32(0), errors.New("[GetShardID] CXReceiptsProof or its receipts is NIL")
} }
for i, cx := range cxp.Receipts { for i, cx := range cxp.Receipts {
if i == 0 { if i == 0 {
@ -211,7 +209,7 @@ func (cxp *CXReceiptsProof) GetToShardID() (uint32, error) {
} else if shardID == cx.ToShardID { } else if shardID == cx.ToShardID {
continue continue
} else { } else {
return shardID, ctxerror.New("[GetShardID] CXReceiptsProof contains distinct ToShardID") return shardID, errors.New("[GetShardID] CXReceiptsProof contains distinct ToShardID")
} }
} }
return shardID, nil return shardID, nil

@ -1,11 +1,10 @@
package bls package bls
import ( import (
"errors"
"fmt" "fmt"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/internal/ctxerror" "github.com/pkg/errors"
) )
func init() { func init() {
@ -88,9 +87,11 @@ func (m *Mask) Len() int {
// cosigners 0-7, bits 0-7 of byte 1 correspond to cosigners 8-15, etc. // cosigners 0-7, bits 0-7 of byte 1 correspond to cosigners 8-15, etc.
func (m *Mask) SetMask(mask []byte) error { func (m *Mask) SetMask(mask []byte) error {
if m.Len() != len(mask) { if m.Len() != len(mask) {
return ctxerror.New("mismatching bitmap lengths", return errors.Errorf(
"expectedBitmapLength", m.Len(), "mismatching bitmap lengths expectedBitmapLength %d providedBitmapLength %d",
"providedBitmapLength", len(mask)) m.Len(),
len(mask),
)
} }
for i := range m.Publics { for i := range m.Publics {
byt := i >> 3 byt := i >> 3
@ -133,7 +134,7 @@ func (m *Mask) GetPubKeyFromMask(flag bool) []*bls.PublicKey {
for i := range m.Publics { for i := range m.Publics {
byt := i >> 3 byt := i >> 3
msk := byte(1) << uint(i&7) msk := byte(1) << uint(i&7)
if flag == true { if flag {
if (m.Bitmap[byt] & msk) != 0 { if (m.Bitmap[byt] & msk) != 0 {
pubKeys = append(pubKeys, m.Publics[i]) pubKeys = append(pubKeys, m.Publics[i])
} }

@ -1,35 +0,0 @@
package matchers
import (
"fmt"
"path"
"strings"
)
// Path is a pathname matcher.
//
// A value matches if it is the same as the matcher pattern or has the matcher
// pattern as a trailing component. For example,
// a pattern "abc/def" matches "abc/def" itself, "omg/abc/def",
// but not "abc/def/wtf", "abc/omg/def", or "xabc/def".
//
// Both the pattern and the value are sanitized using path.Clean() before use.
//
// The empty pattern "" matches only the empty value "".
type Path string
// Matches returns whether x is the matching pathname itself or ends with the
// matching pathname, inside another directory.
func (p Path) Matches(x interface{}) bool {
if s, ok := x.(string); ok {
p1 := path.Clean(string(p))
s = path.Clean(s)
return s == p1 || strings.HasSuffix(s, "/"+p1)
}
return false
}
// String returns the string representation of this pathname matcher.
func (p Path) String() string {
return fmt.Sprintf("<path suffix %#v>", path.Clean(string(p)))
}

@ -1,51 +0,0 @@
package matchers
import "testing"
func TestPathMatcher_Matches(t *testing.T) {
tests := []struct {
name string
p Path
x interface{}
want bool
}{
{"EmptyMatchesEmpty", "", "", true},
{"EmptyDoesNotMatchNonEmpty", "", "a", false},
{"EmptyDoesNotMatchNonEmptyEvenWithTrailingSlash", "", "a/", false},
{"NonEmptyDoesNotMatchEmpty", "a", "", false},
{"ExactIsOK", "abc/def", "abc/def", true},
{"SuffixIsOK", "abc/def", "omg/abc/def", true},
{"SubstringIsNotOK", "abc/def", "omg/abc/def/wtf", false},
{"PrefixIsNotOK", "abc/def", "abc/def/wtf", false},
{"InterveningElementIsNotOK", "abc/def", "abc/bbq/def", false},
{"GeneralNonMatch", "abc/def", "omg/wtf", false},
{"UncleanPattern", "abc//def/", "abc/def", true},
{"UncleanArg", "abc/def", "abc//def", true},
{"NonStringArg", "a", 'a', false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.p.Matches(tt.x); got != tt.want {
t.Errorf("Path.Matches() = %v, want %v", got, tt.want)
}
})
}
}
func TestPathMatcher_String(t *testing.T) {
tests := []struct {
name string
p Path
want string
}{
{"General", "abc/def", "<path suffix \"abc/def\">"},
{"Unclean", "abc//def/", "<path suffix \"abc/def\">"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.p.String(); got != tt.want {
t.Errorf("Path.String() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,39 +0,0 @@
package matchers
import (
"fmt"
"reflect"
)
// Slice is a gomock matcher that matches elements of an array or
// slice against its own members at the corresponding positions.
// Each member item in a Slice may be a regular item or a gomock
// Matcher instance.
type Slice []interface{}
// Matches returns whether x is a slice with matching elements.
func (sm Slice) Matches(x interface{}) bool {
v := reflect.ValueOf(x)
switch v.Kind() {
case reflect.Slice, reflect.Array: // OK
default:
return false
}
l := v.Len()
if l != len(sm) {
return false
}
for i, m := range sm {
m1 := toMatcher(m)
v1 := v.Index(i).Interface()
if !m1.Matches(v1) {
return false
}
}
return true
}
// String returns the string representation of this slice matcher.
func (sm Slice) String() string {
return fmt.Sprint([]interface{}(sm))
}

@ -1,114 +0,0 @@
package matchers
import (
"testing"
"github.com/golang/mock/gomock"
)
func TestSliceMatcher_Matches(t *testing.T) {
tests := []struct {
name string
sm Slice
x interface{}
want bool
}{
{
"EmptyEqEmpty",
Slice{},
[]interface{}{},
true,
},
{
"EmptyNeNotEmpty",
Slice{},
[]interface{}{1},
false,
},
{
"NotEmptyNeEmpty",
Slice{0},
[]interface{}{},
false,
},
{
"CompareRawValuesUsingEqualityHappy",
Slice{1, 2, 3},
[]interface{}{1, 2, 3},
true,
},
{
"CompareRawValuesUsingEqualityUnhappy",
Slice{1, 2, 3},
[]interface{}{1, 20, 3},
false,
},
{
"CompareMatcherUsingItsMatchesHappy",
Slice{gomock.Nil(), gomock.Eq(3)},
[]interface{}{nil, 3},
true,
},
{
"CompareMatcherUsingItsMatchesUnhappy",
Slice{gomock.Nil(), gomock.Eq(3)},
[]interface{}{0, 3},
false,
},
{
"NestedHappy",
Slice{Slice{3}, 30},
[]interface{}{[]interface{}{3}, 30},
true,
},
{
"NestedUnhappy",
Slice{Slice{3}, 30},
[]interface{}{[]interface{}{300}, 30},
false,
},
{
"MatchSliceOfMoreSpecificTypes",
Slice{1, 2, 3},
[]int{1, 2, 3},
true,
},
{
"AcceptArraysToo",
Slice{1, 2, 3},
[...]int{1, 2, 3},
true,
},
{
"RejectString",
Slice{'a', 'b', 'c'},
"abc",
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.sm.Matches(tt.x); got != tt.want {
t.Errorf("Slice.Matches() = %v, want %v", got, tt.want)
}
})
}
}
func TestSliceMatcher_String(t *testing.T) {
tests := []struct {
name string
sm Slice
want string
}{
{"int", []interface{}{3, 5, 7}, "[3 5 7]"},
{"string", []interface{}{"omg", "wtf", "bbq"}, "[omg wtf bbq]"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.sm.String(); got != tt.want {
t.Errorf("Slice.String() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,53 +0,0 @@
package matchers
import (
"fmt"
"reflect"
"sort"
"strings"
)
// Struct is a struct member matcher.
type Struct map[string]interface{}
// Matches returns whether all specified members match.
func (sm Struct) Matches(x interface{}) bool {
v := reflect.ValueOf(x)
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return false
}
for n, m := range sm {
m1 := toMatcher(m)
f := v.FieldByName(n)
if f == (reflect.Value{}) {
return false
}
f1 := f.Interface()
if !m1.Matches(f1) {
return false
}
}
return true
}
func (sm Struct) String() string {
var fields sort.StringSlice
for name := range sm {
fields = append(fields, name)
}
sort.Sort(fields)
for i, name := range fields {
value := sm[name]
var vs string
if _, ok := value.(fmt.Stringer); ok {
vs = fmt.Sprintf("%s", value)
} else {
vs = fmt.Sprintf("%v", value)
}
fields[i] = fmt.Sprintf("%s=%s", name, vs)
}
return "<struct " + strings.Join(fields, " ") + ">"
}

@ -1,113 +0,0 @@
package matchers
import (
"testing"
"github.com/golang/mock/gomock"
)
type stringable int
func (s stringable) String() string {
return "omg"
}
func TestStructMatcher_Matches(t *testing.T) {
type value struct {
A int
B string
}
tests := []struct {
name string
sm Struct
x interface{}
want bool
}{
{
"EmptyMatchesEmpty",
Struct{},
value{},
true,
},
{
"EmptyMatchesAny",
Struct{},
value{A: 3, B: "omg"},
true,
},
{
"EmptyStillDoesNotMatchNonStruct",
Struct{},
0,
false,
},
{
"RegularFieldValuesUseEq1",
Struct{"A": 3, "B": "omg"},
value{A: 3, B: "omg"},
true,
},
{
"RegularFieldValuesUseEq2",
Struct{"A": 3, "B": "omg"},
value{A: 4, B: "omg"},
false,
},
{
"MatchersAreUsedVerbatim1",
Struct{"A": gomock.Not(3), "B": gomock.Eq("omg")},
value{A: 4, B: "omg"},
true,
},
{
"MatchersAreUsedVerbatim2",
Struct{"A": gomock.Not(3), "B": gomock.Eq("omg")},
value{A: 3, B: "omg"},
false,
},
{
"UnspecifiedFieldsAreIgnored",
Struct{"A": 3},
value{A: 3, B: "omg"},
true,
},
{
"MissingFieldsReturnFailure",
Struct{"NOTFOUND": 3},
value{A: 3},
false,
},
{
"DerefsPointer",
Struct{"A": 3},
&value{A: 3},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.sm.Matches(tt.x); got != tt.want {
t.Errorf("Struct.Matches() = %v, want %v", got, tt.want)
}
})
}
}
func TestStructMatcher_String(t *testing.T) {
tests := []struct {
name string
sm Struct
want string
}{
{"UsesStringer", Struct{"A": stringable(0)}, "<struct A=omg>"},
{"ReprIfNotStringable", Struct{"A": nil}, "<struct A=<nil>>"},
{"SortsByKey", Struct{"B": 3, "A": 4}, "<struct A=4 B=3>"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.sm.String(); got != tt.want {
t.Errorf("Struct.String() = %v, want %v", got, tt.want)
}
})
}
}

@ -1,12 +0,0 @@
package matchers
import (
"github.com/golang/mock/gomock"
)
func toMatcher(v interface{}) gomock.Matcher {
if m, ok := v.(gomock.Matcher); ok {
return m
}
return gomock.Eq(v)
}

@ -6,10 +6,7 @@ import (
"math/big" "math/big"
"sort" "sort"
"github.com/harmony-one/harmony/staking/availability"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
@ -18,11 +15,11 @@ import (
"github.com/harmony-one/harmony/consensus/reward" "github.com/harmony-one/harmony/consensus/reward"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls" "github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/shard/committee" "github.com/harmony-one/harmony/shard/committee"
"github.com/harmony-one/harmony/staking/availability"
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -124,15 +121,21 @@ func (e *engineImpl) VerifyHeaders(chain engine.ChainReader, headers []*block.He
} }
// ReadPublicKeysFromLastBlock finds the public keys of last block's committee // ReadPublicKeysFromLastBlock finds the public keys of last block's committee
func ReadPublicKeysFromLastBlock(bc engine.ChainReader, header *block.Header) ([]*bls.PublicKey, error) { func ReadPublicKeysFromLastBlock(
bc engine.ChainReader, header *block.Header,
) ([]*bls.PublicKey, error) {
parentHeader := bc.GetHeaderByHash(header.ParentHash()) parentHeader := bc.GetHeaderByHash(header.ParentHash())
return GetPublicKeys(bc, parentHeader, false) return GetPublicKeys(bc, parentHeader, false)
} }
// VerifyShardState implements Engine, checking the shardstate is valid at epoch transition // VerifyShardState implements Engine, checking the shardstate is valid at epoch transition
func (e *engineImpl) VerifyShardState(bc engine.ChainReader, beacon engine.ChainReader, header *block.Header) error { func (e *engineImpl) VerifyShardState(
bc engine.ChainReader, beacon engine.ChainReader, header *block.Header,
) error {
if bc.ShardID() != header.ShardID() { if bc.ShardID() != header.ShardID() {
return ctxerror.New("[VerifyShardState] shardID not match", "bc.ShardID", bc.ShardID(), "header.ShardID", header.ShardID()) return errors.Errorf(
"[VerifyShardState] shardID not match %d %d", bc.ShardID(), header.ShardID(),
)
} }
headerShardStateBytes := header.ShardState() headerShardStateBytes := header.ShardState()
// TODO: figure out leader withhold shardState // TODO: figure out leader withhold shardState
@ -141,7 +144,7 @@ func (e *engineImpl) VerifyShardState(bc engine.ChainReader, beacon engine.Chain
} }
shardState, err := bc.SuperCommitteeForNextEpoch(beacon, header, true) shardState, err := bc.SuperCommitteeForNextEpoch(beacon, header, true)
if err != nil { if err != nil {
return ctxerror.New("[VerifyShardState] SuperCommitteeForNexEpoch calculation had error", "shardState", shardState).WithCause(err) return err
} }
isStaking := false isStaking := false
@ -150,23 +153,13 @@ func (e *engineImpl) VerifyShardState(bc engine.ChainReader, beacon engine.Chain
} }
shardStateBytes, err := shard.EncodeWrapper(*shardState, isStaking) shardStateBytes, err := shard.EncodeWrapper(*shardState, isStaking)
if err != nil { if err != nil {
return ctxerror.New("[VerifyShardState] ShardState Encoding had error", "shardStateBytes", shardStateBytes).WithCause(err) return errors.Wrapf(
err, "[VerifyShardState] ShardState Encoding had error",
)
} }
if !bytes.Equal(shardStateBytes, headerShardStateBytes) { if !bytes.Equal(shardStateBytes, headerShardStateBytes) {
headerSS, err := header.GetShardState() return errors.New("shard state header did not match as expected")
if err != nil {
headerSS = shard.State{}
}
utils.Logger().Error().
Str("shard-state", hexutil.Encode(shardStateBytes)).
Str("header-shard-state", hexutil.Encode(headerShardStateBytes)).
Msg("Shard states did not match, use rlpdump to inspect")
return ctxerror.New(
"[VerifyShardState] ShardState is Invalid", "shardStateEpoch", shardState.Epoch, "headerEpoch",
header.Epoch(), "headerShardStateEpoch", headerSS.Epoch, "beaconEpoch",
beacon.CurrentHeader().Epoch(),
)
} }
return nil return nil
@ -182,16 +175,16 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
publicKeys, err := ReadPublicKeysFromLastBlock(chain, header) publicKeys, err := ReadPublicKeysFromLastBlock(chain, header)
if err != nil { if err != nil {
return ctxerror.New("[VerifySeal] Cannot retrieve publickeys from last block").WithCause(err) return errors.New("[VerifySeal] Cannot retrieve publickeys from last block")
} }
sig := header.LastCommitSignature() sig := header.LastCommitSignature()
payload := append(sig[:], header.LastCommitBitmap()...) payload := append(sig[:], header.LastCommitBitmap()...)
aggSig, mask, err := ReadSignatureBitmapByPublicKeys(payload, publicKeys) aggSig, mask, err := ReadSignatureBitmapByPublicKeys(payload, publicKeys)
if err != nil { if err != nil {
return ctxerror.New( return errors.New(
"[VerifySeal] Unable to deserialize the LastCommitSignature" + "[VerifySeal] Unable to deserialize the LastCommitSignature" +
" and LastCommitBitmap in Block Header", " and LastCommitBitmap in Block Header",
).WithCause(err) )
} }
parentHash := header.ParentHash() parentHash := header.ParentHash()
parentHeader := chain.GetHeader(parentHash, header.Number().Uint64()-1) parentHeader := chain.GetHeader(parentHash, header.Number().Uint64()-1)
@ -216,7 +209,7 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
return err return err
} }
if !d.IsQuorumAchievedByMask(mask) { if !d.IsQuorumAchievedByMask(mask) {
return ctxerror.New( return errors.New(
"[VerifySeal] Not enough voting power in LastCommitSignature from Block Header", "[VerifySeal] Not enough voting power in LastCommitSignature from Block Header",
) )
} }
@ -227,9 +220,9 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
"cannot calculate quorum for block %s", header.Number()) "cannot calculate quorum for block %s", header.Number())
} }
if count := utils.CountOneBits(mask.Bitmap); count < int64(parentQuorum) { if count := utils.CountOneBits(mask.Bitmap); count < int64(parentQuorum) {
return ctxerror.New( return errors.Errorf(
"[VerifySeal] Not enough signature in LastCommitSignature from Block Header", "[VerifySeal] need %d signature in LastCommitSignature have %d",
"need", parentQuorum, "got", count, parentQuorum, count,
) )
} }
} }
@ -238,12 +231,9 @@ func (e *engineImpl) VerifySeal(chain engine.ChainReader, header *block.Header)
blockNumHash := make([]byte, 8) blockNumHash := make([]byte, 8)
binary.LittleEndian.PutUint64(blockNumHash, header.Number().Uint64()-1) binary.LittleEndian.PutUint64(blockNumHash, header.Number().Uint64()-1)
lastCommitPayload := append(blockNumHash, parentHash[:]...) lastCommitPayload := append(blockNumHash, parentHash[:]...)
if !aggSig.VerifyHash(mask.AggregatePublic, lastCommitPayload) { if !aggSig.VerifyHash(mask.AggregatePublic, lastCommitPayload) {
const msg = "[VerifySeal] Unable to verify aggregated signature from last block" const msg = "[VerifySeal] Unable to verify aggregated signature from last block"
return ctxerror.New( return errors.New(msg)
msg, "lastBlockNum", header.Number().Uint64()-1, "lastBlockHash", parentHash,
)
} }
return nil return nil
} }
@ -298,7 +288,7 @@ func (e *engineImpl) Finalize(
chain, state, header, e.Beaconchain(), chain, state, header, e.Beaconchain(),
) )
if err != nil { if err != nil {
return nil, nil, ctxerror.New("cannot pay block reward").WithCause(err) return nil, nil, errors.New("cannot pay block reward")
} }
// Apply slashes // Apply slashes
@ -328,15 +318,15 @@ func payoutUndelegations(
countTrack := map[common.Address]int{} countTrack := map[common.Address]int{}
if err != nil { if err != nil {
const msg = "[Finalize] failed to read all validators" const msg = "[Finalize] failed to read all validators"
return ctxerror.New(msg).WithCause(err) return errors.New(msg)
} }
// Payout undelegated/unlocked tokens // Payout undelegated/unlocked tokens
for _, validator := range validators { for _, validator := range validators {
wrapper, err := state.ValidatorWrapper(validator) wrapper, err := state.ValidatorWrapper(validator)
if err != nil { if err != nil {
return ctxerror.New( return errors.New(
"[Finalize] failed to get validator from state to finalize", "[Finalize] failed to get validator from state to finalize",
).WithCause(err) )
} }
for i := range wrapper.Delegations { for i := range wrapper.Delegations {
delegation := &wrapper.Delegations[i] delegation := &wrapper.Delegations[i]
@ -350,7 +340,7 @@ func payoutUndelegations(
validator, wrapper, validator, wrapper,
); err != nil { ); err != nil {
const msg = "[Finalize] failed update validator info" const msg = "[Finalize] failed update validator info"
return ctxerror.New(msg).WithCause(err) return errors.New(msg)
} }
} }
@ -367,21 +357,21 @@ func setLastEpochInCommittee(header *block.Header, state *state.DB) error {
newShardState, err := header.GetShardState() newShardState, err := header.GetShardState()
if err != nil { if err != nil {
const msg = "[Finalize] failed to read shard state" const msg = "[Finalize] failed to read shard state"
return ctxerror.New(msg).WithCause(err) return errors.New(msg)
} }
for _, addr := range newShardState.StakedValidators().Addrs { for _, addr := range newShardState.StakedValidators().Addrs {
wrapper, err := state.ValidatorWrapper(addr) wrapper, err := state.ValidatorWrapper(addr)
if err != nil { if err != nil {
return ctxerror.New( return errors.New(
"[Finalize] failed to get validator from state to finalize", "[Finalize] failed to get validator from state to finalize",
).WithCause(err) )
} }
wrapper.LastEpochInCommittee = newShardState.Epoch wrapper.LastEpochInCommittee = newShardState.Epoch
if err := state.UpdateValidatorWrapper( if err := state.UpdateValidatorWrapper(
addr, wrapper, addr, wrapper,
); err != nil { ); err != nil {
const msg = "[Finalize] failed update validator info" const msg = "[Finalize] failed update validator info"
return ctxerror.New(msg).WithCause(err) return errors.New(msg)
} }
} }
return nil return nil
@ -470,7 +460,7 @@ func applySlashes(
records, records,
rate, rate,
); err != nil { ); err != nil {
return ctxerror.New("[Finalize] could not apply slash").WithCause(err) return errors.New("[Finalize] could not apply slash")
} }
utils.Logger().Info(). utils.Logger().Info().
@ -492,8 +482,9 @@ func QuorumForBlock(
} else { } else {
ss, err = chain.ReadShardState(h.Epoch()) ss, err = chain.ReadShardState(h.Epoch())
if err != nil { if err != nil {
return 0, ctxerror.New("failed to read shard state of epoch", return 0, errors.Wrapf(
"epoch", h.Epoch().Uint64()).WithCause(err) err, "failed to read shard state of epoch %d", h.Epoch().Uint64(),
)
} }
} }
@ -515,13 +506,16 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
} }
publicKeys, err := GetPublicKeys(chain, header, reCalculate) publicKeys, err := GetPublicKeys(chain, header, reCalculate)
if err != nil { if err != nil {
return ctxerror.New("[VerifyHeaderWithSignature] Cannot get publickeys for block header").WithCause(err) return errors.New("[VerifyHeaderWithSignature] Cannot get publickeys for block header")
} }
payload := append(commitSig[:], commitBitmap[:]...) payload := append(commitSig[:], commitBitmap[:]...)
aggSig, mask, err := ReadSignatureBitmapByPublicKeys(payload, publicKeys) aggSig, mask, err := ReadSignatureBitmapByPublicKeys(payload, publicKeys)
if err != nil { if err != nil {
return ctxerror.New("[VerifyHeaderWithSignature] Unable to deserialize the commitSignature and commitBitmap in Block Header").WithCause(err) return errors.Wrapf(
err,
"[VerifyHeaderWithSignature] Unable to deserialize signatures",
)
} }
hash := header.Hash() hash := header.Hash()
@ -545,7 +539,7 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
return err return err
} }
if !d.IsQuorumAchievedByMask(mask) { if !d.IsQuorumAchievedByMask(mask) {
return ctxerror.New( return errors.New(
"[VerifySeal] Not enough voting power in commitSignature from Block Header", "[VerifySeal] Not enough voting power in commitSignature from Block Header",
) )
} }
@ -556,8 +550,9 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
"cannot calculate quorum for block %s", header.Number()) "cannot calculate quorum for block %s", header.Number())
} }
if count := utils.CountOneBits(mask.Bitmap); count < int64(quorumCount) { if count := utils.CountOneBits(mask.Bitmap); count < int64(quorumCount) {
return ctxerror.New("[VerifyHeaderWithSignature] Not enough signature in commitSignature from Block Header", return errors.New(
"need", quorumCount, "got", count) "[VerifyHeaderWithSignature] Not enough signature in commitSignature from Block Header",
)
} }
} }
// TODO(audit): verify signature on hash+blockNum+viewID (add a hard fork) // TODO(audit): verify signature on hash+blockNum+viewID (add a hard fork)
@ -566,7 +561,7 @@ func (e *engineImpl) VerifyHeaderWithSignature(chain engine.ChainReader, header
commitPayload := append(blockNumHash, hash[:]...) commitPayload := append(blockNumHash, hash[:]...)
if !aggSig.VerifyHash(mask.AggregatePublic, commitPayload) { if !aggSig.VerifyHash(mask.AggregatePublic, commitPayload) {
return ctxerror.New("[VerifySeal] Unable to verify aggregated signature for block", "blockNum", header.Number().Uint64()-1, "blockHash", hash) return errors.New("[VerifySeal] Unable to verify aggregated signature for block")
} }
return nil return nil
} }
@ -582,16 +577,19 @@ func GetPublicKeys(
} else { } else {
shardState, err = chain.ReadShardState(header.Epoch()) shardState, err = chain.ReadShardState(header.Epoch())
if err != nil { if err != nil {
return nil, ctxerror.New("failed to read shard state of epoch", return nil, errors.Wrapf(
"epoch", header.Epoch().Uint64()).WithCause(err) err, "failed to read shard state of epoch %d", header.Epoch().Uint64(),
)
} }
} }
subCommittee, err := shardState.FindCommitteeByID(header.ShardID()) subCommittee, err := shardState.FindCommitteeByID(header.ShardID())
if err != nil { if err != nil {
return nil, ctxerror.New("cannot find shard in the shard state", return nil, errors.Wrapf(
"blockNumber", header.Number(), err,
"shardID", header.ShardID(), "cannot find shard in the shard state at block %d shard %d",
header.Number(),
header.ShardID(),
) )
} }
return subCommittee.BLSPublicKeys() return subCommittee.BLSPublicKeys()

@ -5,8 +5,6 @@ import (
"math/big" "math/big"
"sort" "sort"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
@ -28,16 +26,16 @@ func ballotResultBeaconchain(
) (shard.SlotList, shard.SlotList, shard.SlotList, error) { ) (shard.SlotList, shard.SlotList, shard.SlotList, error) {
parentHeader := bc.GetHeaderByHash(header.ParentHash()) parentHeader := bc.GetHeaderByHash(header.ParentHash())
if parentHeader == nil { if parentHeader == nil {
return nil, nil, nil, ctxerror.New( return nil, nil, nil, errors.Errorf(
"cannot find parent block header in DB", "cannot find parent block header in DB %s",
"parentHash", header.ParentHash(), header.ParentHash().Hex(),
) )
} }
parentShardState, err := bc.ReadShardState(parentHeader.Epoch()) parentShardState, err := bc.ReadShardState(parentHeader.Epoch())
if err != nil { if err != nil {
return nil, nil, nil, ctxerror.New( return nil, nil, nil, errors.Errorf(
"cannot read shard state", "epoch", parentHeader.Epoch(), "cannot read shard state %v", parentHeader.Epoch(),
).WithCause(err) )
} }
return availability.BallotResult(parentHeader, header, parentShardState, shard.BeaconChainShardID) return availability.BallotResult(parentHeader, header, parentShardState, shard.BeaconChainShardID)
@ -325,14 +323,11 @@ func AccumulateRewardsAndCountSigs(
} }
// Before staking // Before staking
// TODO ek – retrieving by parent number (blockNum - 1) doesn't work,
// while it is okay with hash. Sounds like DB inconsistency.
// Figure out why.
parentHeader := bc.GetHeaderByHash(header.ParentHash()) parentHeader := bc.GetHeaderByHash(header.ParentHash())
if parentHeader == nil { if parentHeader == nil {
return network.EmptyPayout, ctxerror.New( return network.EmptyPayout, errors.Errorf(
"cannot find parent block header in DB", "cannot find parent block header in DB at parent hash %s",
"parentHash", header.ParentHash(), header.ParentHash().Hex(),
) )
} }
if parentHeader.Number().Cmp(common.Big0) == 0 { if parentHeader.Number().Cmp(common.Big0) == 0 {
@ -342,11 +337,13 @@ func AccumulateRewardsAndCountSigs(
} }
parentShardState, err := bc.ReadShardState(parentHeader.Epoch()) parentShardState, err := bc.ReadShardState(parentHeader.Epoch())
if err != nil { if err != nil {
return nil, ctxerror.New( return nil, errors.Wrapf(
"cannot read shard state", "epoch", parentHeader.Epoch(), err, "cannot read shard state at epoch %v", parentHeader.Epoch(),
).WithCause(err) )
} }
_, signers, _, err := availability.BallotResult(parentHeader, header, parentShardState, header.ShardID()) _, signers, _, err := availability.BallotResult(
parentHeader, header, parentShardState, header.ShardID(),
)
if err != nil { if err != nil {
return network.EmptyPayout, err return network.EmptyPayout, err

@ -1,33 +1,22 @@
package nodeconfig package nodeconfig
import ( import (
"math/big"
"testing" "testing"
"github.com/golang/mock/gomock"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/pkg/errors"
"github.com/harmony-one/harmony/internal/blsgen" "github.com/harmony-one/harmony/internal/blsgen"
shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding" shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding"
mock_shardingconfig "github.com/harmony-one/harmony/internal/configs/sharding/mock" "github.com/pkg/errors"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/multibls"
) )
func TestNodeConfigSingleton(t *testing.T) { func TestNodeConfigSingleton(t *testing.T) {
// init 3 configs // init 3 configs
_ = GetShardConfig(2) _ = GetShardConfig(2)
// get the singleton variable // get the singleton variable
c := GetShardConfig(Global) c := GetShardConfig(Global)
c.SetBeaconGroupID(GroupIDBeacon) c.SetBeaconGroupID(GroupIDBeacon)
d := GetShardConfig(Global) d := GetShardConfig(Global)
g := d.GetBeaconGroupID() g := d.GetBeaconGroupID()
if g != GroupIDBeacon { if g != GroupIDBeacon {
t.Errorf("GetBeaconGroupID = %v, expected = %v", g, GroupIDBeacon) t.Errorf("GetBeaconGroupID = %v, expected = %v", g, GroupIDBeacon)
} }
@ -67,74 +56,6 @@ func blsPubKeyFromHex(hex string) *bls.PublicKey {
return &k return &k
} }
func TestConfigType_ShardIDFromConsensusKey(t *testing.T) {
type fields struct {
ConsensusPubKey *bls.PublicKey
networkType NetworkType
}
tests := []struct {
name string
fields fields
epoch *big.Int
shards uint32
want uint32
}{
{
"Mainnet",
fields{
blsPubKeyFromHex("ca23704be46ce9c4704681ac9c08ddc644f1858a5c28ce236e1b5d9dee67c1f5a28075b5ef089adeffa8a372c1762007"),
"mainnet",
},
params.MainnetChainConfig.StakingEpoch,
4,
3,
},
{
"Testnet",
fields{
blsPubKeyFromHex("e7f54994bc5c02edeeb178ce2d34db276a893bab5c59ac3d7eb9f077c893f9e31171de6236ba0e21be415d8631e45b91"),
"testnet",
},
params.TestnetChainConfig.StakingEpoch,
3,
1,
},
{
"Devnet",
fields{
blsPubKeyFromHex("e7f54994bc5c02edeeb178ce2d34db276a893bab5c59ac3d7eb9f077c893f9e31171de6236ba0e21be415d8631e45b91"),
"devnet",
},
params.TestnetChainConfig.StakingEpoch,
2,
1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
instance := mock_shardingconfig.NewMockInstance(mc)
instance.EXPECT().NumShards().Return(tt.shards)
schedule := mock_shardingconfig.NewMockSchedule(mc)
schedule.EXPECT().InstanceForEpoch(tt.epoch).Return(instance)
conf := &ConfigType{
ConsensusPubKey: multibls.GetPublicKey(tt.fields.ConsensusPubKey),
networkType: tt.fields.networkType,
shardingSchedule: schedule,
}
got, err := conf.ShardIDFromConsensusKey()
if err != nil {
t.Errorf("ShardIDFromConsensusKey() error = %v", err)
return
}
if got != tt.want {
t.Errorf("ShardIDFromConsensusKey() got = %v, want %v", got, tt.want)
}
})
}
}
func TestValidateConsensusKeysForSameShard(t *testing.T) { func TestValidateConsensusKeysForSameShard(t *testing.T) {
// set localnet config // set localnet config
networkType := "localnet" networkType := "localnet"

@ -3,10 +3,9 @@ package shardingconfig
import ( import (
"math/big" "math/big"
"github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/genesis"
"github.com/harmony-one/harmony/numeric"
"github.com/pkg/errors"
) )
// NetworkID is the network type of the blockchain. // NetworkID is the network type of the blockchain.
@ -44,27 +43,33 @@ func NewInstance(
reshardingEpoch []*big.Int, blocksE uint64, reshardingEpoch []*big.Int, blocksE uint64,
) (Instance, error) { ) (Instance, error) {
if numShards < 1 { if numShards < 1 {
return nil, ctxerror.New("sharding config must have at least one shard", return nil, errors.Errorf(
"numShards", numShards) "sharding config must have at least one shard have %d", numShards,
)
} }
if numNodesPerShard < 1 { if numNodesPerShard < 1 {
return nil, ctxerror.New("each shard must have at least one node", return nil, errors.Errorf(
"numNodesPerShard", numNodesPerShard) "each shard must have at least one node %d", numNodesPerShard,
)
} }
if numHarmonyOperatedNodesPerShard < 0 { if numHarmonyOperatedNodesPerShard < 0 {
return nil, ctxerror.New("Harmony-operated nodes cannot be negative", return nil, errors.Errorf(
"numHarmonyOperatedNodesPerShard", numHarmonyOperatedNodesPerShard) "Harmony-operated nodes cannot be negative %d", numHarmonyOperatedNodesPerShard,
)
} }
if numHarmonyOperatedNodesPerShard > numNodesPerShard { if numHarmonyOperatedNodesPerShard > numNodesPerShard {
return nil, ctxerror.New(""+ return nil, errors.Errorf(""+
"number of Harmony-operated nodes cannot exceed "+ "number of Harmony-operated nodes cannot exceed "+
"overall number of nodes per shard", "overall number of nodes per shard %d %d",
"numHarmonyOperatedNodesPerShard", numHarmonyOperatedNodesPerShard, numHarmonyOperatedNodesPerShard,
"numNodesPerShard", numNodesPerShard) numNodesPerShard,
)
} }
if harmonyVotePercent.LT(numeric.ZeroDec()) || harmonyVotePercent.GT(numeric.OneDec()) { if harmonyVotePercent.LT(numeric.ZeroDec()) ||
return nil, ctxerror.New("" + harmonyVotePercent.GT(numeric.OneDec()) {
"total voting power of harmony nodes should be within [0, 1]") return nil, errors.Errorf("" +
"total voting power of harmony nodes should be within [0, 1]",
)
} }
return instance{ return instance{
@ -84,7 +89,9 @@ func NewInstance(
// given parameters. It panics if parameter validation fails. // given parameters. It panics if parameter validation fails.
// It is intended to be used for static initialization. // It is intended to be used for static initialization.
func MustNewInstance( func MustNewInstance(
numShards uint32, numNodesPerShard, numHarmonyOperatedNodesPerShard int, harmonyVotePercent numeric.Dec, numShards uint32,
numNodesPerShard, numHarmonyOperatedNodesPerShard int,
harmonyVotePercent numeric.Dec,
hmyAccounts []genesis.DeployAccount, hmyAccounts []genesis.DeployAccount,
fnAccounts []genesis.DeployAccount, fnAccounts []genesis.DeployAccount,
reshardingEpoch []*big.Int, blocksPerEpoch uint64, reshardingEpoch []*big.Int, blocksPerEpoch uint64,

@ -1,341 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: shardingconfig.go
// Package mock_shardingconfig is a generated GoMock package.
package mock_shardingconfig
import (
gomock "github.com/golang/mock/gomock"
sharding "github.com/harmony-one/harmony/internal/configs/sharding"
genesis "github.com/harmony-one/harmony/internal/genesis"
numeric "github.com/harmony-one/harmony/numeric"
big "math/big"
reflect "reflect"
)
// MockSchedule is a mock of Schedule interface
type MockSchedule struct {
ctrl *gomock.Controller
recorder *MockScheduleMockRecorder
}
// MockScheduleMockRecorder is the mock recorder for MockSchedule
type MockScheduleMockRecorder struct {
mock *MockSchedule
}
// NewMockSchedule creates a new mock instance
func NewMockSchedule(ctrl *gomock.Controller) *MockSchedule {
mock := &MockSchedule{ctrl: ctrl}
mock.recorder = &MockScheduleMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockSchedule) EXPECT() *MockScheduleMockRecorder {
return m.recorder
}
// InstanceForEpoch mocks base method
func (m *MockSchedule) InstanceForEpoch(epoch *big.Int) sharding.Instance {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "InstanceForEpoch", epoch)
ret0, _ := ret[0].(sharding.Instance)
return ret0
}
// InstanceForEpoch indicates an expected call of InstanceForEpoch
func (mr *MockScheduleMockRecorder) InstanceForEpoch(epoch interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceForEpoch", reflect.TypeOf((*MockSchedule)(nil).InstanceForEpoch), epoch)
}
// BlocksPerEpoch mocks base method
func (m *MockSchedule) BlocksPerEpoch() uint64 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BlocksPerEpoch")
ret0, _ := ret[0].(uint64)
return ret0
}
// BlocksPerEpoch indicates an expected call of BlocksPerEpoch
func (mr *MockScheduleMockRecorder) BlocksPerEpoch() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlocksPerEpoch", reflect.TypeOf((*MockSchedule)(nil).BlocksPerEpoch))
}
// CalcEpochNumber mocks base method
func (m *MockSchedule) CalcEpochNumber(blockNum uint64) *big.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CalcEpochNumber", blockNum)
ret0, _ := ret[0].(*big.Int)
return ret0
}
// CalcEpochNumber indicates an expected call of CalcEpochNumber
func (mr *MockScheduleMockRecorder) CalcEpochNumber(blockNum interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalcEpochNumber", reflect.TypeOf((*MockSchedule)(nil).CalcEpochNumber), blockNum)
}
// IsLastBlock mocks base method
func (m *MockSchedule) IsLastBlock(blockNum uint64) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IsLastBlock", blockNum)
ret0, _ := ret[0].(bool)
return ret0
}
// IsLastBlock indicates an expected call of IsLastBlock
func (mr *MockScheduleMockRecorder) IsLastBlock(blockNum interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsLastBlock", reflect.TypeOf((*MockSchedule)(nil).IsLastBlock), blockNum)
}
// EpochLastBlock mocks base method
func (m *MockSchedule) EpochLastBlock(epochNum uint64) uint64 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EpochLastBlock", epochNum)
ret0, _ := ret[0].(uint64)
return ret0
}
// EpochLastBlock indicates an expected call of EpochLastBlock
func (mr *MockScheduleMockRecorder) EpochLastBlock(epochNum interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EpochLastBlock", reflect.TypeOf((*MockSchedule)(nil).EpochLastBlock), epochNum)
}
// VdfDifficulty mocks base method
func (m *MockSchedule) VdfDifficulty() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "VdfDifficulty")
ret0, _ := ret[0].(int)
return ret0
}
// VdfDifficulty indicates an expected call of VdfDifficulty
func (mr *MockScheduleMockRecorder) VdfDifficulty() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "VdfDifficulty", reflect.TypeOf((*MockSchedule)(nil).VdfDifficulty))
}
// ConsensusRatio mocks base method
func (m *MockSchedule) ConsensusRatio() float64 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ConsensusRatio")
ret0, _ := ret[0].(float64)
return ret0
}
// ConsensusRatio indicates an expected call of ConsensusRatio
func (mr *MockScheduleMockRecorder) ConsensusRatio() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConsensusRatio", reflect.TypeOf((*MockSchedule)(nil).ConsensusRatio))
}
// RandomnessStartingEpoch mocks base method
func (m *MockSchedule) RandomnessStartingEpoch() uint64 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RandomnessStartingEpoch")
ret0, _ := ret[0].(uint64)
return ret0
}
// RandomnessStartingEpoch indicates an expected call of RandomnessStartingEpoch
func (mr *MockScheduleMockRecorder) RandomnessStartingEpoch() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RandomnessStartingEpoch", reflect.TypeOf((*MockSchedule)(nil).RandomnessStartingEpoch))
}
// GetNetworkID mocks base method
func (m *MockSchedule) GetNetworkID() sharding.NetworkID {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetNetworkID")
ret0, _ := ret[0].(sharding.NetworkID)
return ret0
}
// GetNetworkID indicates an expected call of GetNetworkID
func (mr *MockScheduleMockRecorder) GetNetworkID() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNetworkID", reflect.TypeOf((*MockSchedule)(nil).GetNetworkID))
}
// GetShardingStructure mocks base method
func (m *MockSchedule) GetShardingStructure(arg0, arg1 int) []map[string]interface{} {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetShardingStructure", arg0, arg1)
ret0, _ := ret[0].([]map[string]interface{})
return ret0
}
// GetShardingStructure indicates an expected call of GetShardingStructure
func (mr *MockScheduleMockRecorder) GetShardingStructure(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetShardingStructure", reflect.TypeOf((*MockSchedule)(nil).GetShardingStructure), arg0, arg1)
}
// MockInstance is a mock of Instance interface
type MockInstance struct {
ctrl *gomock.Controller
recorder *MockInstanceMockRecorder
}
// MockInstanceMockRecorder is the mock recorder for MockInstance
type MockInstanceMockRecorder struct {
mock *MockInstance
}
// NewMockInstance creates a new mock instance
func NewMockInstance(ctrl *gomock.Controller) *MockInstance {
mock := &MockInstance{ctrl: ctrl}
mock.recorder = &MockInstanceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInstance) EXPECT() *MockInstanceMockRecorder {
return m.recorder
}
// NumShards mocks base method
func (m *MockInstance) NumShards() uint32 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NumShards")
ret0, _ := ret[0].(uint32)
return ret0
}
// NumShards indicates an expected call of NumShards
func (mr *MockInstanceMockRecorder) NumShards() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NumShards", reflect.TypeOf((*MockInstance)(nil).NumShards))
}
// NumNodesPerShard mocks base method
func (m *MockInstance) NumNodesPerShard() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NumNodesPerShard")
ret0, _ := ret[0].(int)
return ret0
}
// NumNodesPerShard indicates an expected call of NumNodesPerShard
func (mr *MockInstanceMockRecorder) NumNodesPerShard() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NumNodesPerShard", reflect.TypeOf((*MockInstance)(nil).NumNodesPerShard))
}
// NumHarmonyOperatedNodesPerShard mocks base method
func (m *MockInstance) NumHarmonyOperatedNodesPerShard() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NumHarmonyOperatedNodesPerShard")
ret0, _ := ret[0].(int)
return ret0
}
// NumHarmonyOperatedNodesPerShard indicates an expected call of NumHarmonyOperatedNodesPerShard
func (mr *MockInstanceMockRecorder) NumHarmonyOperatedNodesPerShard() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NumHarmonyOperatedNodesPerShard", reflect.TypeOf((*MockInstance)(nil).NumHarmonyOperatedNodesPerShard))
}
// HarmonyVotePercent mocks base method
func (m *MockInstance) HarmonyVotePercent() numeric.Dec {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HarmonyVotePercent")
ret0, _ := ret[0].(numeric.Dec)
return ret0
}
// HarmonyVotePercent indicates an expected call of HarmonyVotePercent
func (mr *MockInstanceMockRecorder) HarmonyVotePercent() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HarmonyVotePercent", reflect.TypeOf((*MockInstance)(nil).HarmonyVotePercent))
}
// ExternalVotePercent mocks base method
func (m *MockInstance) ExternalVotePercent() numeric.Dec {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ExternalVotePercent")
ret0, _ := ret[0].(numeric.Dec)
return ret0
}
// ExternalVotePercent indicates an expected call of ExternalVotePercent
func (mr *MockInstanceMockRecorder) ExternalVotePercent() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExternalVotePercent", reflect.TypeOf((*MockInstance)(nil).ExternalVotePercent))
}
// HmyAccounts mocks base method
func (m *MockInstance) HmyAccounts() []genesis.DeployAccount {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HmyAccounts")
ret0, _ := ret[0].([]genesis.DeployAccount)
return ret0
}
// HmyAccounts indicates an expected call of HmyAccounts
func (mr *MockInstanceMockRecorder) HmyAccounts() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HmyAccounts", reflect.TypeOf((*MockInstance)(nil).HmyAccounts))
}
// FnAccounts mocks base method
func (m *MockInstance) FnAccounts() []genesis.DeployAccount {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FnAccounts")
ret0, _ := ret[0].([]genesis.DeployAccount)
return ret0
}
// FnAccounts indicates an expected call of FnAccounts
func (mr *MockInstanceMockRecorder) FnAccounts() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FnAccounts", reflect.TypeOf((*MockInstance)(nil).FnAccounts))
}
// FindAccount mocks base method
func (m *MockInstance) FindAccount(blsPubKey string) (bool, *genesis.DeployAccount) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "FindAccount", blsPubKey)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(*genesis.DeployAccount)
return ret0, ret1
}
// FindAccount indicates an expected call of FindAccount
func (mr *MockInstanceMockRecorder) FindAccount(blsPubKey interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAccount", reflect.TypeOf((*MockInstance)(nil).FindAccount), blsPubKey)
}
// ReshardingEpoch mocks base method
func (m *MockInstance) ReshardingEpoch() []*big.Int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReshardingEpoch")
ret0, _ := ret[0].([]*big.Int)
return ret0
}
// ReshardingEpoch indicates an expected call of ReshardingEpoch
func (mr *MockInstanceMockRecorder) ReshardingEpoch() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReshardingEpoch", reflect.TypeOf((*MockInstance)(nil).ReshardingEpoch))
}
// BlocksPerEpoch mocks base method
func (m *MockInstance) BlocksPerEpoch() uint64 {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BlocksPerEpoch")
ret0, _ := ret[0].(uint64)
return ret0
}
// BlocksPerEpoch indicates an expected call of BlocksPerEpoch
func (mr *MockInstanceMockRecorder) BlocksPerEpoch() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlocksPerEpoch", reflect.TypeOf((*MockInstance)(nil).BlocksPerEpoch))
}

@ -11,8 +11,6 @@ import (
"github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/genesis"
) )
//go:generate mockgen -source=shardingconfig.go -destination=mock/shardingconfig.go
// Schedule returns the sharding configuration instance for the given // Schedule returns the sharding configuration instance for the given
// epoch. // epoch.
type Schedule interface { type Schedule interface {

@ -1,163 +0,0 @@
// Package ctxerror provides a context-aware error facility.
//
// Inspired by log15-style (semi-)structured logging,
// it also provides a log15 bridge.
package ctxerror
//go:generate mockgen -source ctxerror.go -destination mock/ctxerror.go
import (
"fmt"
"github.com/ethereum/go-ethereum/log"
)
// CtxError is a context-aware error container.
type CtxError interface {
// Error returns a fully formatted message, with context info.
Error() string
// Message returns the bare error message, without context info.
Message() string
// Contexts returns message contexts.
// Caller shall not modify the returned map.
Contexts() map[string]interface{}
// WithCause chains an error after the receiver.
// It returns the merged/chained instance,
// where the message is "<receiver.Message>: <c.Message>",
// and with contexts merged (ones in c takes precedence).
WithCause(c error) CtxError
}
type ctxError struct {
msg string
ctx map[string]interface{}
}
// New creates and returns a new context-aware error.
func New(msg string, ctx ...interface{}) CtxError {
e := &ctxError{msg: msg, ctx: make(map[string]interface{})}
e.updateCtx(ctx...)
return e
}
func (e *ctxError) updateCtx(ctx ...interface{}) {
var name string
if len(ctx)%2 == 1 {
ctx = append(ctx, nil)
}
for idx, value := range ctx {
if idx%2 == 0 {
name = value.(string)
} else {
e.ctx[name] = value
}
}
}
// Error returns a fully formatted message, with context info.
func (e *ctxError) Error() string {
s := e.msg
for k, v := range e.ctx {
s += fmt.Sprintf(", %s=%#v", k, v)
}
return s
}
// Message returns the bare error message, without context info.
func (e *ctxError) Message() string {
return e.msg
}
// Contexts returns message contexts.
// Caller shall not modify the returned map.
func (e *ctxError) Contexts() map[string]interface{} {
return e.ctx
}
// WithCause chains an error after the receiver.
// It returns the merged/chained instance,
// where the message is “<receiver.Message>: <c.Message>”,
// and with contexts merged (ones in c takes precedence).
func (e *ctxError) WithCause(c error) CtxError {
r := &ctxError{msg: e.msg + ": ", ctx: make(map[string]interface{})}
for k, v := range e.ctx {
r.ctx[k] = v
}
switch c := c.(type) {
case *ctxError:
r.msg += c.msg
for k, v := range c.ctx {
r.ctx[k] = v
}
default:
r.msg += c.Error()
}
return r
}
// Log15Func is a log15-compatible logging function.
type Log15Func func(msg string, ctx ...interface{})
// Log15Logger logs something with a log15-style logging function.
type Log15Logger interface {
Log15(f Log15Func)
}
// Log15 logs the receiver with a log15-style logging function.
func (e *ctxError) Log15(f Log15Func) {
var ctx []interface{}
for k, v := range e.ctx {
ctx = append(ctx, k, v)
}
f(e.msg, ctx...)
}
// Log15 logs an error with a log15-style logging function.
// It handles both regular errors and Log15Logger-compliant errors.
func Log15(f Log15Func, e error) {
if e15, ok := e.(Log15Logger); ok {
e15.Log15(f)
} else {
f(e.Error())
}
}
// Log15WithMsg logs an error with a message prefix using a log15-style
// logging function. It is a shortcut for a common pattern of prepending a
// context prefix.
func Log15WithMsg(f Log15Func, e error, msg string, ctx ...interface{}) {
Log15(f, New(msg, ctx...).WithCause(e))
}
// Trace logs an error with a message prefix using a log15-style logger.
func Trace(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Trace, e, msg, ctx...)
}
// Debug logs an error with a message prefix using a log15-style logger.
func Debug(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Debug, e, msg, ctx...)
}
// Info logs an error with a message prefix using a log15-style logger.
func Info(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Info, e, msg, ctx...)
}
// Warn logs an error with a message prefix using a log15-style logger.
func Warn(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Warn, e, msg, ctx...)
}
// Error logs an error with a message prefix using a log15-style logger.
func Error(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Error, e, msg, ctx...)
}
// Crit logs an error with a message prefix using a log15-style logger.
func Crit(l log.Logger, e error, msg string, ctx ...interface{}) {
Log15WithMsg(l.Crit, e, msg, ctx...)
}

@ -1,363 +0,0 @@
package ctxerror
import (
"errors"
"reflect"
"testing"
)
func TestNew(t *testing.T) {
type args struct {
msg string
ctx []interface{}
}
tests := []struct {
name string
args args
want CtxError
}{
{
name: "Empty",
args: args{msg: "", ctx: []interface{}{}},
want: &ctxError{msg: "", ctx: map[string]interface{}{}},
},
{
name: "Regular",
args: args{msg: "omg", ctx: []interface{}{"wtf", 1, "bbq", 2}},
want: &ctxError{msg: "omg", ctx: map[string]interface{}{"wtf": 1, "bbq": 2}},
},
{
name: "Truncated",
args: args{
msg: "omg",
ctx: []interface{}{"wtf", 1, "bbq" /* missing value... */},
},
want: &ctxError{
msg: "omg",
ctx: map[string]interface{}{"wtf": 1, "bbq": /* becomes */ nil},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := New(tt.args.msg, tt.args.ctx...); !reflect.DeepEqual(got, tt.want) {
t.Errorf("New() = %#v, want %#v", got, tt.want)
}
})
}
}
func Test_ctxError_updateCtx(t *testing.T) {
tests := []struct {
name string
before, after map[string]interface{}
delta []interface{}
}{
{
name: "Empty",
before: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
delta: []interface{}{},
after: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
},
{
name: "Regular",
before: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
delta: []interface{}{"omg", 10, "wtf", 20},
after: map[string]interface{}{"omg": 10, "wtf": 20, "bbq": 3},
},
{
name: "Truncated",
before: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
delta: []interface{}{"omg", 10, "wtf" /* missing value... */},
after: map[string]interface{}{"omg": 10, "wtf": /* becomes */ nil, "bbq": 3},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &ctxError{msg: tt.name, ctx: tt.before}
e.updateCtx(tt.delta...)
if !reflect.DeepEqual(e.ctx, tt.after) {
t.Errorf("expected ctx %#v != %#v seen", tt.after, e.ctx)
}
})
}
}
func Test_ctxError_Error(t *testing.T) {
type fields struct {
msg string
ctx map[string]interface{}
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "AllEmpty",
fields: fields{msg: "", ctx: map[string]interface{}{}},
want: "",
},
{
name: "CtxEmpty",
fields: fields{msg: "omg", ctx: map[string]interface{}{}},
want: "omg",
},
{
name: "MsgEmpty",
fields: fields{msg: "", ctx: map[string]interface{}{"wtf": "bbq"}},
want: ", wtf=\"bbq\"",
},
{
name: "Regular",
fields: fields{msg: "omg", ctx: map[string]interface{}{"wtf": "bbq"}},
want: "omg, wtf=\"bbq\"",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &ctxError{
msg: tt.fields.msg,
ctx: tt.fields.ctx,
}
if got := e.Error(); got != tt.want {
t.Errorf("Error() = %#v, want %#v", got, tt.want)
}
})
}
}
func Test_ctxError_Message(t *testing.T) {
type fields struct {
msg string
ctx map[string]interface{}
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "AllEmpty",
fields: fields{msg: "", ctx: map[string]interface{}{}},
want: "",
},
{
name: "CtxEmpty",
fields: fields{msg: "omg", ctx: map[string]interface{}{}},
want: "omg",
},
{
name: "MsgEmpty",
fields: fields{msg: "", ctx: map[string]interface{}{"wtf": "bbq"}},
want: "",
},
{
name: "Regular",
fields: fields{msg: "omg", ctx: map[string]interface{}{"wtf": "bbq"}},
want: "omg",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &ctxError{
msg: tt.fields.msg,
ctx: tt.fields.ctx,
}
if got := e.Message(); got != tt.want {
t.Errorf("Message() = %#v, want %#v", got, tt.want)
}
})
}
}
func Test_ctxError_Contexts(t *testing.T) {
type fields struct {
msg string
ctx map[string]interface{}
}
tests := []struct {
name string
fields fields
want map[string]interface{}
}{
{
name: "Empty",
fields: fields{msg: "", ctx: map[string]interface{}{}},
want: map[string]interface{}{},
},
{
name: "Regular",
fields: fields{
msg: "",
ctx: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
},
want: map[string]interface{}{"omg": 1, "wtf": 2, "bbq": 3},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &ctxError{
msg: tt.fields.msg,
ctx: tt.fields.ctx,
}
if got := e.Contexts(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Contexts() = %#v, want %#v", got, tt.want)
}
})
}
}
func Test_ctxError_WithCause(t *testing.T) {
type fields struct {
msg string
ctx map[string]interface{}
}
type args struct {
c error
}
tests := []struct {
name string
fields fields
args args
want CtxError
}{
{
name: "CtxError",
fields: fields{
msg: "hello",
ctx: map[string]interface{}{"omg": 1, "wtf": 2},
},
args: args{c: &ctxError{
msg: "world",
ctx: map[string]interface{}{"wtf": 20, "bbq": 30},
}},
want: &ctxError{
msg: "hello: world",
ctx: map[string]interface{}{"omg": 1, "wtf": 20, "bbq": 30},
},
},
{
name: "RegularError",
fields: fields{
msg: "hello",
ctx: map[string]interface{}{"omg": 1, "wtf": 2},
},
args: args{c: errors.New("world")},
want: &ctxError{
msg: "hello: world",
ctx: map[string]interface{}{"omg": 1, "wtf": 2},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
e := &ctxError{
msg: tt.fields.msg,
ctx: tt.fields.ctx,
}
if got := e.WithCause(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("WithCause() = %#v, want %#v", got, tt.want)
}
})
}
}
func Test_ctxError_Log15(t *testing.T) {
type fields struct {
msg string
ctx map[string]interface{}
}
type want struct {
msg string
ctx []interface{}
}
tests := []struct {
name string
fields fields
want want
}{
{
name: "Empty",
fields: fields{msg: "", ctx: map[string]interface{}{}},
want: want{msg: "", ctx: nil},
},
{
name: "Regular",
fields: fields{msg: "hello", ctx: map[string]interface{}{"omg": 1}},
want: want{msg: "hello", ctx: []interface{}{"omg", 1}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
called := false
f := func(msg string, ctx ...interface{}) {
called = true
if msg != tt.want.msg {
t.Errorf("expected message %#v != %#v seen",
tt.want.msg, msg)
}
if !reflect.DeepEqual(ctx, tt.want.ctx) {
t.Errorf("expected ctx %#v != %#v seen", ctx, tt.want.ctx)
}
}
e := &ctxError{
msg: tt.fields.msg,
ctx: tt.fields.ctx,
}
e.Log15(f)
if !called {
t.Error("logging func not called")
}
})
}
}
func TestLog15(t *testing.T) {
type args struct {
e error
}
type want struct {
msg string
ctx []interface{}
}
tests := []struct {
name string
args args
want want
}{
{
name: "Regular",
args: args{e: errors.New("hello")},
want: want{msg: "hello", ctx: nil},
},
{
name: "CtxError",
args: args{e: &ctxError{
msg: "hello",
ctx: map[string]interface{}{"omg": 1},
}},
want: want{msg: "hello", ctx: []interface{}{"omg", 1}},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
called := false
f := func(msg string, ctx ...interface{}) {
called = true
if msg != tt.want.msg {
t.Errorf("expected message %#v != %#v seen",
tt.want.msg, msg)
}
if !reflect.DeepEqual(ctx, tt.want.ctx) {
t.Errorf("expected ctx %#v != %#v seen",
tt.want.ctx, ctx)
}
}
Log15(f, tt.args.e)
if !called {
t.Errorf("logging func not called")
}
})
}
}

@ -1,125 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: ctxerror.go
// Package mock_ctxerror is a generated GoMock package.
package mock_ctxerror
import (
gomock "github.com/golang/mock/gomock"
ctxerror "github.com/harmony-one/harmony/internal/ctxerror"
reflect "reflect"
)
// MockCtxError is a mock of CtxError interface
type MockCtxError struct {
ctrl *gomock.Controller
recorder *MockCtxErrorMockRecorder
}
// MockCtxErrorMockRecorder is the mock recorder for MockCtxError
type MockCtxErrorMockRecorder struct {
mock *MockCtxError
}
// NewMockCtxError creates a new mock instance
func NewMockCtxError(ctrl *gomock.Controller) *MockCtxError {
mock := &MockCtxError{ctrl: ctrl}
mock.recorder = &MockCtxErrorMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockCtxError) EXPECT() *MockCtxErrorMockRecorder {
return m.recorder
}
// Error mocks base method
func (m *MockCtxError) Error() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Error")
ret0, _ := ret[0].(string)
return ret0
}
// Error indicates an expected call of Error
func (mr *MockCtxErrorMockRecorder) Error() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockCtxError)(nil).Error))
}
// Message mocks base method
func (m *MockCtxError) Message() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Message")
ret0, _ := ret[0].(string)
return ret0
}
// Message indicates an expected call of Message
func (mr *MockCtxErrorMockRecorder) Message() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Message", reflect.TypeOf((*MockCtxError)(nil).Message))
}
// Contexts mocks base method
func (m *MockCtxError) Contexts() map[string]interface{} {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Contexts")
ret0, _ := ret[0].(map[string]interface{})
return ret0
}
// Contexts indicates an expected call of Contexts
func (mr *MockCtxErrorMockRecorder) Contexts() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Contexts", reflect.TypeOf((*MockCtxError)(nil).Contexts))
}
// WithCause mocks base method
func (m *MockCtxError) WithCause(c error) ctxerror.CtxError {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "WithCause", c)
ret0, _ := ret[0].(ctxerror.CtxError)
return ret0
}
// WithCause indicates an expected call of WithCause
func (mr *MockCtxErrorMockRecorder) WithCause(c interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WithCause", reflect.TypeOf((*MockCtxError)(nil).WithCause), c)
}
// MockLog15Logger is a mock of Log15Logger interface
type MockLog15Logger struct {
ctrl *gomock.Controller
recorder *MockLog15LoggerMockRecorder
}
// MockLog15LoggerMockRecorder is the mock recorder for MockLog15Logger
type MockLog15LoggerMockRecorder struct {
mock *MockLog15Logger
}
// NewMockLog15Logger creates a new mock instance
func NewMockLog15Logger(ctrl *gomock.Controller) *MockLog15Logger {
mock := &MockLog15Logger{ctrl: ctrl}
mock.recorder = &MockLog15LoggerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockLog15Logger) EXPECT() *MockLog15LoggerMockRecorder {
return m.recorder
}
// Log15 mocks base method
func (m *MockLog15Logger) Log15(f ctxerror.Log15Func) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Log15", f)
}
// Log15 indicates an expected call of Log15
func (mr *MockLog15LoggerMockRecorder) Log15(f interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Log15", reflect.TypeOf((*MockLog15Logger)(nil).Log15), f)
}

@ -5,14 +5,13 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/consensus/engine" "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
"github.com/harmony-one/harmony/internal/ctxerror" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/pkg/errors"
) )
// Collection is a collection of per-shard blockchains. // Collection is a collection of per-shard blockchains.
@ -78,15 +77,14 @@ func (sc *CollectionImpl) ShardChain(shardID uint32) (*core.BlockChain, error) {
// NewChainDB may return incompletely initialized DB; // NewChainDB may return incompletely initialized DB;
// avoid closing it. // avoid closing it.
db = nil db = nil
return nil, ctxerror.New("cannot open chain database").WithCause(err) return nil, errors.New("cannot open chain database")
} }
if rawdb.ReadCanonicalHash(db, 0) == (common.Hash{}) { if rawdb.ReadCanonicalHash(db, 0) == (common.Hash{}) {
utils.Logger().Info(). utils.Logger().Info().
Uint32("shardID", shardID). Uint32("shardID", shardID).
Msg("initializing a new chain database") Msg("initializing a new chain database")
if err := sc.dbInit.InitChainDB(db, shardID); err != nil { if err := sc.dbInit.InitChainDB(db, shardID); err != nil {
return nil, ctxerror.New("cannot initialize a new chain database"). return nil, errors.Wrapf(err, "cannot initialize a new chain database")
WithCause(err)
} }
} }
var cacheConfig *core.CacheConfig var cacheConfig *core.CacheConfig
@ -98,7 +96,7 @@ func (sc *CollectionImpl) ShardChain(shardID uint32) (*core.BlockChain, error) {
db, cacheConfig, sc.chainConfig, sc.engine, vm.Config{}, nil, db, cacheConfig, sc.chainConfig, sc.engine, vm.Config{}, nil,
) )
if err != nil { if err != nil {
return nil, ctxerror.New("cannot create blockchain").WithCause(err) return nil, errors.Wrapf(err, "cannot create blockchain")
} }
db = nil // don't close db = nil // don't close
sc.pool[shardID] = bc sc.pool[shardID] = bc
@ -118,7 +116,7 @@ func (sc *CollectionImpl) CloseShardChain(shardID uint32) error {
defer sc.mtx.Unlock() defer sc.mtx.Unlock()
bc, ok := sc.pool[shardID] bc, ok := sc.pool[shardID]
if !ok { if !ok {
return ctxerror.New("shard chain not found", "shardID", shardID) return errors.Errorf("shard chain not found %d", shardID)
} }
utils.Logger().Info(). utils.Logger().Info().
Uint32("shardID", shardID). Uint32("shardID", shardID).

@ -1,89 +0,0 @@
package utils
import (
"reflect"
"testing"
"github.com/ethereum/go-ethereum/log"
"github.com/golang/mock/gomock"
matchers "github.com/harmony-one/harmony/gomock_matchers"
"github.com/harmony-one/harmony/internal/utils/mock_log"
)
//go:generate mockgen -destination mock_log/logger.go github.com/ethereum/go-ethereum/log Logger
//go:generate mockgen -destination mock_log/handler.go github.com/ethereum/go-ethereum/log Handler
const (
thisPkg = "github.com/harmony-one/harmony/internal/utils"
thisFile = "logging_test.go"
)
func testWithCallerSkip0(t *testing.T, skip int, name string, line int) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
want := log.Root()
logger := mock_log.NewMockLogger(ctrl)
logger.EXPECT().New(matchers.Slice{
"funcName", thisPkg + "." + name,
"funcFile", thisFile,
"funcLine", line,
}).Return(want)
if got := WithCallerSkip(logger, skip); !reflect.DeepEqual(got, want) {
t.Errorf("WithCallerSkip() = %v, want %v", got, want)
}
}
func testWithCallerSkip1(t *testing.T, skip int, name string, line int) {
testWithCallerSkip0(t, skip, name, line)
}
func testWithCallerSkip2(t *testing.T, skip int, name string, line int) {
testWithCallerSkip1(t, skip, name, line)
}
func TestWithCallerSkip(t *testing.T) {
t.Run("0", func(t *testing.T) {
testWithCallerSkip2(t, 0, "testWithCallerSkip0", 32)
})
t.Run("1", func(t *testing.T) {
testWithCallerSkip2(t, 1, "testWithCallerSkip1", 38)
})
t.Run("2", func(t *testing.T) {
testWithCallerSkip2(t, 2, "testWithCallerSkip2", 42)
})
}
func TestWithCaller(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
want := log.Root()
logger := mock_log.NewMockLogger(ctrl)
logger.EXPECT().New(matchers.Slice{
"funcName", thisPkg + ".TestWithCaller",
"funcFile", thisFile,
"funcLine", 67, // keep this in sync with WithCaller() call below
}).Return(want)
if got := WithCaller(logger); !reflect.DeepEqual(got, want) {
t.Errorf("WithCallerSkip() = %v, want %v", got, want)
}
}
func TestGetLogger(t *testing.T) {
oldHandler := GetLogInstance().GetHandler()
defer GetLogInstance().SetHandler(oldHandler)
ctrl := gomock.NewController(t)
handler := mock_log.NewMockHandler(ctrl)
handler.EXPECT().Log(matchers.Struct{
"Msg": "omg",
"Ctx": matchers.Slice{
"port", "", // added by the singleton instance
"ip", "", // added by the singleton instance
"funcName", thisPkg + ".TestGetLogger",
"funcFile", thisFile,
"funcLine", 88, // keep this in sync with Debug() call below
},
})
GetLogInstance().SetHandler(handler)
GetLogger().Debug("omg")
}

@ -1,49 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: testing.go
// Package mock_utils is a generated GoMock package.
package mock_utils
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockTestLogger is a mock of TestLogger interface
type MockTestLogger struct {
ctrl *gomock.Controller
recorder *MockTestLoggerMockRecorder
}
// MockTestLoggerMockRecorder is the mock recorder for MockTestLogger
type MockTestLoggerMockRecorder struct {
mock *MockTestLogger
}
// NewMockTestLogger creates a new mock instance
func NewMockTestLogger(ctrl *gomock.Controller) *MockTestLogger {
mock := &MockTestLogger{ctrl: ctrl}
mock.recorder = &MockTestLoggerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockTestLogger) EXPECT() *MockTestLoggerMockRecorder {
return m.recorder
}
// Log mocks base method
func (m *MockTestLogger) Log(args ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{}
for _, a := range args {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Log", varargs...)
}
// Log indicates an expected call of Log
func (mr *MockTestLoggerMockRecorder) Log(args ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Log", reflect.TypeOf((*MockTestLogger)(nil).Log), args...)
}

@ -1,48 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ethereum/go-ethereum/log (interfaces: Handler)
// Package mock_log is a generated GoMock package.
package mock_log
import (
log "github.com/ethereum/go-ethereum/log"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockHandler is a mock of Handler interface
type MockHandler struct {
ctrl *gomock.Controller
recorder *MockHandlerMockRecorder
}
// MockHandlerMockRecorder is the mock recorder for MockHandler
type MockHandlerMockRecorder struct {
mock *MockHandler
}
// NewMockHandler creates a new mock instance
func NewMockHandler(ctrl *gomock.Controller) *MockHandler {
mock := &MockHandler{ctrl: ctrl}
mock.recorder = &MockHandlerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockHandler) EXPECT() *MockHandlerMockRecorder {
return m.recorder
}
// Log mocks base method
func (m *MockHandler) Log(arg0 *log.Record) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Log", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Log indicates an expected call of Log
func (mr *MockHandlerMockRecorder) Log(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Log", reflect.TypeOf((*MockHandler)(nil).Log), arg0)
}

@ -1,180 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/ethereum/go-ethereum/log (interfaces: Logger)
// Package mock_log is a generated GoMock package.
package mock_log
import (
log "github.com/ethereum/go-ethereum/log"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockLogger is a mock of Logger interface
type MockLogger struct {
ctrl *gomock.Controller
recorder *MockLoggerMockRecorder
}
// MockLoggerMockRecorder is the mock recorder for MockLogger
type MockLoggerMockRecorder struct {
mock *MockLogger
}
// NewMockLogger creates a new mock instance
func NewMockLogger(ctrl *gomock.Controller) *MockLogger {
mock := &MockLogger{ctrl: ctrl}
mock.recorder = &MockLoggerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockLogger) EXPECT() *MockLoggerMockRecorder {
return m.recorder
}
// Crit mocks base method
func (m *MockLogger) Crit(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Crit", varargs...)
}
// Crit indicates an expected call of Crit
func (mr *MockLoggerMockRecorder) Crit(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Crit", reflect.TypeOf((*MockLogger)(nil).Crit), varargs...)
}
// Debug mocks base method
func (m *MockLogger) Debug(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Debug", varargs...)
}
// Debug indicates an expected call of Debug
func (mr *MockLoggerMockRecorder) Debug(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Debug", reflect.TypeOf((*MockLogger)(nil).Debug), varargs...)
}
// Error mocks base method
func (m *MockLogger) Error(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Error", varargs...)
}
// Error indicates an expected call of Error
func (mr *MockLoggerMockRecorder) Error(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Error", reflect.TypeOf((*MockLogger)(nil).Error), varargs...)
}
// GetHandler mocks base method
func (m *MockLogger) GetHandler() log.Handler {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetHandler")
ret0, _ := ret[0].(log.Handler)
return ret0
}
// GetHandler indicates an expected call of GetHandler
func (mr *MockLoggerMockRecorder) GetHandler() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHandler", reflect.TypeOf((*MockLogger)(nil).GetHandler))
}
// Info mocks base method
func (m *MockLogger) Info(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Info", varargs...)
}
// Info indicates an expected call of Info
func (mr *MockLoggerMockRecorder) Info(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Info", reflect.TypeOf((*MockLogger)(nil).Info), varargs...)
}
// New mocks base method
func (m *MockLogger) New(arg0 ...interface{}) log.Logger {
m.ctrl.T.Helper()
varargs := []interface{}{}
for _, a := range arg0 {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "New", varargs...)
ret0, _ := ret[0].(log.Logger)
return ret0
}
// New indicates an expected call of New
func (mr *MockLoggerMockRecorder) New(arg0 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "New", reflect.TypeOf((*MockLogger)(nil).New), arg0...)
}
// SetHandler mocks base method
func (m *MockLogger) SetHandler(arg0 log.Handler) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "SetHandler", arg0)
}
// SetHandler indicates an expected call of SetHandler
func (mr *MockLoggerMockRecorder) SetHandler(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandler", reflect.TypeOf((*MockLogger)(nil).SetHandler), arg0)
}
// Trace mocks base method
func (m *MockLogger) Trace(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Trace", varargs...)
}
// Trace indicates an expected call of Trace
func (mr *MockLoggerMockRecorder) Trace(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trace", reflect.TypeOf((*MockLogger)(nil).Trace), varargs...)
}
// Warn mocks base method
func (m *MockLogger) Warn(arg0 string, arg1 ...interface{}) {
m.ctrl.T.Helper()
varargs := []interface{}{arg0}
for _, a := range arg1 {
varargs = append(varargs, a)
}
m.ctrl.Call(m, "Warn", varargs...)
}
// Warn indicates an expected call of Warn
func (mr *MockLoggerMockRecorder) Warn(arg0 interface{}, arg1 ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{arg0}, arg1...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Warn", reflect.TypeOf((*MockLogger)(nil).Warn), varargs...)
}

@ -1,69 +0,0 @@
package utils
import (
"fmt"
"strings"
"github.com/ethereum/go-ethereum/log"
)
//go:generate mockgen -source=testing.go -destination=mock/testing.go
// TestLogRedirector is a log15-compatible log handler that logs to the testing
// object. It is useful when debugging, because it surfaces application log
// messages – such as ones emitted by the SUT – which are otherwise discarded
// and not displayed during testing.
//
// Typical usage:
//
// func TestMyFunc(t *testing.T) {
// l := utils.GetLogInstance()
// lrd := NewTestLogRedirector(l, t)
// defer lrd.Close()
//
// // Everything sent to the logger l will be printed onto the test log,
// // until lrd.Close() is called at the end of the function.
// // Contexts are formatted using the "%#v" format specifier.
// l.Debug("hello", "audience", "world")
// // The above prints: hello, audience="world"
// }
type TestLogRedirector struct {
l log.Logger
h log.Handler
t TestLogger
}
// TestLogger is the logging interface implemented by testing.T.
type TestLogger interface {
Log(args ...interface{})
}
// NewTestLogRedirector returns a new testing log redirector.
// The given logger's handler is saved and replaced by the receiver.
// Caller shall ensure Close() is called when the redirector is no longer
// needed.
func NewTestLogRedirector(l log.Logger, t TestLogger) *TestLogRedirector {
r := &TestLogRedirector{l: l, h: l.GetHandler(), t: t}
l.SetHandler(r)
return r
}
// Log logs the given log15 record into the testing object.
func (redirector *TestLogRedirector) Log(r *log.Record) error {
segments := []string{fmt.Sprintf("[%s] %s", r.Lvl.String(), r.Msg)}
for i := 0; i+1 < len(r.Ctx); i += 2 {
segments = append(segments, fmt.Sprintf("%s=%#v", r.Ctx[i], r.Ctx[i+1]))
}
redirector.t.Log(strings.Join(segments, ", "))
return nil
}
// Close restores the log handler back to the original one.
func (redirector *TestLogRedirector) Close() error {
if redirector.l != nil {
redirector.l.SetHandler(redirector.h)
redirector.l = nil
redirector.h = nil
}
return nil
}

@ -1,106 +0,0 @@
package utils
import (
"testing"
"github.com/ethereum/go-ethereum/log"
"github.com/golang/mock/gomock"
mock_utils "github.com/harmony-one/harmony/internal/utils/mock"
)
func TestExampleTestLogRedirectorUsingGetLogInstance(t *testing.T) {
tlr := NewTestLogRedirector(GetLogInstance(), t)
defer tlr.Close()
// Everything logged via GetLogInstance(),
// including lines said by the Menethil family below,
// is forwarded to the testing object.
// You will see their lines when you run this “test.”
terenasMenethil()
arthasMenethil()
}
func terenasMenethil() {
GetLogInstance().Info("what are you doing my son")
}
func arthasMenethil() {
GetLogInstance().Warn("succeding you father")
}
func TestNewTestLogRedirector(t *testing.T) {
logger := log.New()
origHandler := logger.GetHandler()
tlr := NewTestLogRedirector(logger, t)
if tlr == nil {
t.Fatalf("NewTestLogRedirector() = nil")
}
if tlr.l != logger {
t.Errorf("NewTestLogRedirector().l = %v, want %v", tlr.l, logger)
}
if tlr.h != origHandler {
t.Errorf("NewTestLogRedirector().h = %v, want %v", tlr.h, origHandler)
}
if tlr.t != t {
t.Errorf("NewTestLogRedirector().t = %v, want %v", tlr.t, t)
}
}
func TestTestLogRedirector_Log(t *testing.T) {
type args struct {
r *log.Record
}
tests := []struct {
name string
rec log.Record
want string
}{
{
"WithoutContexts",
log.Record{Lvl: log.LvlDebug, Msg: "hello world"},
`[dbug] hello world`,
},
{
"WithContexts",
log.Record{Lvl: log.LvlWarn, Msg: "hello", Ctx: []interface{}{
"audience", "world",
"pid", 31337,
}},
`[warn] hello, audience="world", pid=31337`,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockTestLogger := mock_utils.NewMockTestLogger(ctrl)
redirector := NewTestLogRedirector(log.New(), mockTestLogger)
mockTestLogger.EXPECT().Log(tt.want)
if err := redirector.Log(&tt.rec); err != nil {
t.Errorf("TestLogRedirector.Log() error = %v, want nil", err)
}
})
}
}
func TestTestLogRedirector_Close(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockTestLogger := mock_utils.NewMockTestLogger(ctrl)
logger := log.New()
tlr := NewTestLogRedirector(logger, mockTestLogger)
mockTestLogger.EXPECT().Log("[info] before close").Times(1)
mockTestLogger.EXPECT().Log("[info] after close").Times(0)
mockTestLogger.EXPECT().Log("[info] after idempotent close").Times(0)
logger.Info("before close")
if err := tlr.Close(); err != nil {
t.Errorf("TestLogRedirector.Close() error = %v, want nil", err)
}
logger.Info("after close")
if err := tlr.Close(); err != nil {
t.Errorf("TestLogRedirector.Close() error = %v, want nil", err)
}
logger.Info("after idempotent close")
}

@ -21,7 +21,6 @@ import (
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/chain" "github.com/harmony-one/harmony/internal/chain"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/shardchain" "github.com/harmony-one/harmony/internal/shardchain"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
@ -34,6 +33,7 @@ import (
"github.com/harmony-one/harmony/staking/slash" "github.com/harmony-one/harmony/staking/slash"
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/harmony-one/harmony/webhooks" "github.com/harmony-one/harmony/webhooks"
"github.com/pkg/errors"
) )
// State is a state of a node. // State is a state of a node.
@ -141,10 +141,6 @@ type Node struct {
peerRegistrationRecord map[string]*syncConfig // record registration time (unixtime) of peers begin in syncing peerRegistrationRecord map[string]*syncConfig // record registration time (unixtime) of peers begin in syncing
SyncingPeerProvider SyncingPeerProvider SyncingPeerProvider SyncingPeerProvider
// syncing frequency parameters
syncFreq int
beaconSyncFreq int
// The p2p host used to send/receive p2p messages // The p2p host used to send/receive p2p messages
host p2p.Host host p2p.Host
@ -418,9 +414,6 @@ func New(
failedStakingTxns *ring.Ring failedStakingTxns *ring.Ring
failedTxns *ring.Ring failedTxns *ring.Ring
}{sync.Mutex{}, ring.New(sinkSize), ring.New(sinkSize)} }{sync.Mutex{}, ring.New(sinkSize), ring.New(sinkSize)}
node.syncFreq = SyncFrequency
node.beaconSyncFreq = SyncFrequency
// Get the node config that's created in the harmony.go program. // Get the node config that's created in the harmony.go program.
if consensusObj != nil { if consensusObj != nil {
node.NodeConfig = nodeconfig.GetShardConfig(consensusObj.ShardID) node.NodeConfig = nodeconfig.GetShardConfig(consensusObj.ShardID)
@ -572,7 +565,7 @@ func (node *Node) InitConsensusWithValidators() (err error) {
if node.Consensus == nil { if node.Consensus == nil {
utils.Logger().Error(). utils.Logger().Error().
Msg("[InitConsensusWithValidators] consenus is nil; Cannot figure out shardID") Msg("[InitConsensusWithValidators] consenus is nil; Cannot figure out shardID")
return ctxerror.New( return errors.New(
"[InitConsensusWithValidators] consenus is nil; Cannot figure out shardID", "[InitConsensusWithValidators] consenus is nil; Cannot figure out shardID",
) )
} }
@ -606,10 +599,10 @@ func (node *Node) InitConsensusWithValidators() (err error) {
Uint32("shardID", shardID). Uint32("shardID", shardID).
Uint64("blockNum", blockNum). Uint64("blockNum", blockNum).
Msg("[InitConsensusWithValidators] PublicKeys is Empty, Cannot update public keys") Msg("[InitConsensusWithValidators] PublicKeys is Empty, Cannot update public keys")
return ctxerror.New( return errors.Wrapf(
err,
"[InitConsensusWithValidators] PublicKeys is Empty, Cannot update public keys", "[InitConsensusWithValidators] PublicKeys is Empty, Cannot update public keys",
"shardID", shardID, )
"blockNum", blockNum)
} }
for _, key := range pubKeys { for _, key := range pubKeys {

@ -4,10 +4,10 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/verify" "github.com/harmony-one/harmony/staking/verify"
"github.com/pkg/errors"
) )
const ( const (
@ -15,43 +15,39 @@ const (
crossLinkBatchSize = 10 crossLinkBatchSize = 10
) )
var (
errAlreadyExist = errors.New("crosslink already exist")
)
// VerifyBlockCrossLinks verifies the cross links of the block // VerifyBlockCrossLinks verifies the cross links of the block
func (node *Node) VerifyBlockCrossLinks(block *types.Block) error { func (node *Node) VerifyBlockCrossLinks(block *types.Block) error {
if len(block.Header().CrossLinks()) == 0 { cxLinksData := block.Header().CrossLinks()
if len(cxLinksData) == 0 {
utils.Logger().Debug().Msgf("[CrossLinkVerification] Zero CrossLinks in the header") utils.Logger().Debug().Msgf("[CrossLinkVerification] Zero CrossLinks in the header")
return nil return nil
} }
crossLinks := &types.CrossLinks{} crossLinks := &types.CrossLinks{}
err := rlp.DecodeBytes(block.Header().CrossLinks(), crossLinks) err := rlp.DecodeBytes(cxLinksData, crossLinks)
if err != nil { if err != nil {
return ctxerror.New("[CrossLinkVerification] failed to decode cross links", return errors.Wrapf(
"blockHash", block.Hash(), err, "[CrossLinkVerification] failed to decode cross links",
"crossLinks", len(block.Header().CrossLinks()), )
).WithCause(err)
} }
if !crossLinks.IsSorted() { if !crossLinks.IsSorted() {
return ctxerror.New("[CrossLinkVerification] cross links are not sorted", return errors.New("[CrossLinkVerification] cross links are not sorted")
"blockHash", block.Hash(),
"crossLinks", len(block.Header().CrossLinks()),
)
} }
for _, crossLink := range *crossLinks { for _, crossLink := range *crossLinks {
cl, err := node.Blockchain().ReadCrossLink(crossLink.ShardID(), crossLink.BlockNum()) cl, err := node.Blockchain().ReadCrossLink(crossLink.ShardID(), crossLink.BlockNum())
if err == nil && cl != nil { if err == nil && cl != nil {
// Add slash for exist same blocknum but different crosslink // Add slash for exist same blocknum but different crosslink
return ctxerror.New("crosslink already exist!") return errAlreadyExist
} }
if err = node.VerifyCrossLink(crossLink); err != nil { if err := node.VerifyCrossLink(crossLink); err != nil {
return ctxerror.New("cannot VerifyBlockCrossLinks", return errors.Wrapf(err, "cannot VerifyBlockCrossLinks")
"blockHash", block.Hash(),
"blockNum", block.Number(),
"crossLinkShard", crossLink.ShardID(),
"crossLinkBlock", crossLink.BlockNum(),
"numTx", len(block.Transactions()),
).WithCause(err)
} }
} }
return nil return nil
@ -112,18 +108,17 @@ func (node *Node) ProcessCrossLinkMessage(msgPayload []byte) {
// VerifyCrossLink verifies the header is valid // VerifyCrossLink verifies the header is valid
func (node *Node) VerifyCrossLink(cl types.CrossLink) error { func (node *Node) VerifyCrossLink(cl types.CrossLink) error {
if node.Blockchain().ShardID() != shard.BeaconChainShardID { if node.Blockchain().ShardID() != shard.BeaconChainShardID {
return ctxerror.New("[VerifyCrossLink] Shard chains should not verify cross links") return errors.New("[VerifyCrossLink] Shard chains should not verify cross links")
} }
if cl.BlockNum() <= 1 { if cl.BlockNum() <= 1 {
return ctxerror.New("[VerifyCrossLink] CrossLink BlockNumber should greater than 1") return errors.New("[VerifyCrossLink] CrossLink BlockNumber should greater than 1")
} }
if !node.Blockchain().Config().IsCrossLink(cl.Epoch()) { if !node.Blockchain().Config().IsCrossLink(cl.Epoch()) {
return ctxerror.New( return errors.Errorf(
"[VerifyCrossLink] CrossLink Epoch should >= cross link starting epoch", "[VerifyCrossLink] CrossLink Epoch should >= cross link starting epoch %v %v",
"crossLinkEpoch", cl.Epoch(), "cross_link_starting_eoch", cl.Epoch(), node.Blockchain().Config().CrossLinkEpoch,
node.Blockchain().Config().CrossLinkEpoch,
) )
} }
@ -142,10 +137,11 @@ func (node *Node) VerifyCrossLink(cl types.CrossLink) error {
aggSig := &bls.Sign{} aggSig := &bls.Sign{}
sig := cl.Signature() sig := cl.Signature()
if err = aggSig.Deserialize(sig[:]); err != nil { if err := aggSig.Deserialize(sig[:]); err != nil {
return ctxerror.New( return errors.Wrapf(
err,
"[VerifyCrossLink] unable to deserialize multi-signature from payload", "[VerifyCrossLink] unable to deserialize multi-signature from payload",
).WithCause(err) )
} }
return verify.AggregateSigForCommittee( return verify.AggregateSigForCommittee(

@ -7,10 +7,10 @@ import (
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/p2p/host" "github.com/harmony-one/harmony/p2p/host"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/pkg/errors"
) )
// BroadcastCXReceipts broadcasts cross shard receipts to correspoding // BroadcastCXReceipts broadcasts cross shard receipts to correspoding
@ -66,7 +66,13 @@ func (node *Node) BroadcastCXReceiptsWithShardID(block *types.Block, commitSig [
return return
} }
cxReceiptsProof := &types.CXReceiptsProof{Receipts: cxReceipts, MerkleProof: merkleProof, Header: block.Header(), CommitSig: commitSig, CommitBitmap: commitBitmap} cxReceiptsProof := &types.CXReceiptsProof{
Receipts: cxReceipts,
MerkleProof: merkleProof,
Header: block.Header(),
CommitSig: commitSig,
CommitBitmap: commitBitmap,
}
groupID := nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(toShardID)) groupID := nodeconfig.NewGroupIDByShardID(nodeconfig.ShardID(toShardID))
utils.Logger().Info().Uint32("ToShardID", toShardID).Str("GroupID", string(groupID)).Interface("cxp", cxReceiptsProof).Msg("[BroadcastCXReceiptsWithShardID] ReadCXReceipts and MerkleProof ready. Sending CX receipts...") utils.Logger().Info().Uint32("ToShardID", toShardID).Str("GroupID", string(groupID)).Interface("cxp", cxReceiptsProof).Msg("[BroadcastCXReceiptsWithShardID] ReadCXReceipts and MerkleProof ready. Sending CX receipts...")
@ -102,29 +108,36 @@ func (node *Node) BroadcastMissingCXReceipts() {
} }
} }
var (
errDoubleSpent = errors.New("[verifyIncomingReceipts] Double Spent")
)
func (node *Node) verifyIncomingReceipts(block *types.Block) error { func (node *Node) verifyIncomingReceipts(block *types.Block) error {
m := make(map[common.Hash]struct{}) m := make(map[common.Hash]struct{})
cxps := block.IncomingReceipts() cxps := block.IncomingReceipts()
for _, cxp := range cxps { for _, cxp := range cxps {
// double spent // double spent
if node.Blockchain().IsSpent(cxp) { if node.Blockchain().IsSpent(cxp) {
return ctxerror.New("[verifyIncomingReceipts] Double Spent!") return errDoubleSpent
} }
hash := cxp.MerkleProof.BlockHash hash := cxp.MerkleProof.BlockHash
// duplicated receipts // duplicated receipts
if _, ok := m[hash]; ok { if _, ok := m[hash]; ok {
return ctxerror.New("[verifyIncomingReceipts] Double Spent!") return errDoubleSpent
} }
m[hash] = struct{}{} m[hash] = struct{}{}
for _, item := range cxp.Receipts { for _, item := range cxp.Receipts {
if item.ToShardID != node.Blockchain().ShardID() { if s := node.Blockchain().ShardID(); item.ToShardID != s {
return ctxerror.New("[verifyIncomingReceipts] Invalid ToShardID", "myShardID", node.Blockchain().ShardID(), "expectShardID", item.ToShardID) return errors.Errorf(
"[verifyIncomingReceipts] Invalid ToShardID %d expectShardID %d",
s, item.ToShardID,
)
} }
} }
if err := node.Blockchain().Validator().ValidateCXReceiptsProof(cxp); err != nil { if err := node.Blockchain().Validator().ValidateCXReceiptsProof(cxp); err != nil {
return ctxerror.New("[verifyIncomingReceipts] verification failed").WithCause(err) return errors.Wrapf(err, "[verifyIncomingReceipts] verification failed")
} }
} }
@ -133,7 +146,7 @@ func (node *Node) verifyIncomingReceipts(block *types.Block) error {
incomingReceiptHash = types.DeriveSha(cxps) incomingReceiptHash = types.DeriveSha(cxps)
} }
if incomingReceiptHash != block.Header().IncomingReceiptHash() { if incomingReceiptHash != block.Header().IncomingReceiptHash() {
return ctxerror.New("[verifyIncomingReceipts] Invalid IncomingReceiptHash in block header") return errors.New("[verifyIncomingReceipts] Invalid IncomingReceiptHash in block header")
} }
return nil return nil
@ -143,10 +156,12 @@ func (node *Node) verifyIncomingReceipts(block *types.Block) error {
func (node *Node) ProcessReceiptMessage(msgPayload []byte) { func (node *Node) ProcessReceiptMessage(msgPayload []byte) {
cxp := types.CXReceiptsProof{} cxp := types.CXReceiptsProof{}
if err := rlp.DecodeBytes(msgPayload, &cxp); err != nil { if err := rlp.DecodeBytes(msgPayload, &cxp); err != nil {
utils.Logger().Error().Err(err).Msg("[ProcessReceiptMessage] Unable to Decode message Payload") utils.Logger().Error().Err(err).
Msg("[ProcessReceiptMessage] Unable to Decode message Payload")
return return
} }
utils.Logger().Debug().Interface("cxp", cxp).Msg("[ProcessReceiptMessage] Add CXReceiptsProof to pending Receipts") utils.Logger().Debug().Interface("cxp", cxp).
Msg("[ProcessReceiptMessage] Add CXReceiptsProof to pending Receipts")
// TODO: integrate with txpool // TODO: integrate with txpool
node.AddPendingReceipts(&cxp) node.AddPendingReceipts(&cxp)
} }

@ -7,18 +7,16 @@ import (
"math/rand" "math/rand"
"time" "time"
"github.com/harmony-one/harmony/consensus"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/api/proto" "github.com/harmony-one/harmony/api/proto"
proto_discovery "github.com/harmony-one/harmony/api/proto/discovery" proto_discovery "github.com/harmony-one/harmony/api/proto/discovery"
proto_node "github.com/harmony-one/harmony/api/proto/node" proto_node "github.com/harmony-one/harmony/api/proto/node"
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/core" "github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node" nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/msgq" "github.com/harmony-one/harmony/msgq"
"github.com/harmony-one/harmony/p2p" "github.com/harmony-one/harmony/p2p"
@ -29,6 +27,7 @@ import (
staking "github.com/harmony-one/harmony/staking/types" staking "github.com/harmony-one/harmony/staking/types"
"github.com/harmony-one/harmony/webhooks" "github.com/harmony-one/harmony/webhooks"
libp2p_peer "github.com/libp2p/go-libp2p-core/peer" libp2p_peer "github.com/libp2p/go-libp2p-core/peer"
"github.com/pkg/errors"
) )
const p2pMsgPrefixSize = 5 const p2pMsgPrefixSize = 5
@ -332,11 +331,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
Str("blockHash", newBlock.Hash().Hex()). Str("blockHash", newBlock.Hash().Hex()).
Err(err). Err(err).
Msg("[VerifyNewBlock] Cannot validate header for the new block") Msg("[VerifyNewBlock] Cannot validate header for the new block")
return ctxerror.New( return err
"[VerifyNewBlock] Cannot validate header for the new block",
"blockHash",
newBlock.Hash(),
).WithCause(err)
} }
if newBlock.ShardID() != node.Blockchain().ShardID() { if newBlock.ShardID() != node.Blockchain().ShardID() {
@ -344,10 +339,7 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
Uint32("my shard ID", node.Blockchain().ShardID()). Uint32("my shard ID", node.Blockchain().ShardID()).
Uint32("new block's shard ID", newBlock.ShardID()). Uint32("new block's shard ID", newBlock.ShardID()).
Msg("[VerifyNewBlock] Wrong shard ID of the new block") Msg("[VerifyNewBlock] Wrong shard ID of the new block")
return ctxerror.New("[VerifyNewBlock] Wrong shard ID of the new block", return errors.New("[VerifyNewBlock] Wrong shard ID of the new block")
"my shard ID", node.Blockchain().ShardID(),
"new block's shard ID", newBlock.ShardID(),
)
} }
if err := node.Blockchain().Engine().VerifyShardState( if err := node.Blockchain().Engine().VerifyShardState(
@ -357,10 +349,9 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
Str("blockHash", newBlock.Hash().Hex()). Str("blockHash", newBlock.Hash().Hex()).
Err(err). Err(err).
Msg("[VerifyNewBlock] Cannot verify shard state for the new block") Msg("[VerifyNewBlock] Cannot verify shard state for the new block")
return ctxerror.New( return errors.New(
"[VerifyNewBlock] Cannot verify shard state for the new block", "blockHash", "[VerifyNewBlock] Cannot verify shard state for the new block",
newBlock.Hash(), )
).WithCause(err)
} }
if err := node.Blockchain().ValidateNewBlock(newBlock); err != nil { if err := node.Blockchain().ValidateNewBlock(newBlock); err != nil {
@ -381,10 +372,11 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
Int("numStakingTx", len(newBlock.StakingTransactions())). Int("numStakingTx", len(newBlock.StakingTransactions())).
Err(err). Err(err).
Msg("[VerifyNewBlock] Cannot Verify New Block!!!") Msg("[VerifyNewBlock] Cannot Verify New Block!!!")
return ctxerror.New("[VerifyNewBlock] Cannot Verify New Block!!!", return errors.Errorf(
"blockHash", newBlock.Hash(), "[VerifyNewBlock] Cannot Verify New Block!!! block-hash %s txn-count %d",
"numTx", len(newBlock.Transactions()), newBlock.Hash().Hex(),
).WithCause(err) len(newBlock.Transactions()),
)
} }
// Verify cross links // Verify cross links
@ -404,8 +396,9 @@ func (node *Node) VerifyNewBlock(newBlock *types.Block) error {
Int("numIncomingReceipts", len(newBlock.IncomingReceipts())). Int("numIncomingReceipts", len(newBlock.IncomingReceipts())).
Err(err). Err(err).
Msg("[VerifyNewBlock] Cannot ValidateNewBlock") Msg("[VerifyNewBlock] Cannot ValidateNewBlock")
return ctxerror.New("[VerifyNewBlock] Cannot ValidateNewBlock", "blockHash", newBlock.Hash(), return errors.Wrapf(
"numIncomingReceipts", len(newBlock.IncomingReceipts())).WithCause(err) err, "[VerifyNewBlock] Cannot ValidateNewBlock",
)
} }
return nil return nil
} }

@ -196,13 +196,13 @@ func (node *Node) DoBeaconSyncing() {
} }
} }
node.beaconSync.SyncLoop(node.Beaconchain(), node.BeaconWorker, true, nil) node.beaconSync.SyncLoop(node.Beaconchain(), node.BeaconWorker, true, nil)
time.Sleep(time.Duration(node.beaconSyncFreq) * time.Second) time.Sleep(time.Duration(SyncFrequency) * time.Second)
} }
} }
// DoSyncing keep the node in sync with other peers, willJoinConsensus means the node will try to join consensus after catch up // DoSyncing keep the node in sync with other peers, willJoinConsensus means the node will try to join consensus after catch up
func (node *Node) DoSyncing(bc *core.BlockChain, worker *worker.Worker, willJoinConsensus bool) { func (node *Node) DoSyncing(bc *core.BlockChain, worker *worker.Worker, willJoinConsensus bool) {
ticker := time.NewTicker(time.Duration(node.syncFreq) * time.Second) ticker := time.NewTicker(time.Duration(SyncFrequency) * time.Second)
// TODO ek – infinite loop; add shutdown/cleanup logic // TODO ek – infinite loop; add shutdown/cleanup logic
for { for {
select { select {

@ -17,7 +17,6 @@ import (
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/core/vm" "github.com/harmony-one/harmony/core/vm"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/params" "github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -251,7 +250,7 @@ func (w *Worker) CommitReceipts(receiptsList []*types.CXReceiptsProof) error {
if err := core.ApplyIncomingReceipt( if err := core.ApplyIncomingReceipt(
w.config, w.current.state, w.current.header, cx, w.config, w.current.state, w.current.header, cx,
); err != nil { ); err != nil {
return ctxerror.New("Failed applying cross-shard receipts").WithCause(err) return errors.Wrapf(err, "Failed applying cross-shard receipts")
} }
} }
w.current.incxs = append(w.current.incxs, receiptsList...) w.current.incxs = append(w.current.incxs, receiptsList...)
@ -471,7 +470,7 @@ func (w *Worker) FinalizeNewBlock(
w.current.slashes, w.current.slashes,
) )
if err != nil { if err != nil {
return nil, ctxerror.New("cannot finalize block").WithCause(err) return nil, errors.Wrapf(err, "cannot finalize block")
} }
return block, nil return block, nil

@ -314,12 +314,6 @@ func TestSerializationText(t *testing.T) {
require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2) require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2)
} }
type testDEmbedStruct struct {
Field1 string `json:"f1"`
Field2 int `json:"f2"`
Field3 Dec `json:"f3"`
}
func TestStringOverflow(t *testing.T) { func TestStringOverflow(t *testing.T) {
// two random 64 bit primes // two random 64 bit primes
dec1, err := NewDecFromStr("51643150036226787134389711697696177267") dec1, err := NewDecFromStr("51643150036226787134389711697696177267")

@ -6,8 +6,6 @@ import (
libp2p_peer "github.com/libp2p/go-libp2p-peer" libp2p_peer "github.com/libp2p/go-libp2p-peer"
) )
//go:generate mockgen -source host.go -destination=host/mock/host_mock.go
// Host is the client + server in p2p network. // Host is the client + server in p2p network.
type Host interface { type Host interface {
GetSelfPeer() Peer GetSelfPeer() Peer

@ -1,7 +1,5 @@
package hostv2 package hostv2
//go:generate mockgen -source=hostv2.go -package=hostv2 -destination=hostv2_mock_for_test.go
import ( import (
"context" "context"
"fmt" "fmt"

@ -1,152 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: hostv2.go
// Package hostv2 is a generated GoMock package.
package hostv2
import (
context "context"
gomock "github.com/golang/mock/gomock"
go_libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub"
reflect "reflect"
)
// MocktopicHandle is a mock of topicHandle interface
type MocktopicHandle struct {
ctrl *gomock.Controller
recorder *MocktopicHandleMockRecorder
}
// MocktopicHandleMockRecorder is the mock recorder for MocktopicHandle
type MocktopicHandleMockRecorder struct {
mock *MocktopicHandle
}
// NewMocktopicHandle creates a new mock instance
func NewMocktopicHandle(ctrl *gomock.Controller) *MocktopicHandle {
mock := &MocktopicHandle{ctrl: ctrl}
mock.recorder = &MocktopicHandleMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MocktopicHandle) EXPECT() *MocktopicHandleMockRecorder {
return m.recorder
}
// Publish mocks base method
func (m *MocktopicHandle) Publish(ctx context.Context, data []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Publish", ctx, data)
ret0, _ := ret[0].(error)
return ret0
}
// Publish indicates an expected call of Publish
func (mr *MocktopicHandleMockRecorder) Publish(ctx, data interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Publish", reflect.TypeOf((*MocktopicHandle)(nil).Publish), ctx, data)
}
// Subscribe mocks base method
func (m *MocktopicHandle) Subscribe() (subscription, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Subscribe")
ret0, _ := ret[0].(subscription)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Subscribe indicates an expected call of Subscribe
func (mr *MocktopicHandleMockRecorder) Subscribe() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Subscribe", reflect.TypeOf((*MocktopicHandle)(nil).Subscribe))
}
// MocktopicJoiner is a mock of topicJoiner interface
type MocktopicJoiner struct {
ctrl *gomock.Controller
recorder *MocktopicJoinerMockRecorder
}
// MocktopicJoinerMockRecorder is the mock recorder for MocktopicJoiner
type MocktopicJoinerMockRecorder struct {
mock *MocktopicJoiner
}
// NewMocktopicJoiner creates a new mock instance
func NewMocktopicJoiner(ctrl *gomock.Controller) *MocktopicJoiner {
mock := &MocktopicJoiner{ctrl: ctrl}
mock.recorder = &MocktopicJoinerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MocktopicJoiner) EXPECT() *MocktopicJoinerMockRecorder {
return m.recorder
}
// JoinTopic mocks base method
func (m *MocktopicJoiner) JoinTopic(topic string) (topicHandle, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "JoinTopic", topic)
ret0, _ := ret[0].(topicHandle)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// JoinTopic indicates an expected call of JoinTopic
func (mr *MocktopicJoinerMockRecorder) JoinTopic(topic interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JoinTopic", reflect.TypeOf((*MocktopicJoiner)(nil).JoinTopic), topic)
}
// Mocksubscription is a mock of subscription interface
type Mocksubscription struct {
ctrl *gomock.Controller
recorder *MocksubscriptionMockRecorder
}
// MocksubscriptionMockRecorder is the mock recorder for Mocksubscription
type MocksubscriptionMockRecorder struct {
mock *Mocksubscription
}
// NewMocksubscription creates a new mock instance
func NewMocksubscription(ctrl *gomock.Controller) *Mocksubscription {
mock := &Mocksubscription{ctrl: ctrl}
mock.recorder = &MocksubscriptionMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *Mocksubscription) EXPECT() *MocksubscriptionMockRecorder {
return m.recorder
}
// Next mocks base method
func (m *Mocksubscription) Next(ctx context.Context) (*go_libp2p_pubsub.Message, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Next", ctx)
ret0, _ := ret[0].(*go_libp2p_pubsub.Message)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Next indicates an expected call of Next
func (mr *MocksubscriptionMockRecorder) Next(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Next", reflect.TypeOf((*Mocksubscription)(nil).Next), ctx)
}
// Cancel mocks base method
func (m *Mocksubscription) Cancel() {
m.ctrl.T.Helper()
m.ctrl.Call(m, "Cancel")
}
// Cancel indicates an expected call of Cancel
func (mr *MocksubscriptionMockRecorder) Cancel() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cancel", reflect.TypeOf((*Mocksubscription)(nil).Cancel))
}

@ -1,299 +0,0 @@
package hostv2
import (
"context"
"errors"
"reflect"
"testing"
"github.com/golang/mock/gomock"
libp2p_peer "github.com/libp2p/go-libp2p-core/peer"
libp2p_pubsub "github.com/libp2p/go-libp2p-pubsub"
libp2p_pubsub_pb "github.com/libp2p/go-libp2p-pubsub/pb"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
)
func TestHostV2_SendMessageToGroups(t *testing.T) {
t.Run("Basic", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
okTopic := NewMocktopicHandle(mc)
newTopic := NewMocktopicHandle(mc)
groups := []nodeconfig.GroupID{"OK", "New"}
data := []byte{1, 2, 3}
joined := map[string]topicHandle{"OK": okTopic}
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: joined}
gomock.InOrder(
// okTopic is already in joined map, JoinTopic shouldn't be called
joiner.EXPECT().JoinTopic("OK").Times(0),
okTopic.EXPECT().Publish(context.TODO(), data).Return(nil),
// newTopic is not in joined map, JoinTopic should be called
joiner.EXPECT().JoinTopic("New").Return(newTopic, nil),
newTopic.EXPECT().Publish(context.TODO(), data).Return(nil),
)
err := host.SendMessageToGroups(groups, data)
if err != nil {
t.Errorf("expected no error; got %v", err)
}
})
t.Run("JoinError", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
okTopic := NewMocktopicHandle(mc)
groups := []nodeconfig.GroupID{"Error", "OK"}
data := []byte{1, 2, 3}
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
gomock.InOrder(
// Make first join return an error
joiner.EXPECT().JoinTopic("Error").Return(nil, errors.New("join error")),
// Subsequent topics should still be processed after an error
joiner.EXPECT().JoinTopic("OK").Return(okTopic, nil),
okTopic.EXPECT().Publish(context.TODO(), data).Return(nil),
)
err := host.SendMessageToGroups(groups, data)
if err == nil {
t.Error("expected an error; got nil")
}
})
t.Run("PublishError", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
okTopic := NewMocktopicHandle(mc)
erringTopic := NewMocktopicHandle(mc)
groups := []nodeconfig.GroupID{"Error", "OK"}
data := []byte{1, 2, 3}
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
gomock.InOrder(
// Make first publish return an error
joiner.EXPECT().JoinTopic("Error").Return(erringTopic, nil),
erringTopic.EXPECT().Publish(context.TODO(), data).Return(errors.New("publish error")),
// Subsequent topics should still be processed after an error
joiner.EXPECT().JoinTopic("OK").Return(okTopic, nil),
okTopic.EXPECT().Publish(context.TODO(), data).Return(nil),
)
if err := host.SendMessageToGroups(groups, data); err == nil {
t.Error("expected an error; got nil")
}
})
}
func TestGroupReceiver_Close(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
sub := NewMocksubscription(mc)
sub.EXPECT().Cancel()
receiver := GroupReceiverImpl{sub: sub}
err := receiver.Close()
if err != nil {
t.Errorf("expected no error but got %v", err)
}
}
func pubsubMessage(from libp2p_peer.ID, data []byte) *libp2p_pubsub.Message {
m := libp2p_pubsub_pb.Message{From: []byte(from), Data: data}
return &libp2p_pubsub.Message{Message: &m}
}
func TestGroupReceiver_Receive(t *testing.T) {
t.Run("OK", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
ctx := context.Background()
sub := NewMocksubscription(mc)
receiver := GroupReceiverImpl{sub: sub}
wantSender := libp2p_peer.ID("OK")
wantMsg := []byte{1, 2, 3}
sub.EXPECT().Next(ctx).Return(pubsubMessage(wantSender, wantMsg), nil)
gotMsg, gotSender, err := receiver.Receive(ctx)
if err != nil {
t.Errorf("expected no error; got %v", err)
}
if gotSender != wantSender {
t.Errorf("expected sender %v; got %v", wantSender, gotSender)
}
if !reflect.DeepEqual(gotMsg, wantMsg) {
t.Errorf("expected message %v; got %v", wantMsg, gotMsg)
}
})
t.Run("Error", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
ctx := context.Background()
sub := NewMocksubscription(mc)
receiver := GroupReceiverImpl{sub: sub}
sub.EXPECT().Next(ctx).Return(nil, errors.New("receive error"))
msg, sender, err := receiver.Receive(ctx)
if err == nil {
t.Error("expected an error; got nil")
}
if sender != "" {
t.Errorf("expected empty sender; got %v", sender)
}
if len(msg) > 0 {
t.Errorf("expected empty message; got %v", msg)
}
})
}
func TestHostV2_GroupReceiver(t *testing.T) {
t.Run("New", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
sub := &libp2p_pubsub.Subscription{}
topic := NewMocktopicHandle(mc)
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
gomock.InOrder(
joiner.EXPECT().JoinTopic("ABC").Return(topic, nil),
topic.EXPECT().Subscribe().Return(sub, nil),
)
gotReceiver, err := host.GroupReceiver("ABC")
if r, ok := gotReceiver.(*GroupReceiverImpl); !ok {
t.Errorf("expected a hostv2 GroupReceiverImpl; got %v", gotReceiver)
} else if r.sub != sub {
t.Errorf("unexpected subscriber %v", r.sub)
}
if err != nil {
t.Errorf("expected no error; got %v", err)
}
})
t.Run("JoinError", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
joiner.EXPECT().JoinTopic("ABC").Return(nil, errors.New("join error"))
gotReceiver, err := host.GroupReceiver("ABC")
if gotReceiver != nil {
t.Errorf("expected a nil hostv2 GroupReceiverImpl; got %v", gotReceiver)
}
if err == nil {
t.Error("expected an error; got none")
}
})
t.Run("SubscribeError", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
topic := NewMocktopicHandle(mc)
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
gomock.InOrder(
joiner.EXPECT().JoinTopic("ABC").Return(topic, nil),
topic.EXPECT().Subscribe().Return(nil, errors.New("subscription error")),
)
gotReceiver, err := host.GroupReceiver("ABC")
if gotReceiver != nil {
t.Errorf("expected a nil hostv2 GroupReceiverImpl; got %v", gotReceiver)
}
if err == nil {
t.Error("expected an error; got none")
}
})
t.Run("Closed", func(t *testing.T) {
var emptyReceiver GroupReceiverImpl
_, _, err := emptyReceiver.Receive(context.Background())
if err == nil {
t.Errorf("Receive() from nil/closed receiver did not return error")
}
})
}
func TestHostV2_getTopic(t *testing.T) {
t.Run("NewOK", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
joiner := NewMocktopicJoiner(mc)
want := NewMocktopicHandle(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
joiner.EXPECT().JoinTopic("ABC").Return(want, nil)
got, err := host.getTopic("ABC")
if err != nil {
t.Errorf("want nil error; got %v", err)
}
if got != want {
t.Errorf("want topic handle %v; got %v", want, got)
}
if _, ok := host.joined["ABC"]; !ok {
t.Error("topic not found in joined map")
}
})
t.Run("NewError", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
joiner := NewMocktopicJoiner(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{}}
joiner.EXPECT().JoinTopic("ABC").Return(nil, errors.New("OMG"))
got, err := host.getTopic("ABC")
if err == nil {
t.Error("want non-nil error; got nil")
}
if got != nil {
t.Errorf("want nil handle; got %v", got)
}
})
t.Run("Existing", func(t *testing.T) {
mc := gomock.NewController(t)
defer mc.Finish()
joiner := NewMocktopicJoiner(mc)
want := NewMocktopicHandle(mc)
host := &HostV2{joiner: joiner, joined: map[string]topicHandle{"ABC": want}}
joiner.EXPECT().JoinTopic("ABC").Times(0)
got, err := host.getTopic("ABC")
if err != nil {
t.Errorf("want nil error; got %v", err)
}
if got != want {
t.Errorf("want topic handle %v; got %v", want, got)
}
})
}

@ -1,162 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: host.go
// Package mock_p2p is a generated GoMock package.
package mock_p2p
import (
gomock "github.com/golang/mock/gomock"
node "github.com/harmony-one/harmony/internal/configs/node"
p2p "github.com/harmony-one/harmony/p2p"
go_libp2p_host "github.com/libp2p/go-libp2p-host"
go_libp2p_peer "github.com/libp2p/go-libp2p-peer"
reflect "reflect"
)
// MockHost is a mock of Host interface
type MockHost struct {
ctrl *gomock.Controller
recorder *MockHostMockRecorder
}
// MockHostMockRecorder is the mock recorder for MockHost
type MockHostMockRecorder struct {
mock *MockHost
}
// NewMockHost creates a new mock instance
func NewMockHost(ctrl *gomock.Controller) *MockHost {
mock := &MockHost{ctrl: ctrl}
mock.recorder = &MockHostMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockHost) EXPECT() *MockHostMockRecorder {
return m.recorder
}
// GetSelfPeer mocks base method
func (m *MockHost) GetSelfPeer() p2p.Peer {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetSelfPeer")
ret0, _ := ret[0].(p2p.Peer)
return ret0
}
// GetSelfPeer indicates an expected call of GetSelfPeer
func (mr *MockHostMockRecorder) GetSelfPeer() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSelfPeer", reflect.TypeOf((*MockHost)(nil).GetSelfPeer))
}
// Close mocks base method
func (m *MockHost) Close() error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close")
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close
func (mr *MockHostMockRecorder) Close() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockHost)(nil).Close))
}
// AddPeer mocks base method
func (m *MockHost) AddPeer(arg0 *p2p.Peer) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddPeer", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// AddPeer indicates an expected call of AddPeer
func (mr *MockHostMockRecorder) AddPeer(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddPeer", reflect.TypeOf((*MockHost)(nil).AddPeer), arg0)
}
// GetID mocks base method
func (m *MockHost) GetID() go_libp2p_peer.ID {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetID")
ret0, _ := ret[0].(go_libp2p_peer.ID)
return ret0
}
// GetID indicates an expected call of GetID
func (mr *MockHostMockRecorder) GetID() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetID", reflect.TypeOf((*MockHost)(nil).GetID))
}
// GetP2PHost mocks base method
func (m *MockHost) GetP2PHost() go_libp2p_host.Host {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetP2PHost")
ret0, _ := ret[0].(go_libp2p_host.Host)
return ret0
}
// GetP2PHost indicates an expected call of GetP2PHost
func (mr *MockHostMockRecorder) GetP2PHost() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetP2PHost", reflect.TypeOf((*MockHost)(nil).GetP2PHost))
}
// GetPeerCount mocks base method
func (m *MockHost) GetPeerCount() int {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetPeerCount")
ret0, _ := ret[0].(int)
return ret0
}
// GetPeerCount indicates an expected call of GetPeerCount
func (mr *MockHostMockRecorder) GetPeerCount() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPeerCount", reflect.TypeOf((*MockHost)(nil).GetPeerCount))
}
// ConnectHostPeer mocks base method
func (m *MockHost) ConnectHostPeer(arg0 p2p.Peer) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "ConnectHostPeer", arg0)
}
// ConnectHostPeer indicates an expected call of ConnectHostPeer
func (mr *MockHostMockRecorder) ConnectHostPeer(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ConnectHostPeer", reflect.TypeOf((*MockHost)(nil).ConnectHostPeer), arg0)
}
// SendMessageToGroups mocks base method
func (m *MockHost) SendMessageToGroups(groups []node.GroupID, msg []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SendMessageToGroups", groups, msg)
ret0, _ := ret[0].(error)
return ret0
}
// SendMessageToGroups indicates an expected call of SendMessageToGroups
func (mr *MockHostMockRecorder) SendMessageToGroups(groups, msg interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMessageToGroups", reflect.TypeOf((*MockHost)(nil).SendMessageToGroups), groups, msg)
}
// GroupReceiver mocks base method
func (m *MockHost) GroupReceiver(arg0 node.GroupID) (p2p.GroupReceiver, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GroupReceiver", arg0)
ret0, _ := ret[0].(p2p.GroupReceiver)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GroupReceiver indicates an expected call of GroupReceiver
func (mr *MockHostMockRecorder) GroupReceiver(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GroupReceiver", reflect.TypeOf((*MockHost)(nil).GroupReceiver), arg0)
}

@ -1,92 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: stream.go
// Package p2p is a generated GoMock package.
package p2p
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
time "time"
)
// MockStream is a mock of Stream interface
type MockStream struct {
ctrl *gomock.Controller
recorder *MockStreamMockRecorder
}
// MockStreamMockRecorder is the mock recorder for MockStream
type MockStreamMockRecorder struct {
mock *MockStream
}
// NewMockStream creates a new mock instance
func NewMockStream(ctrl *gomock.Controller) *MockStream {
mock := &MockStream{ctrl: ctrl}
mock.recorder = &MockStreamMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockStream) EXPECT() *MockStreamMockRecorder {
return m.recorder
}
// Read mocks base method
func (m *MockStream) Read(arg0 []byte) (int, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Read", arg0)
ret0, _ := ret[0].(int)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Read indicates an expected call of Read
func (mr *MockStreamMockRecorder) Read(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Read", reflect.TypeOf((*MockStream)(nil).Read), arg0)
}
// Write mocks base method
func (m *MockStream) Write(arg0 []byte) (int, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Write", arg0)
ret0, _ := ret[0].(int)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Write indicates an expected call of Write
func (mr *MockStreamMockRecorder) Write(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockStream)(nil).Write), arg0)
}
// Close mocks base method
func (m *MockStream) Close() error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close")
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close
func (mr *MockStreamMockRecorder) Close() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockStream)(nil).Close))
}
// SetReadDeadline mocks base method
func (m *MockStream) SetReadDeadline(arg0 time.Time) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetReadDeadline", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// SetReadDeadline indicates an expected call of SetReadDeadline
func (mr *MockStreamMockRecorder) SetReadDeadline(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetReadDeadline", reflect.TypeOf((*MockStream)(nil).SetReadDeadline), arg0)
}

@ -2,8 +2,6 @@ package p2p
import "time" import "time"
//go:generate mockgen -source stream.go -package p2p -destination=mock_stream.go
// Stream is abstract p2p stream from where we read message // Stream is abstract p2p stream from where we read message
type Stream interface { type Stream interface {
Read([]byte) (int, error) Read([]byte) (int, error)

@ -825,7 +825,6 @@ do
-bootnodes "${BN_MA}" -bootnodes "${BN_MA}"
-ip "${PUB_IP}" -ip "${PUB_IP}"
-port "${NODE_PORT}" -port "${NODE_PORT}"
-is_genesis
-network_type="${network_type}" -network_type="${network_type}"
-dns_zone="${dns_zone}" -dns_zone="${dns_zone}"
-blacklist="${blacklist}" -blacklist="${blacklist}"

@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors"
"math/big" "math/big"
"sort" "sort"
"time" "time"
@ -14,8 +13,8 @@ import (
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/pkg/errors"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
"golang.org/x/sync/singleflight" "golang.org/x/sync/singleflight"
) )
@ -332,9 +331,9 @@ func FromLibBLSPublicKeyUnsafe(key *bls.PublicKey) *BLSPublicKey {
func (pk *BLSPublicKey) FromLibBLSPublicKey(key *bls.PublicKey) error { func (pk *BLSPublicKey) FromLibBLSPublicKey(key *bls.PublicKey) error {
bytes := key.Serialize() bytes := key.Serialize()
if len(bytes) != len(pk) { if len(bytes) != len(pk) {
return ctxerror.New("BLS public key size mismatch", return errors.Errorf(
"expected", len(pk), "key size (BLS) size mismatch, expected %d have %d", len(pk), len(bytes),
"actual", len(bytes)) )
} }
copy(pk[:], bytes) copy(pk[:], bytes)
return nil return nil

@ -7,7 +7,6 @@ import (
"github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/block"
"github.com/harmony-one/harmony/core/state" "github.com/harmony-one/harmony/core/state"
bls2 "github.com/harmony-one/harmony/crypto/bls" bls2 "github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -27,23 +26,15 @@ func BlockSigners(
bitmap []byte, parentCommittee *shard.Committee, bitmap []byte, parentCommittee *shard.Committee,
) (shard.SlotList, shard.SlotList, error) { ) (shard.SlotList, shard.SlotList, error) {
committerKeys, err := parentCommittee.BLSPublicKeys() committerKeys, err := parentCommittee.BLSPublicKeys()
if err != nil { if err != nil {
return nil, nil, ctxerror.New( return nil, nil, err
"cannot convert a BLS public key",
).WithCause(err)
} }
mask, err := bls2.NewMask(committerKeys, nil) mask, err := bls2.NewMask(committerKeys, nil)
if err != nil { if err != nil {
return nil, nil, ctxerror.New( return nil, nil, err
"cannot create group sig mask",
).WithCause(err)
} }
if err := mask.SetMask(bitmap); err != nil { if err := mask.SetMask(bitmap); err != nil {
return nil, nil, ctxerror.New( return nil, nil, err
"cannot set group sig mask bits",
).WithCause(err)
} }
payable, missing := shard.SlotList{}, shard.SlotList{} payable, missing := shard.SlotList{}, shard.SlotList{}
@ -51,9 +42,7 @@ func BlockSigners(
for idx, member := range parentCommittee.Slots { for idx, member := range parentCommittee.Slots {
switch signed, err := mask.IndexEnabled(idx); true { switch signed, err := mask.IndexEnabled(idx); true {
case err != nil: case err != nil:
return nil, nil, ctxerror.New("cannot check for committer bit", return nil, nil, err
"committerIndex", idx,
).WithCause(err)
case signed: case signed:
payable = append(payable, member) payable = append(payable, member)
default: default:
@ -71,10 +60,10 @@ func BallotResult(
parentCommittee, err := parentShardState.FindCommitteeByID(shardID) parentCommittee, err := parentShardState.FindCommitteeByID(shardID)
if err != nil { if err != nil {
return nil, nil, nil, ctxerror.New( return nil, nil, nil, errors.Errorf(
"cannot find shard in the shard state", "cannot find shard in the shard state %d %d",
"parentBlockNumber", parentHeader.Number(), parentHeader.Number(),
"shardID", parentHeader.ShardID(), parentHeader.ShardID(),
) )
} }
@ -235,14 +224,14 @@ func ComputeAndMutateEPOSStatus(
Str("threshold", measure.String()). Str("threshold", measure.String()).
Msg("validator failed availability threshold, set to inactive") Msg("validator failed availability threshold, set to inactive")
default: default:
// Default is no-op so validator who wants to leave the committee can actually leave. // Default is no-op so validator who wants
// to leave the committee can actually leave.
} }
if err := state.UpdateValidatorWrapper( if err := state.UpdateValidatorWrapper(
addr, wrapper, addr, wrapper,
); err != nil { ); err != nil {
const msg = "[ComputeAndMutateEPOSStatus] failed update validator info" return err
return ctxerror.New(msg).WithCause(err)
} }
return nil return nil

@ -11,7 +11,6 @@ import (
"github.com/harmony-one/harmony/consensus/votepower" "github.com/harmony-one/harmony/consensus/votepower"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/internal/genesis" "github.com/harmony-one/harmony/internal/genesis"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
@ -411,33 +410,28 @@ func UpdateDescription(d1, d2 Description) (Description, error) {
// EnsureLength ensures the length of a validator's description. // EnsureLength ensures the length of a validator's description.
func (d Description) EnsureLength() (Description, error) { func (d Description) EnsureLength() (Description, error) {
if len(d.Name) > MaxNameLength { if len(d.Name) > MaxNameLength {
return d, ctxerror.New( return d, errors.Errorf(
"[EnsureLength] Exceed Maximum Length", "have", "exceed maximum name length %d %d", len(d.Name), MaxNameLength,
len(d.Name), "maxNameLen", MaxNameLength,
) )
} }
if len(d.Identity) > MaxIdentityLength { if len(d.Identity) > MaxIdentityLength {
return d, ctxerror.New( return d, errors.Errorf(
"[EnsureLength] Exceed Maximum Length", "have", "exceed Maximum Length identity %d %d", len(d.Identity), MaxIdentityLength,
len(d.Identity), "maxIdentityLen", MaxIdentityLength,
) )
} }
if len(d.Website) > MaxWebsiteLength { if len(d.Website) > MaxWebsiteLength {
return d, ctxerror.New( return d, errors.Errorf(
"[EnsureLength] Exceed Maximum Length", "have", len(d.Website), "exceed Maximum Length website %d %d", len(d.Website), MaxWebsiteLength,
"maxWebsiteLen", MaxWebsiteLength,
) )
} }
if len(d.SecurityContact) > MaxSecurityContactLength { if len(d.SecurityContact) > MaxSecurityContactLength {
return d, ctxerror.New( return d, errors.Errorf(
"[EnsureLength] Exceed Maximum Length", "have", "exceed Maximum Length %d %d", len(d.SecurityContact), MaxSecurityContactLength,
len(d.SecurityContact), "maxSecurityContactLen", MaxSecurityContactLength,
) )
} }
if len(d.Details) > MaxDetailsLength { if len(d.Details) > MaxDetailsLength {
return d, ctxerror.New( return d, errors.Errorf(
"[EnsureLength] Exceed Maximum Length", "have", len(d.Details), "exceed Maximum Length for details %d %d", len(d.Details), MaxDetailsLength,
"maxDetailsLen", MaxDetailsLength,
) )
} }

@ -10,7 +10,6 @@ import (
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/crypto/hash" "github.com/harmony-one/harmony/crypto/hash"
common2 "github.com/harmony-one/harmony/internal/common" common2 "github.com/harmony-one/harmony/internal/common"
"github.com/harmony-one/harmony/internal/ctxerror"
"github.com/harmony-one/harmony/numeric" "github.com/harmony-one/harmony/numeric"
"github.com/harmony-one/harmony/shard" "github.com/harmony-one/harmony/shard"
"github.com/harmony-one/harmony/staking/effective" "github.com/harmony-one/harmony/staking/effective"
@ -278,64 +277,11 @@ func TestValidatorSanityCheck(t *testing.T) {
} }
} }
func TestValidatorWrapperSanityCheck(t *testing.T) {
// no delegation must fail
wrapper := createNewValidatorWrapper(createNewValidator())
if err := wrapper.SanityCheck(DoNotEnforceMaxBLS); err == nil {
t.Error("expected", ErrInvalidSelfDelegation, "got", err)
}
// valid self delegation must not fail
wrapper.Validator.MaxTotalDelegation = tenK
valDel := NewDelegation(validatorAddr, tenK)
wrapper.Delegations = []Delegation{valDel}
if err := wrapper.SanityCheck(DoNotEnforceMaxBLS); err != nil {
t.Errorf("validator wrapper SanityCheck failed: %s", err)
}
// invalid self delegation must fail
valDel = NewDelegation(validatorAddr, big.NewInt(1e18))
wrapper.Delegations = []Delegation{valDel}
if err := wrapper.SanityCheck(DoNotEnforceMaxBLS); err == nil {
t.Error("expected", ErrInvalidSelfDelegation, "got", err)
}
// invalid self delegation of less than 10K ONE must fail
valDel = NewDelegation(validatorAddr, big.NewInt(1e18))
if err := wrapper.SanityCheck(DoNotEnforceMaxBLS); err == nil {
t.Error("expected", ErrInvalidSelfDelegation, "got", err)
}
}
func testEnsureLength(t *testing.T) {
// test name length > MaxNameLength
if _, err := longNameDesc.EnsureLength(); err == nil {
t.Error("expected", ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(longNameDesc.Name), "maxNameLen", MaxNameLength), "got", err)
}
// test identity length > MaxIdentityLength
if _, err := longIdentityDesc.EnsureLength(); err == nil {
t.Error("expected", ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(longIdentityDesc.Identity), "maxIdentityLen", MaxIdentityLength), "got", err)
}
// test website length > MaxWebsiteLength
if _, err := longWebsiteDesc.EnsureLength(); err == nil {
t.Error("expected", ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(longWebsiteDesc.Website), "maxWebsiteLen", MaxWebsiteLength), "got", err)
}
// test security contact length > MaxSecurityContactLength
if _, err := longSecurityContactDesc.EnsureLength(); err == nil {
t.Error("expected", ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(longSecurityContactDesc.SecurityContact), "maxSecurityContactLen", MaxSecurityContactLength), "got", err)
}
// test details length > MaxDetailsLength
if _, err := longDetailsDesc.EnsureLength(); err == nil {
t.Error("expected", ctxerror.New("[EnsureLength] Exceed Maximum Length", "have", len(longDetailsDesc.Details), "maxDetailsLen", MaxDetailsLength), "got", err)
}
}
func TestEnsureLength(t *testing.T) { func TestEnsureLength(t *testing.T) {
_, err := validator.Description.EnsureLength() _, err := validator.Description.EnsureLength()
if err != nil { if err != nil {
t.Error("expected", "nil", "got", err) t.Error("expected", "nil", "got", err)
} }
testEnsureLength(t)
} }
func TestUpdateDescription(t *testing.T) { func TestUpdateDescription(t *testing.T) {

Loading…
Cancel
Save