github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/cmd/geth/log_display_basic.go (about)

     1  // ---
     2  //2017-02-03 16:44:00  Discover                                                              0/25 peers
     3  //2017-02-03 16:45:00  Discover                                                              1/25 peers
     4  //2017-02-03 16:46:00  Fast   #2481951 of #3124363    79.4%   1211/  554    blk/mgas sec     6/25 peers
     5  //2017-02-03 16:47:00  Fast   #2689911 of #3124363    86.1%    611/  981    blk/mgas sec     6/25 peers
     6  //2017-02-03 16:48:00  Fast   #2875913 of #3124363    92.0%    502/  760    blk/mgas sec     4/25 peers
     7  //2017-02-03 16:49:00  Sync   #3124227 of #3124363 c76c34e7   77/ 242/ 7 blk/tx/mgas sec     4/25 peers
     8  //2017-02-03 16:50:00  Sync   #3124247 of #3124363 75e48eff   51/  51/ 5 blk/tx/mgas sec     4/25 peers
     9  //2017-02-03 16:51:00  Sync   #3124567 of #3124363 9af334ae  117/ 129/11 blk/tx/mgas sec     5/25 peers
    10  //2017-02-03 16:52:00  Sync   #3124787 of #3124363 1e3a8351    9/   6/ 1 blk/tx/mgas sec     7/25 peers
    11  //2017-02-03 16:52:05  Import #3124788             84e11ff4        15/ 7 tx/mgas            10/25 peers
    12  //2017-02-03 16:52:25  Import #3124789             9e45a241         5/ 1 tx/mgas            12/25 peers
    13  //2017-02-03 16:52:45  Import #3124790             d819f71c         0/ 0 tx/mgas            18/25 peers
    14  //2017-02-03 16:52:46  Mined  #3124791             b719f31b         7/ 1 tx/mgas            18/25 peers
    15  // ---
    16  
    17  package main
    18  
    19  import (
    20  	"fmt"
    21  	"math/big"
    22  	"strconv"
    23  	"time"
    24  
    25  	"github.com/ethereumproject/go-ethereum/core"
    26  	"github.com/ethereumproject/go-ethereum/core/types"
    27  	"github.com/ethereumproject/go-ethereum/eth"
    28  	"github.com/ethereumproject/go-ethereum/eth/downloader"
    29  	"github.com/ethereumproject/go-ethereum/logger"
    30  	"github.com/ethereumproject/go-ethereum/logger/glog"
    31  	"gopkg.in/urfave/cli.v1"
    32  )
    33  
    34  // basicDisplaySystem is the basic display system spec'd in #127.
    35  var basicDisplaySystem = displayEventHandlers{
    36  	{
    37  		eventT: logEventCoreChainInsert,
    38  		ev:     core.ChainInsertEvent{},
    39  		handlers: displayEventHandlerFns{
    40  			func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) {
    41  				// Conditional prevents chain insert event logs during full/fast sync
    42  				if currentMode == lsModeImport {
    43  					switch d := evData.(type) {
    44  					case core.ChainInsertEvent:
    45  						currentBlockNumber = PrintStatusBasic(e, tickerInterval, &d, ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx)))
    46  						chainEventLastSent = time.Now()
    47  					}
    48  				}
    49  			},
    50  		},
    51  	},
    52  	{
    53  		eventT: logEventCoreMinedBlock,
    54  		ev:     core.NewMinedBlockEvent{},
    55  		handlers: displayEventHandlerFns{
    56  			func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) {
    57  				switch d := evData.(type) {
    58  				case core.NewMinedBlockEvent:
    59  					glog.D(logger.Warn).Infof(basicScanLn,
    60  						"Mined",
    61  						formatBlockNumber(d.Block.NumberU64()),
    62  						d.Block.Hash().Hex()[2:2+len(xlocalHeadHashD)],
    63  						fmt.Sprintf("%3d/%2d", d.Block.Transactions().Len(), new(big.Int).Div(d.Block.GasUsed(), big.NewInt(1000000)).Int64()),
    64  						"txs/mgas",
    65  						fmt.Sprintf("%2d/%2d peers", e.Downloader().GetPeers().Len(), ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx))),
    66  					)
    67  					currentBlockNumber = d.Block.NumberU64()
    68  				}
    69  			},
    70  		},
    71  	},
    72  	{
    73  		eventT: logEventDownloaderStart,
    74  		ev:     downloader.StartEvent{},
    75  	},
    76  	{
    77  		eventT: logEventDownloaderDone,
    78  		ev:     downloader.DoneEvent{},
    79  	},
    80  	{
    81  		eventT: logEventDownloaderFailed,
    82  		ev:     downloader.FailedEvent{},
    83  	},
    84  	{
    85  		eventT: logEventInterval,
    86  		handlers: displayEventHandlerFns{
    87  			func(ctx *cli.Context, e *eth.Ethereum, evData interface{}, tickerInterval time.Duration) {
    88  				// If not in import mode OR if we haven't logged a chain event.
    89  				if currentMode != lsModeImport || chainEventLastSent.IsZero() {
    90  					currentBlockNumber = PrintStatusBasic(e, tickerInterval, nil, ctx.GlobalInt(aliasableName(MaxPeersFlag.Name, ctx)))
    91  				}
    92  			},
    93  		},
    94  	},
    95  }
    96  
    97  func formatBlockNumber(i uint64) string {
    98  	return "#" + strconv.FormatUint(i, 10)
    99  }
   100  
   101  // Examples of spec'd output.
   102  const (
   103  	xlocalOfMaxD = "#92481951 of #93124363" // #2481951 of #3124363
   104  	// xpercentD = "   92.0%"                //    92.0% // commented because it is an item in the spec, but shorter than xLocalHeadHashD
   105  	xlocalHeadHashD     = "c76c34e7"         // c76c34e7
   106  	xprogressRateD      = " 117/ 129/ 11"    //  117/ 129/11
   107  	xprogressRateUnitsD = "blk/txs/mgas sec" // blk/tx/mgas sec
   108  	xpeersD             = "18/25 peers"      //  18/25 peers
   109  )
   110  
   111  const basicScanLn = "%-8s %-22s %8s %13s %-16s %11s"
   112  
   113  func strScanLenOf(s string, leftAlign bool) string {
   114  	if leftAlign {
   115  		return "%-" + strconv.Itoa(len(s)) + "s"
   116  	}
   117  	return "%" + strconv.Itoa(len(s)) + "s"
   118  }
   119  
   120  type printUnit struct {
   121  	value     string
   122  	example   string
   123  	leftAlign bool
   124  }
   125  
   126  func (p *printUnit) String() string {
   127  	return fmt.Sprintf("%s", p.value)
   128  }
   129  
   130  func calcBlockDiff(e *eth.Ethereum, lastLoggedBlockN uint64, localHead *types.Block) (blks, txs, mgas int) {
   131  	// Calculate block stats for interval
   132  	localHeadN := localHead.NumberU64()
   133  	blks = int(localHeadN - lastLoggedBlockN)
   134  	txs = 0
   135  	mGas := new(big.Int)
   136  
   137  	for i := lastLoggedBlockN + 1; i <= localHeadN; i++ {
   138  		b := e.BlockChain().GetBlockByNumber(i)
   139  		if b != nil {
   140  			// Add to tallies
   141  			txs += b.Transactions().Len()
   142  			mGas = mGas.Add(mGas, b.GasUsed())
   143  		}
   144  	}
   145  	mGas.Div(mGas, big.NewInt(1000000))
   146  	return blks, txs, int(mGas.Int64())
   147  }
   148  
   149  func calcPercent(quotient, divisor uint64) float64 {
   150  	out := float64(quotient) / float64(divisor)
   151  	return out * 100
   152  }
   153  
   154  // PrintStatusBasic implements the displayEventHandlerFn interface
   155  var PrintStatusBasic = func(e *eth.Ethereum, tickerInterval time.Duration, insertEvent *core.ChainInsertEvent, maxPeers int) uint64 {
   156  
   157  	// Set variable copy of current mode to avoid issue around currentMode's non-thread safety
   158  	currentModeLocal := currentMode
   159  
   160  	localOfMaxD := &printUnit{"", xlocalOfMaxD, true}
   161  	percentOrHash := &printUnit{"", xlocalHeadHashD, false}
   162  	progressRateD := &printUnit{"", xprogressRateD, false}           //  117/ 129/11
   163  	progressRateUnitsD := &printUnit{"", xprogressRateUnitsD, false} // blk/tx/mgas sec
   164  	peersD := &printUnit{"", xpeersD, false}                         //  18/25 peers
   165  
   166  	formatLocalOfMaxD := func(localheight, syncheight uint64) string {
   167  		if localheight < syncheight {
   168  			return fmt.Sprintf("%9s of %9s", formatBlockNumber(localheight), formatBlockNumber(syncheight))
   169  		}
   170  		// Show diff if imported more than one block.
   171  		if insertEvent != nil && insertEvent.Processed > 1 {
   172  			return fmt.Sprintf("%9s (+%4d)     ", formatBlockNumber(localheight), insertEvent.Processed)
   173  		}
   174  		return fmt.Sprintf("%9s             ", formatBlockNumber(localheight))
   175  	}
   176  
   177  	formatPercentD := func(localheight, syncheight uint64) string {
   178  		// Calculate and format percent sync of known height
   179  		fHeightRatio := fmt.Sprintf("%4.2f%%", calcPercent(localheight, syncheight))
   180  		return fmt.Sprintf("%s", fHeightRatio)
   181  	}
   182  
   183  	formatBlockHashD := func(b *types.Block) string {
   184  		return b.Hash().Hex()[2 : 2+len(xlocalHeadHashD)]
   185  	}
   186  
   187  	formatProgressRateD := func(blksN, txsN, mgasN int) string {
   188  		if blksN < 0 {
   189  			return fmt.Sprintf("%4d/%2d", txsN, mgasN)
   190  		}
   191  		if txsN < 0 {
   192  			return fmt.Sprintf("%3d/%2d", blksN, mgasN)
   193  		}
   194  		return fmt.Sprintf("%3d/%4d/%2d", blksN, txsN, mgasN)
   195  	}
   196  
   197  	formatPeersD := func(peersN, maxpeersN int) string {
   198  		return fmt.Sprintf("%2d/%2d peers", peersN, maxpeersN)
   199  	}
   200  
   201  	peersD.value = formatPeersD(e.Downloader().GetPeers().Len(), maxPeers)
   202  	defer func() {
   203  		glog.D(logger.Warn).Infof(basicScanLn,
   204  			currentModeLocal, localOfMaxD, percentOrHash, progressRateD, progressRateUnitsD, peersD)
   205  
   206  	}()
   207  
   208  	origin, current, chainSyncHeight, _, _ := e.Downloader().Progress() // origin, current, height, pulled, known
   209  	mode := e.Downloader().GetMode()
   210  	if mode == downloader.FastSync {
   211  		current = e.BlockChain().CurrentFastBlock().NumberU64()
   212  	}
   213  
   214  	if currentModeLocal == lsModeDiscover {
   215  		return current
   216  	}
   217  
   218  	var localHead *types.Block
   219  	if insertEvent != nil {
   220  		if evB := e.BlockChain().GetBlock(insertEvent.LastHash); evB != nil && currentModeLocal == lsModeImport {
   221  			localHead = evB
   222  		}
   223  	} else {
   224  		localHead = e.BlockChain().GetBlockByNumber(current)
   225  	}
   226  	// Sanity/safety check
   227  	if localHead == nil {
   228  		localHead = e.BlockChain().CurrentBlock()
   229  		if mode == downloader.FastSync {
   230  			localHead = e.BlockChain().CurrentFastBlock()
   231  		}
   232  	}
   233  
   234  	// Calculate progress rates
   235  	var blks, txs, mgas int
   236  	if currentModeLocal == lsModeImport && insertEvent != nil && insertEvent.Processed == 1 {
   237  		blks, txs, mgas = 1, localHead.Transactions().Len(), int(new(big.Int).Div(localHead.GasUsed(), big.NewInt(1000000)).Uint64())
   238  	} else if insertEvent != nil && insertEvent.Processed > 1 {
   239  		blks, txs, mgas = calcBlockDiff(e, localHead.NumberU64()-uint64(insertEvent.Processed), localHead)
   240  	} else if currentBlockNumber == 0 && origin > 0 {
   241  		blks, txs, mgas = calcBlockDiff(e, origin, localHead)
   242  	} else if currentBlockNumber != 0 && currentBlockNumber < localHead.NumberU64() {
   243  		blks, txs, mgas = calcBlockDiff(e, currentBlockNumber, localHead)
   244  	} else {
   245  		blks, txs, mgas = calcBlockDiff(e, localHead.NumberU64()-1, localHead)
   246  	}
   247  
   248  	switch currentModeLocal {
   249  	case lsModeFastSync:
   250  		lh := localHead.NumberU64()
   251  		localOfMaxD.value = formatLocalOfMaxD(lh, chainSyncHeight)
   252  		percentOrHash.value = formatPercentD(lh, chainSyncHeight)
   253  		progressRateD.value = formatProgressRateD(blks/int(tickerInterval.Seconds()), -1, mgas/int(tickerInterval.Seconds()))
   254  		progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "blk/mgas sec")
   255  	case lsModeFullSync:
   256  		localOfMaxD.value = formatLocalOfMaxD(localHead.NumberU64(), chainSyncHeight)
   257  		percentOrHash.value = formatBlockHashD(localHead)
   258  		progressRateD.value = formatProgressRateD(blks/int(tickerInterval.Seconds()), txs/int(tickerInterval.Seconds()), mgas/int(tickerInterval.Seconds()))
   259  		progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "blk/txs/mgas sec")
   260  	case lsModeImport:
   261  		localOfMaxD.value = formatLocalOfMaxD(localHead.NumberU64(), chainSyncHeight)
   262  		percentOrHash.value = formatBlockHashD(localHead)
   263  		progressRateD.value = fmt.Sprintf(strScanLenOf(xprogressRateD, false), formatProgressRateD(-1, txs, mgas))
   264  		progressRateUnitsD.value = fmt.Sprintf(strScanLenOf(xprogressRateUnitsD, true), "txs/mgas")
   265  	default:
   266  		// Without establishing currentModeLocal it would be possible to reach this case if currentMode changed during
   267  		// execution of last ~40 lines.
   268  	}
   269  	return current
   270  }