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.
This commit is contained in:
Joel Burget 2017-05-04 16:49:48 -04:00 committed by Patrick Mylund Nielsen
parent e3a0ae2703
commit 852ac74467
6 changed files with 36 additions and 18 deletions

View File

@ -727,6 +727,8 @@ func RegisterEthService(ctx *cli.Context, stack *node.Node, extra []byte) {
blockTimeMillis := ctx.GlobalInt(RaftBlockTime.Name) blockTimeMillis := ctx.GlobalInt(RaftBlockTime.Name)
datadir := ctx.GlobalString(DataDirFlag.Name) datadir := ctx.GlobalString(DataDirFlag.Name)
logger.DoLogRaft = true
if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
strId := discover.PubkeyID(stack.PublicKey()).String() strId := discover.PubkeyID(stack.PublicKey()).String()
blockTimeNanos := time.Duration(blockTimeMillis) * time.Millisecond blockTimeNanos := time.Duration(blockTimeMillis) * time.Millisecond

View File

@ -19,6 +19,7 @@ package eth
import ( import (
"math/big" "math/big"
"fmt"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core"
@ -33,6 +34,8 @@ import (
"golang.org/x/net/context" "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 // EthApiBackend implements ethapi.Backend for full nodes
type EthApiBackend struct { type EthApiBackend struct {
eth *Ethereum 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) { func (b *EthApiBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Block, error) {
// Pending block is only known by the miner // Pending block is only known by the miner
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
if b.eth.protocolManager.raftMode {
return nil, raftHasNoPending
}
block, _, _ := b.eth.blockVoting.Pending() block, _, _ := b.eth.blockVoting.Pending()
return block, nil 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) { func (b *EthApiBackend) StateAndHeaderByNumber(blockNr rpc.BlockNumber) (ethapi.State, *types.Header, error) {
// Pending state is only known by the miner // Pending state is only known by the miner
if blockNr == rpc.PendingBlockNumber { if blockNr == rpc.PendingBlockNumber {
if b.eth.protocolManager.raftMode {
return nil, nil, raftHasNoPending
}
block, publicState, privateState := b.eth.blockVoting.Pending() block, publicState, privateState := b.eth.blockVoting.Pending()
return EthApiState{publicState, privateState}, block.Header(), nil return EthApiState{publicState, privateState}, block.Header(), nil
} }

View File

@ -21,7 +21,6 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log"
"math/big" "math/big"
"net/http" "net/http"
"strings" "strings"
@ -1194,12 +1193,10 @@ func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction, si
from, _ := signedTx.From() from, _ := signedTx.From()
addr := crypto.CreateAddress(from, signedTx.Nonce()) addr := crypto.CreateAddress(from, signedTx.Nonce())
glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex()) glog.V(logger.Info).Infof("Tx(%s) created: %s\n", signedTx.Hash().Hex(), addr.Hex())
// XXX(joel) use logCheckpoint logger.LogRaftCheckpoint(logger.TxCreated, signedTx.Hash().Hex(), addr.Hex())
log.Printf("RAFT-CHECKPOINT TX-CREATED (%v, %v)\n", signedTx.Hash().Hex(), addr.Hex())
} else { } else {
glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex()) glog.V(logger.Info).Infof("Tx(%s) to: %s\n", signedTx.Hash().Hex(), tx.To().Hex())
// XXX(joel) use logCheckpoint logger.LogRaftCheckpoint(logger.TxCreated, signedTx.Hash().Hex(), tx.To().Hex())
log.Printf("RAFT-CHECKPOINT TX-CREATED (%v, %v)\n", signedTx.Hash().Hex(), tx.To().Hex())
} }
return signedTx.Hash(), nil return signedTx.Hash(), nil

View File

@ -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)
}
}

View File

@ -26,12 +26,6 @@ const (
snapshotPeriod = 250 snapshotPeriod = 250
peerUrlKeyPrefix = "peerUrl-" peerUrlKeyPrefix = "peerUrl-"
// checkpoints
txCreated = "TX-CREATED"
txAccepted = "TX-ACCEPTED"
becameMinter = "BECAME-MINTER"
becameVerifier = "BECAME-VERIFIER"
) )
var ( var (

View File

@ -350,10 +350,10 @@ func (pm *ProtocolManager) handleRoleChange(roleC <-chan interface{}) {
} }
if intRole == minterRole { if intRole == minterRole {
logCheckpoint(becameMinter, "") logger.LogRaftCheckpoint(logger.BecameMinter)
pm.minter.start() pm.minter.start()
} else { // verifier } else { // verifier
logCheckpoint(becameVerifier, "") logger.LogRaftCheckpoint(logger.BecameVerifier)
pm.minter.stop() pm.minter.stop()
} }
@ -605,10 +605,6 @@ func sleep(duration time.Duration) {
<-time.NewTimer(duration).C <-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 { func blockExtendsChain(block *types.Block, chain *core.BlockChain) bool {
return block.ParentHash() == chain.CurrentBlock().Hash() return block.ParentHash() == chain.CurrentBlock().Hash()
} }
@ -628,7 +624,7 @@ func (pm *ProtocolManager) applyNewChainHead(block *types.Block) {
} }
for _, tx := range block.Transactions() { for _, tx := range block.Transactions() {
logCheckpoint(txAccepted, tx.Hash().Hex()) logger.LogRaftCheckpoint(logger.TxAccepted, tx.Hash().Hex())
} }
_, err := pm.blockchain.InsertChain([]*types.Block{block}) _, err := pm.blockchain.InsertChain([]*types.Block{block})