Break tie of core-consensus-core import cycle; add pRnd channel for consensus

pull/442/head
Rongjian Lan 6 years ago
parent e9732bc3ff
commit 8fae634aba
  1. 1
      cmd/harmony.go
  2. 33
      consensus/consensus.go
  3. 15
      consensus/consensus_leader.go
  4. 3
      consensus/consensus_validator.go
  5. 2
      consensus/engine/consensus_engine.go
  6. 2
      consensus/engine/errors.go
  7. 10
      core/block_validator.go
  8. 32
      core/blockchain.go
  9. 12
      core/chain_makers.go
  10. 4
      core/evm.go
  11. 10
      core/headerchain.go
  12. 6
      core/state_processor.go
  13. 5
      drand/drand.go
  14. 14
      drand/drand_leader.go
  15. 6
      node/worker/worker.go

@ -266,6 +266,7 @@ func main() {
// TODO: enable drand only for beacon chain // TODO: enable drand only for beacon chain
// TODO: put this in a better place other than main. // TODO: put this in a better place other than main.
dRand := drand.New(host, shardID, peers, leader, currentNode.ConfirmedBlockChannel) dRand := drand.New(host, shardID, peers, leader, currentNode.ConfirmedBlockChannel)
currentNode.Consensus.RegisterPRndChannel(dRand.PRndChannel)
currentNode.DRand = dRand currentNode.DRand = dRand
// If there is a client configured in the node list. // If there is a client configured in the node list.

@ -18,6 +18,7 @@ import (
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
consensus_proto "github.com/harmony-one/harmony/api/consensus" consensus_proto "github.com/harmony-one/harmony/api/consensus"
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"
bls_cosi "github.com/harmony-one/harmony/crypto/bls" bls_cosi "github.com/harmony-one/harmony/crypto/bls"
@ -96,6 +97,9 @@ type Consensus struct {
// verified block to state sync broadcast // verified block to state sync broadcast
VerifiedNewBlock chan *types.Block VerifiedNewBlock chan *types.Block
// Channel for DRG protocol to send pRnd (preimage of randomness resulting from combined vrf randomnesses) to consensus. The first 32 bytes are randomness, the rest is for bitmap.
PRndChannel chan []byte
uniqueIDInstance *utils.UniqueValidatorID uniqueIDInstance *utils.UniqueValidatorID
// The p2p host used to send/receive p2p messages // The p2p host used to send/receive p2p messages
@ -213,6 +217,11 @@ func New(host p2p.Host, ShardID string, peers []p2p.Peer, leader p2p.Peer) *Cons
return &consensus return &consensus
} }
// RegisterPRndChannel registers the channel for receiving randomness preimage from DRG protocol
func (consensus *Consensus) RegisterPRndChannel(pRndChannel chan []byte) {
consensus.PRndChannel = pRndChannel
}
// Checks the basic meta of a consensus message, including the signature. // Checks the basic meta of a consensus message, including the signature.
func (consensus *Consensus) checkConsensusMessage(message consensus_proto.Message, publicKey *bls.PublicKey) error { func (consensus *Consensus) checkConsensusMessage(message consensus_proto.Message, publicKey *bls.PublicKey) error {
consensusID := message.ConsensusId consensusID := message.ConsensusId
@ -222,18 +231,18 @@ func (consensus *Consensus) checkConsensusMessage(message consensus_proto.Messag
err := verifyMessageSig(publicKey, message) err := verifyMessageSig(publicKey, message)
if err != nil { if err != nil {
utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err) utils.GetLogInstance().Warn("Failed to verify the message signature", "Error", err)
return ErrInvalidConsensusMessage return consensus_engine.ErrInvalidConsensusMessage
} }
// check consensus Id // check consensus Id
if consensusID != consensus.consensusID { if consensusID != consensus.consensusID {
utils.GetLogInstance().Warn("Wrong consensus Id", "myConsensusId", consensus.consensusID, "theirConsensusId", consensusID, "consensus", consensus) utils.GetLogInstance().Warn("Wrong consensus Id", "myConsensusId", consensus.consensusID, "theirConsensusId", consensusID, "consensus", consensus)
return ErrConsensusIDNotMatch return consensus_engine.ErrConsensusIDNotMatch
} }
if !bytes.Equal(blockHash, consensus.blockHash[:]) { if !bytes.Equal(blockHash, consensus.blockHash[:]) {
utils.GetLogInstance().Warn("Wrong blockHash", "consensus", consensus) utils.GetLogInstance().Warn("Wrong blockHash", "consensus", consensus)
return ErrInvalidConsensusMessage return consensus_engine.ErrInvalidConsensusMessage
} }
return nil return nil
} }
@ -479,7 +488,7 @@ func NewFaker() *Consensus {
// VerifyHeader checks whether a header conforms to the consensus rules of the // VerifyHeader checks whether a header conforms to the consensus rules of the
// stock bft engine. // stock bft engine.
func (consensus *Consensus) VerifyHeader(chain ChainReader, header *types.Header, seal bool) error { func (consensus *Consensus) VerifyHeader(chain consensus_engine.ChainReader, header *types.Header, seal bool) error {
// TODO: implement this // TODO: implement this
return nil return nil
} }
@ -487,7 +496,7 @@ func (consensus *Consensus) VerifyHeader(chain ChainReader, header *types.Header
// VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers // VerifyHeaders is similar to VerifyHeader, but verifies a batch of headers
// concurrently. The method returns a quit channel to abort the operations and // concurrently. The method returns a quit channel to abort the operations and
// a results channel to retrieve the async verifications. // a results channel to retrieve the async verifications.
func (consensus *Consensus) VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) { func (consensus *Consensus) VerifyHeaders(chain consensus_engine.ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error) {
abort, results := make(chan struct{}), make(chan error, len(headers)) abort, results := make(chan struct{}), make(chan error, len(headers))
for i := 0; i < len(headers); i++ { for i := 0; i < len(headers); i++ {
results <- nil results <- nil
@ -495,7 +504,7 @@ func (consensus *Consensus) VerifyHeaders(chain ChainReader, headers []*types.He
return abort, results return abort, results
} }
func (consensus *Consensus) verifyHeaderWorker(chain ChainReader, headers []*types.Header, seals []bool, index int) error { func (consensus *Consensus) verifyHeaderWorker(chain consensus_engine.ChainReader, headers []*types.Header, seals []bool, index int) error {
var parent *types.Header var parent *types.Header
if index == 0 { if index == 0 {
parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1) parent = chain.GetHeader(headers[0].ParentHash, headers[0].Number.Uint64()-1)
@ -503,7 +512,7 @@ func (consensus *Consensus) verifyHeaderWorker(chain ChainReader, headers []*typ
parent = headers[index-1] parent = headers[index-1]
} }
if parent == nil { if parent == nil {
return ErrUnknownAncestor return consensus_engine.ErrUnknownAncestor
} }
if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil { if chain.GetHeader(headers[index].Hash(), headers[index].Number.Uint64()) != nil {
return nil // known block return nil // known block
@ -513,19 +522,19 @@ func (consensus *Consensus) verifyHeaderWorker(chain ChainReader, headers []*typ
// verifyHeader checks whether a header conforms to the consensus rules of the // verifyHeader checks whether a header conforms to the consensus rules of the
// stock bft engine. // stock bft engine.
func (consensus *Consensus) verifyHeader(chain ChainReader, header, parent *types.Header, uncle bool, seal bool) error { func (consensus *Consensus) verifyHeader(chain consensus_engine.ChainReader, header, parent *types.Header, uncle bool, seal bool) error {
return nil return nil
} }
// VerifySeal implements consensus.Engine, checking whether the given block satisfies // VerifySeal implements consensus.Engine, checking whether the given block satisfies
// the PoW difficulty requirements. // the PoW difficulty requirements.
func (consensus *Consensus) VerifySeal(chain ChainReader, header *types.Header) error { func (consensus *Consensus) VerifySeal(chain consensus_engine.ChainReader, header *types.Header) error {
return nil return nil
} }
// Finalize implements consensus.Engine, accumulating the block and uncle rewards, // Finalize implements consensus.Engine, accumulating the block and uncle rewards,
// setting the final state and assembling the block. // setting the final state and assembling the block.
func (consensus *Consensus) Finalize(chain ChainReader, header *types.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt) (*types.Block, error) { func (consensus *Consensus) Finalize(chain consensus_engine.ChainReader, header *types.Header, state *state.DB, txs []*types.Transaction, receipts []*types.Receipt) (*types.Block, error) {
// Accumulate any block and uncle rewards and commit the final state root // Accumulate any block and uncle rewards and commit the final state root
// Header seems complete, assemble into a block and return // Header seems complete, assemble into a block and return
accumulateRewards(chain.Config(), state, header) accumulateRewards(chain.Config(), state, header)
@ -556,14 +565,14 @@ func (consensus *Consensus) SealHash(header *types.Header) (hash common.Hash) {
} }
// Seal is to seal final block. // Seal is to seal final block.
func (consensus *Consensus) Seal(chain ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error { func (consensus *Consensus) Seal(chain consensus_engine.ChainReader, block *types.Block, results chan<- *types.Block, stop <-chan struct{}) error {
// TODO: implement final block sealing // TODO: implement final block sealing
return nil return nil
} }
// Prepare is to prepare ... // Prepare is to prepare ...
// TODO(RJ): fix it. // TODO(RJ): fix it.
func (consensus *Consensus) Prepare(chain ChainReader, header *types.Header) error { func (consensus *Consensus) Prepare(chain consensus_engine.ChainReader, header *types.Header) error {
// TODO: implement prepare method // TODO: implement prepare method
return nil return nil
} }

@ -5,6 +5,8 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/harmony-one/harmony/core"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
"github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/bls/ffi/go/bls"
@ -47,6 +49,19 @@ func (consensus *Consensus) WaitForNewBlock(blockChannel chan *types.Block, stop
time.Sleep(waitForEnoughValidators * time.Millisecond) time.Sleep(waitForEnoughValidators * time.Millisecond)
} }
if core.IsEpochBlock(newBlock) {
// Receive pRnd from DRG protocol
utils.GetLogInstance().Debug("[DRG] Waiting for pRnd")
pRndAndBitmap := <-consensus.PRndChannel
utils.GetLogInstance().Debug("[DRG] GOT pRnd", "pRnd", pRndAndBitmap)
pRnd := pRndAndBitmap[:32]
bitmap := pRndAndBitmap[32:]
vrfBitmap, _ := bls_cosi.NewMask(consensus.PublicKeys, consensus.leader.PubKey)
vrfBitmap.SetMask(bitmap)
// TODO: check validity of pRnd
_ = pRnd
}
startTime = time.Now() startTime = time.Now()
utils.GetLogInstance().Debug("STARTING CONSENSUS", "numTxs", len(newBlock.Transactions()), "consensus", consensus, "startTime", startTime, "publicKeys", len(consensus.PublicKeys)) utils.GetLogInstance().Debug("STARTING CONSENSUS", "numTxs", len(newBlock.Transactions()), "consensus", consensus, "startTime", startTime, "publicKeys", len(consensus.PublicKeys))
for { // Wait until last consensus is finished for { // Wait until last consensus is finished

@ -7,6 +7,7 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
protobuf "github.com/golang/protobuf/proto" protobuf "github.com/golang/protobuf/proto"
consensus_proto "github.com/harmony-one/harmony/api/consensus" consensus_proto "github.com/harmony-one/harmony/api/consensus"
consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
"github.com/harmony-one/harmony/internal/attack" "github.com/harmony-one/harmony/internal/attack"
"github.com/harmony-one/harmony/internal/utils" "github.com/harmony-one/harmony/internal/utils"
@ -74,7 +75,7 @@ func (consensus *Consensus) processAnnounceMessage(message consensus_proto.Messa
if err := consensus.checkConsensusMessage(message, consensus.leader.PubKey); err != nil { if err := consensus.checkConsensusMessage(message, consensus.leader.PubKey); err != nil {
utils.GetLogInstance().Debug("Failed to check the leader message") utils.GetLogInstance().Debug("Failed to check the leader message")
if err == ErrConsensusIDNotMatch { if err == consensus_engine.ErrConsensusIDNotMatch {
utils.GetLogInstance().Debug("sending bft block to state syncing") utils.GetLogInstance().Debug("sending bft block to state syncing")
consensus.sendBFTBlockToStateSyncing(consensusID) consensus.sendBFTBlockToStateSyncing(consensusID)
} }

@ -1,4 +1,4 @@
package consensus package engine
import ( import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"

@ -14,7 +14,7 @@
// You should have received a copy of the GNU Lesser General Public License // You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package consensus package engine
import "errors" import "errors"

@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/consensus" 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"
) )
@ -32,11 +32,11 @@ import (
type BlockValidator struct { type BlockValidator struct {
config *params.ChainConfig // Chain configuration options config *params.ChainConfig // Chain configuration options
bc *BlockChain // Canonical block chain bc *BlockChain // Canonical block chain
engine consensus.Engine // Consensus engine used for validating engine consensus_engine.Engine // Consensus engine used for validating
} }
// NewBlockValidator returns a new block validator which is safe for re-use // NewBlockValidator returns a new block validator which is safe for re-use
func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus.Engine) *BlockValidator { func NewBlockValidator(config *params.ChainConfig, blockchain *BlockChain, engine consensus_engine.Engine) *BlockValidator {
validator := &BlockValidator{ validator := &BlockValidator{
config: config, config: config,
engine: engine, engine: engine,
@ -55,9 +55,9 @@ func (v *BlockValidator) ValidateBody(block *types.Block) error {
} }
if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) { if !v.bc.HasBlockAndState(block.ParentHash(), block.NumberU64()-1) {
if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) { if !v.bc.HasBlock(block.ParentHash(), block.NumberU64()-1) {
return consensus.ErrUnknownAncestor return consensus_engine.ErrUnknownAncestor
} }
return consensus.ErrPrunedAncestor return consensus_engine.ErrPrunedAncestor
} }
// Header validity is known at this point, check the uncles and transactions // Header validity is known at this point, check the uncles and transactions
header := block.Header() header := block.Header()

@ -38,7 +38,7 @@ import (
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/harmony-one/harmony/consensus" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/rawdb"
"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"
@ -135,7 +135,7 @@ type BlockChain struct {
procInterrupt int32 // interrupt signaler for block processing procInterrupt int32 // interrupt signaler for block processing
wg sync.WaitGroup // chain processing wait group for shutting down wg sync.WaitGroup // chain processing wait group for shutting down
engine consensus.Engine engine consensus_engine.Engine
processor Processor // block processor interface processor Processor // block processor interface
validator Validator // block and state validator interface validator Validator // block and state validator interface
vmConfig vm.Config vmConfig vm.Config
@ -147,7 +147,7 @@ type BlockChain struct {
// NewBlockChain returns a fully initialised block chain using information // NewBlockChain returns a fully initialised block chain using information
// available in the database. It initialises the default Ethereum Validator and // available in the database. It initialises the default Ethereum Validator and
// Processor. // Processor.
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool) (*BlockChain, error) { func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus_engine.Engine, vmConfig vm.Config, shouldPreserve func(block *types.Block) bool) (*BlockChain, error) {
if cacheConfig == nil { if cacheConfig == nil {
cacheConfig = &CacheConfig{ cacheConfig = &CacheConfig{
TrieNodeLimit: 256 * 1024 * 1024, TrieNodeLimit: 256 * 1024 * 1024,
@ -223,6 +223,22 @@ func (bc *BlockChain) ValidateNewBlock(block *types.Block, address common.Addres
return nil return nil
} }
// IsEpochBlock returns whether this block is the first block of an epoch.
func IsEpochBlock(block *types.Block) bool {
if block.NumberU64()%BlocksPerEpoch == 0 {
return true
}
return false
}
// IsEpochLastBlock returns whether this block is the last block of an epoch.
func IsEpochLastBlock(block *types.Block) bool {
if block.NumberU64()%BlocksPerEpoch == BlocksPerEpoch-1 {
return true
}
return false
}
func (bc *BlockChain) getProcInterrupt() bool { func (bc *BlockChain) getProcInterrupt() bool {
return atomic.LoadInt32(&bc.procInterrupt) == 1 return atomic.LoadInt32(&bc.procInterrupt) == 1
} }
@ -931,7 +947,7 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
// Calculate the total difficulty of the block // Calculate the total difficulty of the block
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1) ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
if ptd == nil { if ptd == nil {
return NonStatTy, consensus.ErrUnknownAncestor return NonStatTy, consensus_engine.ErrUnknownAncestor
} }
// Make sure no inconsistent state is leaked during insertion // Make sure no inconsistent state is leaked during insertion
bc.mu.Lock() bc.mu.Lock()
@ -1135,7 +1151,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
continue continue
} }
case err == consensus.ErrFutureBlock: case err == consensus_engine.ErrFutureBlock:
// Allow up to MaxFuture second in the future blocks. If this limit is exceeded // Allow up to MaxFuture second in the future blocks. If this limit is exceeded
// the chain is discarded and processed at a later time if given. // the chain is discarded and processed at a later time if given.
max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks) max := big.NewInt(time.Now().Unix() + maxTimeFutureBlocks)
@ -1146,12 +1162,12 @@ func (bc *BlockChain) insertChain(chain types.Blocks) (int, []interface{}, []*ty
stats.queued++ stats.queued++
continue continue
case err == consensus.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()): case err == consensus_engine.ErrUnknownAncestor && bc.futureBlocks.Contains(block.ParentHash()):
bc.futureBlocks.Add(block.Hash(), block) bc.futureBlocks.Add(block.Hash(), block)
stats.queued++ stats.queued++
continue continue
case err == consensus.ErrPrunedAncestor: case err == consensus_engine.ErrPrunedAncestor:
// Block competing with the canonical chain, store in the db, but don't process // Block competing with the canonical chain, store in the db, but don't process
// until the competitor TD goes above the canonical TD // until the competitor TD goes above the canonical TD
currentBlock := bc.CurrentBlock() currentBlock := bc.CurrentBlock()
@ -1611,7 +1627,7 @@ func (bc *BlockChain) GetHeaderByNumber(number uint64) *types.Header {
func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig } func (bc *BlockChain) Config() *params.ChainConfig { return bc.chainConfig }
// Engine retrieves the blockchain's consensus engine. // Engine retrieves the blockchain's consensus engine.
func (bc *BlockChain) Engine() consensus.Engine { return bc.engine } func (bc *BlockChain) Engine() consensus_engine.Engine { return bc.engine }
// SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent. // SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription { func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {

@ -23,7 +23,7 @@ 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/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/consensus" 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/core/vm" "github.com/harmony-one/harmony/core/vm"
@ -44,7 +44,7 @@ type BlockGen struct {
uncles []*types.Header uncles []*types.Header
config *params.ChainConfig config *params.ChainConfig
engine consensus.Engine engine consensus_engine.Engine
} }
// SetCoinbase sets the coinbase of the generated block. // SetCoinbase sets the coinbase of the generated block.
@ -161,7 +161,7 @@ func (b *BlockGen) PrevBlock(index int) *types.Block {
// Blocks created by GenerateChain do not contain valid proof of work // Blocks created by GenerateChain do not contain valid proof of work
// values. Inserting them into BlockChain requires use of FakePow or // values. Inserting them into BlockChain requires use of FakePow or
// a similar non-validating proof of work implementation. // a similar non-validating proof of work implementation.
func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) { func GenerateChain(config *params.ChainConfig, parent *types.Block, engine consensus_engine.Engine, db ethdb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts) {
if config == nil { if config == nil {
config = params.TestChainConfig config = params.TestChainConfig
} }
@ -216,7 +216,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
return blocks, receipts return blocks, receipts
} }
func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.DB, engine consensus.Engine) *types.Header { func makeHeader(chain consensus_engine.ChainReader, parent *types.Block, state *state.DB, engine consensus_engine.Engine) *types.Header {
var time *big.Int var time *big.Int
if parent.Time() == nil { if parent.Time() == nil {
time = big.NewInt(10) time = big.NewInt(10)
@ -241,7 +241,7 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.D
} }
// makeHeaderChain creates a deterministic chain of headers rooted at parent. // makeHeaderChain creates a deterministic chain of headers rooted at parent.
func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Header { func makeHeaderChain(parent *types.Header, n int, engine consensus_engine.Engine, db ethdb.Database, seed int) []*types.Header {
blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed) blocks := makeBlockChain(types.NewBlockWithHeader(parent), n, engine, db, seed)
headers := make([]*types.Header, len(blocks)) headers := make([]*types.Header, len(blocks))
for i, block := range blocks { for i, block := range blocks {
@ -251,7 +251,7 @@ func makeHeaderChain(parent *types.Header, n int, engine consensus.Engine, db et
} }
// makeBlockChain creates a deterministic chain of blocks rooted at parent. // makeBlockChain creates a deterministic chain of blocks rooted at parent.
func makeBlockChain(parent *types.Block, n int, engine consensus.Engine, db ethdb.Database, seed int) []*types.Block { func makeBlockChain(parent *types.Block, n int, engine consensus_engine.Engine, db ethdb.Database, seed int) []*types.Block {
blocks, _ := GenerateChain(params.TestChainConfig, parent, engine, db, n, func(i int, b *BlockGen) { blocks, _ := GenerateChain(params.TestChainConfig, parent, engine, db, n, func(i int, b *BlockGen) {
b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)}) b.SetCoinbase(common.Address{0: byte(seed), 19: byte(i)})
}) })

@ -20,7 +20,7 @@ import (
"math/big" "math/big"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/consensus" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"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"
) )
@ -29,7 +29,7 @@ import (
// current blockchain to be used during transaction processing. // current blockchain to be used during transaction processing.
type ChainContext interface { type ChainContext interface {
// Engine retrieves the chain's consensus engine. // Engine retrieves the chain's consensus engine.
Engine() consensus.Engine Engine() consensus_engine.Engine
// GetHeader returns the hash corresponding to their hash. // GetHeader returns the hash corresponding to their hash.
GetHeader(common.Hash, uint64) *types.Header GetHeader(common.Hash, uint64) *types.Header

@ -30,7 +30,7 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/consensus" consensus_engine "github.com/harmony-one/harmony/consensus/engine"
"github.com/harmony-one/harmony/core/rawdb" "github.com/harmony-one/harmony/core/rawdb"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
lru "github.com/hashicorp/golang-lru" lru "github.com/hashicorp/golang-lru"
@ -63,14 +63,14 @@ type HeaderChain struct {
procInterrupt func() bool procInterrupt func() bool
rand *mrand.Rand rand *mrand.Rand
engine consensus.Engine engine consensus_engine.Engine
} }
// NewHeaderChain creates a new HeaderChain structure. // NewHeaderChain creates a new HeaderChain structure.
// getValidator should return the parent's validator // getValidator should return the parent's validator
// procInterrupt points to the parent's interrupt semaphore // procInterrupt points to the parent's interrupt semaphore
// wg points to the parent's shutdown wait group // wg points to the parent's shutdown wait group
func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus.Engine, procInterrupt func() bool) (*HeaderChain, error) { func NewHeaderChain(chainDb ethdb.Database, config *params.ChainConfig, engine consensus_engine.Engine, procInterrupt func() bool) (*HeaderChain, error) {
headerCache, _ := lru.New(headerCacheLimit) headerCache, _ := lru.New(headerCacheLimit)
tdCache, _ := lru.New(tdCacheLimit) tdCache, _ := lru.New(tdCacheLimit)
numberCache, _ := lru.New(numberCacheLimit) numberCache, _ := lru.New(numberCacheLimit)
@ -140,7 +140,7 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
// Calculate the total difficulty of the header // Calculate the total difficulty of the header
ptd := hc.GetTd(header.ParentHash, number-1) ptd := hc.GetTd(header.ParentHash, number-1)
if ptd == nil { if ptd == nil {
return NonStatTy, consensus.ErrUnknownAncestor return NonStatTy, consensus_engine.ErrUnknownAncestor
} }
localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64()) localTd := hc.GetTd(hc.currentHeaderHash, hc.CurrentHeader().Number.Uint64())
externTd := new(big.Int).Add(header.Difficulty, ptd) externTd := new(big.Int).Add(header.Difficulty, ptd)
@ -498,7 +498,7 @@ func (hc *HeaderChain) SetGenesis(head *types.Header) {
func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config } func (hc *HeaderChain) Config() *params.ChainConfig { return hc.config }
// Engine retrieves the header chain's consensus engine. // Engine retrieves the header chain's consensus engine.
func (hc *HeaderChain) Engine() consensus.Engine { return hc.engine } func (hc *HeaderChain) Engine() consensus_engine.Engine { return hc.engine }
// GetBlock implements consensus.ChainReader, and returns nil for every input as // GetBlock implements consensus.ChainReader, and returns nil for every input as
// a header chain does not have blocks available for retrieval. // a header chain does not have blocks available for retrieval.

@ -20,7 +20,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/consensus" 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/core/vm" "github.com/harmony-one/harmony/core/vm"
@ -33,11 +33,11 @@ import (
type StateProcessor struct { type StateProcessor struct {
config *params.ChainConfig // Chain configuration options config *params.ChainConfig // Chain configuration options
bc *BlockChain // Canonical block chain bc *BlockChain // Canonical block chain
engine consensus.Engine // Consensus engine used for block rewards engine consensus_engine.Engine // Consensus engine used for block rewards
} }
// NewStateProcessor initialises a new StateProcessor. // NewStateProcessor initialises a new StateProcessor.
func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus.Engine) *StateProcessor { func NewStateProcessor(config *params.ChainConfig, bc *BlockChain, engine consensus_engine.Engine) *StateProcessor {
return &StateProcessor{ return &StateProcessor{
config: config, config: config,
bc: bc, bc: bc,

@ -23,7 +23,8 @@ type DRand struct {
bitmap *bls_cosi.Mask bitmap *bls_cosi.Mask
pRand *[32]byte pRand *[32]byte
rand *[32]byte rand *[32]byte
ConfirmedBlockChannel chan *types.Block // Channel for confirmed blocks ConfirmedBlockChannel chan *types.Block // Channel to receive confirmed blocks
PRndChannel chan []byte // Channel to send pRnd (preimage of randomness resulting from combined vrf randomnesses) to consensus. The first 32 bytes are randomness, the rest is for bitmap.
// map of nodeID to validator Peer object // map of nodeID to validator Peer object
// FIXME: should use PubKey of p2p.Peer as the hashkey // FIXME: should use PubKey of p2p.Peer as the hashkey
@ -65,6 +66,8 @@ func New(host p2p.Host, ShardID string, peers []p2p.Peer, leader p2p.Peer, confi
dRand.ConfirmedBlockChannel = confirmedBlockChannel dRand.ConfirmedBlockChannel = confirmedBlockChannel
} }
dRand.PRndChannel = make(chan []byte)
selfPeer := host.GetSelfPeer() selfPeer := host.GetSelfPeer()
if leader.Port == selfPeer.Port && leader.IP == selfPeer.IP { if leader.Port == selfPeer.Port && leader.IP == selfPeer.IP {
dRand.IsLeader = true dRand.IsLeader = true

@ -18,10 +18,9 @@ func (dRand *DRand) WaitForEpochBlock(blockChannel chan *types.Block, stopChan c
default: default:
// keep waiting for epoch block // keep waiting for epoch block
newBlock := <-blockChannel newBlock := <-blockChannel
if newBlock.NumberU64()%core.BlocksPerEpoch == 0 { if core.IsEpochLastBlock(newBlock) {
}
dRand.init(newBlock) dRand.init(newBlock)
}
case <-stopChan: case <-stopChan:
return return
} }
@ -100,5 +99,14 @@ func (dRand *DRand) processCommitMessage(message drand_proto.Message) {
// Construct pRand and initiate consensus on it // Construct pRand and initiate consensus on it
utils.GetLogInstance().Debug("Received enough randomness commit", "numReceivedSoFar", len((*vrfs)), "validatorID", validatorID, "PublicKeys", len(dRand.PublicKeys)) utils.GetLogInstance().Debug("Received enough randomness commit", "numReceivedSoFar", len((*vrfs)), "validatorID", validatorID, "PublicKeys", len(dRand.PublicKeys))
// TODO: communicate the pRand to consensus // TODO: communicate the pRand to consensus
pRnd := [32]byte{}
// Bitwise XOR on all the submitted vrfs
for _, vrf := range *vrfs {
for i := 0; i < len(pRnd); i++ {
pRnd[i] = pRnd[i] ^ vrf[i]
}
}
dRand.PRndChannel <- append(pRnd[:], dRand.bitmap.Bitmap...)
} }
} }

@ -8,7 +8,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/consensus" 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/state" "github.com/harmony-one/harmony/core/state"
"github.com/harmony-one/harmony/core/types" "github.com/harmony-one/harmony/core/types"
@ -33,7 +33,7 @@ type Worker struct {
current *environment // An environment for current running cycle. current *environment // An environment for current running cycle.
coinbase common.Address coinbase common.Address
engine consensus.Engine engine consensus_engine.Engine
gasFloor uint64 gasFloor uint64
gasCeil uint64 gasCeil uint64
@ -156,7 +156,7 @@ func (w *Worker) Commit() (*types.Block, error) {
} }
// New create a new worker object. // New create a new worker object.
func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus.Engine, coinbase common.Address, shardID uint32) *Worker { func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus_engine.Engine, coinbase common.Address, shardID uint32) *Worker {
worker := &Worker{ worker := &Worker{
config: config, config: config,
chain: chain, chain: chain,

Loading…
Cancel
Save