aboutsummaryrefslogtreecommitdiffstats
path: root/indexer
diff options
context:
space:
mode:
authorMeng-Ying Yang <garfield@dexon.org>2018-12-27 19:22:41 +0800
committerWei-Ning Huang <w@dexon.org>2019-03-12 12:19:09 +0800
commitd124aec39f0e346b67434795b433797528084a57 (patch)
tree1b4038f2eca3cbb4b5c04391980a64d00a13134e /indexer
parent37e5d4b0f6a3ab072a8d41e3414048f8546df237 (diff)
downloaddexon-d124aec39f0e346b67434795b433797528084a57.tar.gz
dexon-d124aec39f0e346b67434795b433797528084a57.tar.zst
dexon-d124aec39f0e346b67434795b433797528084a57.zip
indexer: support data exporting/forwarding (#103)
To support more effective and flexible blockchain info exploring, we add `indexer` package, defines the flow of indexer dameon, and integrate into dex.Dexon fullnode. For more export options, we use Golang built-in `plugin` package to support mulitple implementations.
Diffstat (limited to 'indexer')
-rw-r--r--indexer/blockhain.go85
-rw-r--r--indexer/config.go35
-rw-r--r--indexer/interfaces.go19
3 files changed, 139 insertions, 0 deletions
diff --git a/indexer/blockhain.go b/indexer/blockhain.go
new file mode 100644
index 000000000..bf9a180ce
--- /dev/null
+++ b/indexer/blockhain.go
@@ -0,0 +1,85 @@
+package indexer
+
+import (
+ "math/big"
+
+ coreCommon "github.com/dexon-foundation/dexon-consensus/common"
+ coreTypes "github.com/dexon-foundation/dexon-consensus/core/types"
+
+ "github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core"
+ "github.com/dexon-foundation/dexon/core/state"
+ "github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/event"
+ "github.com/dexon-foundation/dexon/rlp"
+)
+
+// ReadOnlyBlockChain defines safe reading blockchain interface by removing write
+// methods of core.BlockChain struct.
+type ReadOnlyBlockChain interface {
+ BadBlocks() []*types.Block
+ CurrentBlock() *types.Block
+ CurrentFastBlock() *types.Block
+ CurrentHeader() *types.Header
+ GasLimit() uint64
+ Genesis() *types.Block
+ GetAncestor(common.Hash, uint64, uint64, *uint64) (common.Hash, uint64)
+ GetAddressInfo(uint32, common.Address) (
+ info struct {
+ Nonce uint64
+ Cost *big.Int
+ Counter uint64
+ })
+ GetBlock(common.Hash, uint64) *types.Block
+ GetBlockByHash(common.Hash) *types.Block
+ GetBlockByNumber(uint64) *types.Block
+ GetBlockHashesFromHash(common.Hash, uint64) []common.Hash
+ GetBlocksFromHash(common.Hash, int) (blocks []*types.Block)
+ GetBody(common.Hash) *types.Body
+ GetBodyRLP(common.Hash) rlp.RawValue
+ GetChainLastConfirmedHeight(uint32) uint64
+ GetConfirmedBlockByHash(uint32, coreCommon.Hash) (*coreTypes.Block, types.Transactions)
+ GetCostInConfirmedBlocks(uint32, common.Address) (*big.Int, bool)
+ GetGovStateByHash(common.Hash) (*types.GovState, error)
+ GetGovStateByNumber(uint64) (*types.GovState, error)
+ GetHeader(common.Hash, uint64) *types.Header
+ GetHeaderByHash(common.Hash) *types.Header
+ GetHeaderByNumber(number uint64) *types.Header
+ GetLastNonceInConfirmedBlocks(uint32, common.Address) (uint64, bool)
+ GetPending() (*types.Block, *state.StateDB)
+ GetPendingBlockByNumber(uint64) *types.Block
+ GetPendingHeight() uint64
+ GetReceiptsByHash(common.Hash) types.Receipts
+ GetRoundHeight(uint64) (uint64, bool)
+ GetTd(common.Hash, uint64) *big.Int
+ GetTdByHash(common.Hash) *big.Int
+ GetUnclesInChain(*types.Block, int) []*types.Header
+ HasBlock(common.Hash, uint64) bool
+ HasBlockAndState(common.Hash, uint64) bool
+ HasHeader(common.Hash, uint64) bool
+ HasState(common.Hash) bool
+ PendingBlock() *types.Block
+ State() (*state.StateDB, error)
+ StateAt(root common.Hash) (*state.StateDB, error)
+ SubscribeBlockConfirmedEvent(chan<- core.BlockConfirmedEvent) event.Subscription
+ SubscribeChainEvent(chan<- core.ChainEvent) event.Subscription
+ SubscribeChainHeadEvent(chan<- core.ChainHeadEvent) event.Subscription
+ SubscribeChainSideEvent(chan<- core.ChainSideEvent) event.Subscription
+ SubscribeLogsEvent(chan<- []*types.Log) event.Subscription
+ SubscribeRemovedLogsEvent(chan<- core.RemovedLogsEvent) event.Subscription
+}
+
+// access protection
+type ro interface {
+ ReadOnlyBlockChain
+}
+
+// ROBlockChain struct for safe read.
+type ROBlockChain struct {
+ ro
+}
+
+// NewROBlockChain converts original block chain to readonly interface.
+func NewROBlockChain(bc *core.BlockChain) ReadOnlyBlockChain {
+ return &ROBlockChain{ro: bc}
+}
diff --git a/indexer/config.go b/indexer/config.go
new file mode 100644
index 000000000..3b626272a
--- /dev/null
+++ b/indexer/config.go
@@ -0,0 +1,35 @@
+package indexer
+
+import (
+ "plugin"
+)
+
+// Config is data sources related configs struct.
+type Config struct {
+ // Used by dex/backend init flow.
+ Enable bool
+
+ // Plugin path for building components.
+ Plugin string
+}
+
+// NewIndexerFromConfig initialize exporter according to given config.
+func NewIndexerFromConfig(bc ReadOnlyBlockChain, c Config) (idx Indexer) {
+ if c.Plugin == "" {
+ // default
+ return
+ }
+
+ plug, err := plugin.Open(c.Plugin)
+ if err != nil {
+ panic(err)
+ }
+
+ symbol, err := plug.Lookup(NewIndexerFuncName)
+ if err != nil {
+ panic(err)
+ }
+
+ idx = symbol.(NewIndexerFunc)(bc, c)
+ return
+}
diff --git a/indexer/interfaces.go b/indexer/interfaces.go
new file mode 100644
index 000000000..f35bc6547
--- /dev/null
+++ b/indexer/interfaces.go
@@ -0,0 +1,19 @@
+package indexer
+
+// NewIndexerFuncName plugin looks up name.
+var NewIndexerFuncName = "NewIndexer"
+
+// NewIndexerFunc init function alias.
+type NewIndexerFunc = func(ReadOnlyBlockChain, Config) Indexer
+
+// Indexer defines indexer daemon interface. The daemon would hold a
+// core.Blockhain, passed by initialization function, to receiving latest block
+// event or other information query and interaction.
+type Indexer interface {
+ // Start is called by dex.Dexon if config is set.
+ Start() error
+
+ // Stop is called by dex.Dexon if config is set and procedure is
+ // terminating.
+ Stop() error
+}