Skip to content

Commit

Permalink
Add ultralight sync mode (ethereum#228)
Browse files Browse the repository at this point in the history
This IBFT-specific mode fetches only the epoch blocks and validates
them.
  • Loading branch information
ashishb authored Jun 12, 2019
1 parent 3411229 commit 2f09e5e
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 93 deletions.
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func initGenesis(ctx *cli.Context) error {
}
// Open an initialise both full and light databases
stack := makeFullNode(ctx)
for _, name := range []string{"chaindata", "lightchaindata", "celolatestchaindata"} {
for _, name := range []string{"chaindata", "lightchaindata", "celolatestchaindata", "ultralightchaindata"} {
chaindb, err := stack.OpenDatabase(name, 0, 0)
if err != nil {
utils.Fatalf("Failed to open database: %v", err)
Expand Down
4 changes: 3 additions & 1 deletion cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,7 @@ func SetDashboardConfig(ctx *cli.Context, cfg *dashboard.Config) {
// RegisterEthService adds an Ethereum client to the stack.
func RegisterEthService(stack *node.Node, cfg *eth.Config) {
var err error
if cfg.SyncMode == downloader.LightSync || cfg.SyncMode == downloader.CeloLatestSync {
if !cfg.SyncMode.SyncFullBlockChain() {
err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
return les.New(ctx, cfg)
})
Expand Down Expand Up @@ -1481,6 +1481,8 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
name = "lightchaindata"
} else if ctx.GlobalString(SyncModeFlag.Name) == "celolatest" {
name = "celolatestchaindata"
} else if ctx.GlobalString(SyncModeFlag.Name) == "ultralight" {
name = "ultralightchaindata"
}
chainDb, err := stack.OpenDatabase(name, cache, handles)
if err != nil {
Expand Down
26 changes: 13 additions & 13 deletions core/chain_indexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,25 @@ type ChainIndexer struct {

log log.Logger
lock sync.RWMutex
// True in all sync modes except CeloLatestSync.
fullChainDownloaded bool
// True in all sync modes except CeloLatestSync and UltraLightSync
fullHeaderChainDownloaded bool
}

// NewChainIndexer creates a new chain indexer to do background processing on
// chain segments of a given size after certain number of confirmations passed.
// The throttling parameter might be used to prevent database thrashing.
func NewChainIndexer(chainDb, indexDb ethdb.Database, backend ChainIndexerBackend, section, confirm uint64, throttling time.Duration, kind string, fullChainDownloaded bool) *ChainIndexer {
c := &ChainIndexer{
chainDb: chainDb,
indexDb: indexDb,
backend: backend,
update: make(chan struct{}, 1),
quit: make(chan chan error),
sectionSize: section,
confirmsReq: confirm,
throttling: throttling,
log: log.New("type", kind),
fullChainDownloaded: fullChainDownloaded,
chainDb: chainDb,
indexDb: indexDb,
backend: backend,
update: make(chan struct{}, 1),
quit: make(chan chan error),
sectionSize: section,
confirmsReq: confirm,
throttling: throttling,
log: log.New("type", kind),
fullHeaderChainDownloaded: fullChainDownloaded,
}
// Initialize database dependent fields and start the updater
c.loadValidSections()
Expand Down Expand Up @@ -395,7 +395,7 @@ func (c *ChainIndexer) processSection(section uint64, lastHead common.Hash) (com
for number := section * c.sectionSize; number < (section+1)*c.sectionSize; number++ {
hash := rawdb.ReadCanonicalHash(c.chainDb, number)
if hash == (common.Hash{}) {
if !c.fullChainDownloaded {
if !c.fullHeaderChainDownloaded {
return lastHead, nil
}
return common.Hash{}, fmt.Errorf("canonical block #%d unknown", number)
Expand Down
10 changes: 4 additions & 6 deletions core/headerchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,10 @@ func (hc *HeaderChain) WriteHeader(header *types.Header) (status WriteStatus, er
if hc.config.FullHeaderChainAvailable {
return NonStatTy, consensus.ErrUnknownAncestor
} else {
// Ancestors would be missing if the full header chain is not available.
// Therefore, we cannot calculate the difficulty level, assume the difficulty of
// a block to be its block number for now. Later on, we will add some verification,
// so that, malicious blocks cannot be inserted.
totalDifficulty := big.NewInt(int64(number))
log.Debug(fmt.Sprintf("Previous header difficulty is not available, setting it to %v", totalDifficulty))
// In IBFT, it seems that the announced td (total difficulty) is 1 + block number.
totalDifficulty := big.NewInt(int64(number + 1))
log.Debug(fmt.Sprintf("Previous header for %d difficulty is not available, setting its difficulty to %v",
number, totalDifficulty))
localTd = big.NewInt(hc.CurrentHeader().Number.Int64())
externTd = externTd.Add(externTd, totalDifficulty)
}
Expand Down
10 changes: 7 additions & 3 deletions eth/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ func (s *Ethereum) AddLesServer(ls LesServer) {
// initialisation of the common Ethereum object)
func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
// Ensure configuration values are compatible and sane
if config.SyncMode == downloader.LightSync || config.SyncMode == downloader.CeloLatestSync {
return nil, errors.New("can't run eth.Ethereum in light sync mode or celolatest mode, use les.LightEthereum")
if !config.SyncMode.SyncFullBlockChain() {
return nil, errors.New("can't run eth.Ethereum in light sync mode, celolatest mode, or ultralight sync mode, use les.LightEthereum")
}
if !config.SyncMode.IsValid() {
return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
Expand All @@ -129,6 +129,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
return nil, genesisErr
}
log.Info("Initialised chain configuration", "config", chainConfig)
fullHeaderChainAvailable := config.SyncMode.SyncFullHeaderChain()

eth := &Ethereum{
config: config,
Expand All @@ -142,7 +143,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
gasPrice: config.MinerGasPrice,
etherbase: config.Etherbase,
bloomRequests: make(chan chan *bloombits.Retrieval),
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms, config.SyncMode != downloader.CeloLatestSync),
bloomIndexer: NewBloomIndexer(chainDb, params.BloomBitsBlocks, params.BloomConfirms, fullHeaderChainAvailable),
}

log.Info("Initialising Ethereum protocol", "versions", eth.engine.Protocol().Versions, "network", config.NetworkId)
Expand Down Expand Up @@ -247,10 +248,12 @@ func CreateDB(ctx *node.ServiceContext, config *Config, name string) (ethdb.Data
func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainConfig, config *Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine {
// If proof-of-authority is requested, set it up
if chainConfig.Clique != nil {
log.Debug("Setting up clique consensus engine")
return clique.New(chainConfig.Clique, db)
}
// If Istanbul is requested, set it up
if chainConfig.Istanbul != nil {
log.Debug("Setting up Istanbul consensus engine")
if chainConfig.Istanbul.Epoch != 0 {
config.Istanbul.Epoch = chainConfig.Istanbul.Epoch
}
Expand All @@ -259,6 +262,7 @@ func CreateConsensusEngine(ctx *node.ServiceContext, chainConfig *params.ChainCo
}

// Otherwise assume proof-of-work
log.Debug("Setting up proof-of-work (pow) consensus engine")
switch config.Ethash.PowMode {
case ethash.ModeFake:
log.Warn("Ethash used in fake mode")
Expand Down
Loading

0 comments on commit 2f09e5e

Please sign in to comment.