From adb04994560c2558fc93c85ea5976b3744ca6b6b Mon Sep 17 00:00:00 2001
From: Wei-Ning Huang <w@dexon.org>
Date: Thu, 15 Nov 2018 13:30:50 +0800
Subject: core: refactor validator and fix light node sync (#25)

Remove custom Dexon validator by adding a new `ValidateWitnessData`
method into the validator interface. This allow us to properly detect
know blocks. This also allow other gdex "light" client to sync
compaction chain. Also, setup a standalone RPC node for handling RPC
reqeusts.
---
 core/tx_pool.go | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

(limited to 'core/tx_pool.go')

diff --git a/core/tx_pool.go b/core/tx_pool.go
index 6a9fa45c3..7f5be1832 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -36,6 +36,9 @@ import (
 )
 
 const (
+	// chainHeadChanSize is the size of channel listening to ChainHeadEvent.
+	chainHeadChanSize = 10
+
 	// blockConfirmedChanSize is the size of channel listening to BlockConfirmedEvent.
 	blockConfirmedChanSize = 10
 )
@@ -118,6 +121,7 @@ type blockChain interface {
 	GetBlock(hash common.Hash, number uint64) *types.Block
 	StateAt(root common.Hash) (*state.StateDB, error)
 
+	SubscribeChainHeadEvent(ch chan<- ChainHeadEvent) event.Subscription
 	SubscribeBlockConfirmedEvent(ch chan<- BlockConfirmedEvent) event.Subscription
 }
 
@@ -189,6 +193,8 @@ type TxPool struct {
 	gasPrice          *big.Int
 	txFeed            event.Feed
 	scope             event.SubscriptionScope
+	chainHeadCh       chan ChainHeadEvent
+	chainHeadSub      event.Subscription
 	blockConfirmedCh  chan BlockConfirmedEvent
 	blockConfirmedSub event.Subscription
 	signer            types.Signer
@@ -209,12 +215,13 @@ type TxPool struct {
 
 	wg sync.WaitGroup // for shutdown sync
 
-	homestead bool
+	homestead       bool
+	isBlockProposer bool
 }
 
 // NewTxPool creates a new transaction pool to gather, sort and filter inbound
 // transactions from the network.
-func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain) *TxPool {
+func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain blockChain, isBlockProposer bool) *TxPool {
 	// Sanitize the input to ensure no vulnerable gas prices are set
 	config = (&config).sanitize()
 
@@ -228,8 +235,10 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
 		queue:            make(map[common.Address]*txList),
 		beats:            make(map[common.Address]time.Time),
 		all:              newTxLookup(),
+		chainHeadCh:      make(chan ChainHeadEvent, chainHeadChanSize),
 		blockConfirmedCh: make(chan BlockConfirmedEvent, blockConfirmedChanSize),
 		gasPrice:         new(big.Int).SetUint64(config.PriceLimit),
+		isBlockProposer:  isBlockProposer,
 	}
 	pool.locals = newAccountSet(pool.signer)
 	for _, addr := range config.Locals {
@@ -252,6 +261,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chain block
 	}
 	// Subscribe events from blockchain
 	pool.blockConfirmedSub = pool.chain.SubscribeBlockConfirmedEvent(pool.blockConfirmedCh)
+	pool.chainHeadSub = pool.chain.SubscribeChainHeadEvent(pool.chainHeadCh)
 
 	// Start the event loop and return
 	pool.wg.Add(1)
@@ -284,8 +294,29 @@ func (pool *TxPool) loop() {
 	// Keep waiting for and reacting to the various events
 	for {
 		select {
+		// Handle ChainHeadEvent
+		case ev := <-pool.chainHeadCh:
+			if pool.isBlockProposer {
+				break
+			}
+			if ev.Block != nil {
+				pool.mu.Lock()
+				if pool.chainconfig.IsHomestead(ev.Block.Number()) {
+					pool.homestead = true
+				}
+				pool.reset(head.Header(), ev.Block.Header())
+				head = ev.Block
+
+				pool.mu.Unlock()
+			}
+			// Be unsubscribed due to system stopped
+		case <-pool.chainHeadSub.Err():
+			return
 		// Handle BlockConfirmedEvent
 		case ev := <-pool.blockConfirmedCh:
+			if !pool.isBlockProposer {
+				break
+			}
 			if ev.Block != nil {
 				pool.mu.Lock()
 				if pool.chainconfig.IsHomestead(ev.Block.Number()) {
-- 
cgit v1.2.3