From 852ac7446757293096827000fca8e44d022d185e Mon Sep 17 00:00:00 2001 From: Joel Burget Date: Thu, 4 May 2017 16:49:48 -0400 Subject: [PATCH] Raft updates (#104) * Move raft checkpoint logging to logger package. This allows us to use it everywhere and turn it on / off from command flags. * Return an error when the pending block is requested in Raft mode. --- cmd/utils/flags.go | 2 ++ eth/api_backend.go | 9 +++++++++ internal/ethapi/api.go | 7 ++----- logger/log_raft_checkpoint.go | 20 ++++++++++++++++++++ raft/constants.go | 6 ------ raft/handler.go | 10 +++------- 6 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 logger/log_raft_checkpoint.go diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index fb8d17c6b..6d951faaa 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -727,6 +727,8 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) { blockTimeMillis := ctx.GlobalInt(RaftBlockTime.Name) datadir := ctx.GlobalString(DataDirFlag.Name) + logger.DoLogRaft = true + if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { strId := discover.PubkeyID(stack.PublicKey()).String() blockTimeNanos := time.Duration(blockTimeMillis) * time.Millisecond diff --git a/eth/api_backend.go b/eth/api_backend.go index e5bc29103..bf8d5451c 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -19,6 +19,7 @@ package eth import ( "math/big" + "fmt" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" @@ -33,6 +34,8 @@ import ( "golang.org/x/net/context" ) +var raftHasNoPending = fmt.Errorf("Raft mode has no Pending block. Use latest instead.") + // EthApiBackend implements ethapi.Backend for full nodes type EthApiBackend struct { eth *Ethereum @@ -58,6 +61,9 @@ func (b *EthApiBackend) HeaderByNumber(blockNr rpc.BlockNumber) *types.Header { func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) { // Pending block is only known by the miner if blockNr == rpc.PendingBlockNumber { + if b.eth.protocolManager.raftMode { + return nil, raftHasNoPending + } block, _, _ := b.eth.blockVoting.Pending() return block, nil } @@ -71,6 +77,9 @@ func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb func (b *EthApiBackend) StateAndHeaderByNumber(blockNr rpc.BlockNumber) (ethapi.State, *types.Header, error) { // Pending state is only known by the miner if blockNr == rpc.PendingBlockNumber { + if b.eth.protocolManager.raftMode { + return nil, nil, raftHasNoPending + } block, publicState, privateState := b.eth.blockVoting.Pending() return EthApiState{publicState, privateState}, block.Header(), nil } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 3bc94e03e..445685c6f 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -21,7 +21,6 @@ import ( "encoding/hex" "encoding/json" "fmt" - "log" "math/big" "net/http" "strings" @@ -1194,12 +1193,10 @@ func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, si from, _ := signedTx.From() addr := crypto.CreateAddress(from, signedTx.Nonce()) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) - // XXX(joel) use logCheckpoint - log.Printf("RAFT-CHECKPOINT TX-CREATED (%v, %v)\n", signedTx.Hash().Hex(), addr.Hex()) + logger.LogRaftCheckpoint(logger.TxCreated, signedTx.Hash().Hex(), addr.Hex()) } else { glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) - // XXX(joel) use logCheckpoint - log.Printf("RAFT-CHECKPOINT TX-CREATED (%v, %v)\n", signedTx.Hash().Hex(), tx.To().Hex()) + logger.LogRaftCheckpoint(logger.TxCreated, signedTx.Hash().Hex(), tx.To().Hex()) } return signedTx.Hash(), nil diff --git a/logger/log_raft_checkpoint.go b/logger/log_raft_checkpoint.go new file mode 100644 index 000000000..b641bd8e7 --- /dev/null +++ b/logger/log_raft_checkpoint.go @@ -0,0 +1,20 @@ +package logger + +import ( + "github.com/ethereum/go-ethereum/logger/glog" +) + +const ( + TxCreated = "TX-CREATED" + TxAccepted = "TX-ACCEPTED" + BecameMinter = "BECAME-MINTER" + BecameVerifier = "BECAME-VERIFIER" +) + +var DoLogRaft = false + +func LogRaftCheckpoint(checkpointName string, logValues ...interface{}) { + if DoLogRaft { + glog.V(Info).Infof("RAFT-CHECKPOINT %s %v\n", checkpointName, logValues) + } +} diff --git a/raft/constants.go b/raft/constants.go index 28de7f736..7d679c17f 100644 --- a/raft/constants.go +++ b/raft/constants.go @@ -26,12 +26,6 @@ const ( snapshotPeriod = 250 peerUrlKeyPrefix = "peerUrl-" - - // checkpoints - txCreated = "TX-CREATED" - txAccepted = "TX-ACCEPTED" - becameMinter = "BECAME-MINTER" - becameVerifier = "BECAME-VERIFIER" ) var ( diff --git a/raft/handler.go b/raft/handler.go index dea5b7efc..539c3c38b 100644 --- a/raft/handler.go +++ b/raft/handler.go @@ -350,10 +350,10 @@ func (pm *ProtocolManager) handleRoleChange(roleC <-chan interface{}) { } if intRole == minterRole { - logCheckpoint(becameMinter, "") + logger.LogRaftCheckpoint(logger.BecameMinter) pm.minter.start() } else { // verifier - logCheckpoint(becameVerifier, "") + logger.LogRaftCheckpoint(logger.BecameVerifier) pm.minter.stop() } @@ -605,10 +605,6 @@ func sleep(duration time.Duration) { <-time.NewTimer(duration).C } -func logCheckpoint(checkpointName string, iface interface{}) { - glog.V(logger.Info).Infof("RAFT-CHECKPOINT %s %v\n", checkpointName, iface) -} - func blockExtendsChain(block *types.Block, chain *core.BlockChain) bool { return block.ParentHash() == chain.CurrentBlock().Hash() } @@ -628,7 +624,7 @@ func (pm *ProtocolManager) applyNewChainHead(block *types.Block) { } for _, tx := range block.Transactions() { - logCheckpoint(txAccepted, tx.Hash().Hex()) + logger.LogRaftCheckpoint(logger.TxAccepted, tx.Hash().Hex()) } _, err := pm.blockchain.InsertChain([]*types.Block{block})