/*
* Copyright (c) [2016] [ <ether.camp> ]
* This file is part of the ethereumJ library.
*
* The ethereumJ library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ethereumJ library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
*/
package org.ethereum.facade;
/**
* Represents the current state of syncing process
*/
public class SyncStatus {
public enum SyncStage {
/**
* Fast sync: looking for a Pivot block.
* Normally we need several peers to select the block but
* the block can be selected from existing peers due to timeout
*/
PivotBlock,
/**
* Fast sync: downloading state trie nodes and importing blocks
*/
StateNodes,
/**
* Fast sync: downloading headers for securing the latest state
*/
Headers,
/**
* Fast sync: downloading blocks
*/
BlockBodies,
/**
* Fast sync: downloading receipts
*/
Receipts,
/**
* Regular sync is in progress
*/
Regular,
/**
* Sync is complete:
* Fast sync: the state is secure, all blocks and receipt are downloaded
* Regular sync: all blocks are imported up to the blockchain head
*/
Complete,
/**
* Syncing is turned off
*/
Off;
/**
* Indicates if this state represents ongoing FastSync
*/
public boolean isFastSync() {
return this == PivotBlock || this == StateNodes || this == Headers || this == BlockBodies || this == Receipts;
}
/**
* Indicates the current state is secure
*
* When doing fast sync UNSECURE sync means that the full state is downloaded,
* chain is on the latest block, and blockchain operations may be executed
* (such as state querying, transaction submission)
* but the state isn't yet confirmed with the whole block chain and can't be
* trusted.
* At this stage historical blocks and receipts are unavailable yet
*
* SECURE sync means that the full state is downloaded,
* chain is on the latest block, and blockchain operations may be executed
* (such as state querying, transaction submission)
* The state is now confirmed by the full chain (all block headers are
* downloaded and verified) and can be trusted
* At this stage historical blocks and receipts are unavailable yet
*/
public boolean isSecure() {
return this != PivotBlock || this != StateNodes && this != Headers;
}
/**
* Indicates the blockchain state is up-to-date
* Warning: the state could still be non-secure
*/
public boolean hasLatestState() {
return this == Headers || this == BlockBodies || this == Receipts || this == Complete;
}
}
private final SyncStage stage;
private final long curCnt;
private final long knownCnt;
private final long blockLastImported;
private final long blockBestKnown;
public SyncStatus(SyncStatus state, long blockLastImported, long blockBestKnown) {
this(state.getStage(), state.getCurCnt(), state.getKnownCnt(), blockLastImported, blockBestKnown);
}
public SyncStatus(SyncStage stage, long curCnt, long knownCnt, long blockLastImported, long blockBestKnown) {
this.stage = stage;
this.curCnt = curCnt;
this.knownCnt = knownCnt;
this.blockLastImported = blockLastImported;
this.blockBestKnown = blockBestKnown;
}
public SyncStatus(SyncStage stage, long curCnt, long knownCnt) {
this(stage, curCnt, knownCnt, 0, 0);
}
/**
* Gets the current stage of syncing
*/
public SyncStage getStage() {
return stage;
}
/**
* Gets the current count of items processed for this syncing stage :
* PivotBlock: number of seconds pivot block is searching for
* ( this number can be greater than getKnownCnt() if no peers found)
* StateNodes: number of trie nodes downloaded
* Headers: number of headers downloaded
* BlockBodies: number of block bodies downloaded
* Receipts: number of blocks receipts are downloaded for
*/
public long getCurCnt() {
return curCnt;
}
/**
* Gets the known count of items for this syncing stage :
* PivotBlock: number of seconds pivot is forced to be selected
* StateNodes: number of currently known trie nodes. This number is not constant as new nodes
* are discovered when their parent is downloaded
* Headers: number of headers to be downloaded
* BlockBodies: number of block bodies to be downloaded
* Receipts: number of blocks receipts are to be downloaded for
*/
public long getKnownCnt() {
return knownCnt;
}
/**
* Reflects the blockchain state: the latest imported block
* Blocks importing can run in parallel with other sync stages
* (like header/blocks/receipts downloading)
*/
public long getBlockLastImported() {
return blockLastImported;
}
/**
* Return the best known block from other peers
*/
public long getBlockBestKnown() {
return blockBestKnown;
}
@Override
public String toString() {
return stage +
(stage != SyncStage.Off && stage != SyncStage.Complete ? " (" + getCurCnt() + " of " + getKnownCnt() + ")" : "") +
", last block #" + getBlockLastImported() + ", best known #" + getBlockBestKnown();
}
}