diff options
author | Meng-Ying Yang <garfield@dexon.org> | 2018-12-27 19:22:41 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-03-12 12:19:09 +0800 |
commit | d124aec39f0e346b67434795b433797528084a57 (patch) | |
tree | 1b4038f2eca3cbb4b5c04391980a64d00a13134e /indexer | |
parent | 37e5d4b0f6a3ab072a8d41e3414048f8546df237 (diff) | |
download | dexon-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.go | 85 | ||||
-rw-r--r-- | indexer/config.go | 35 | ||||
-rw-r--r-- | indexer/interfaces.go | 19 |
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 +} |