Documentation ¶
Index ¶
- Constants
- Variables
- func ClientConfig() *rpcclient.ConnConfig
- func CoinbaseValue(height int32) int64
- func GetFileParsed(db kv.DB) (file int, err error)
- func Itoa(n int32) string
- func NewClient() (*rpcclient.Client, error)
- func PrepareTransactions(db kv.DB, txs []*btcutil.Tx) (transactions []tx.Tx, err error)
- func StoreFileParsed(db kv.DB, file int) (err error)
- type Block
- type Blockchain
- type CheckPoint
- type InputParser
- type OutputParser
- type Parser
- type Skipped
- func (s *Skipped) DeleteBlock(hash *chainhash.Hash)
- func (s *Skipped) Empty()
- func (s *Skipped) GetBlock(hash *chainhash.Hash) (block Block, err error)
- func (s *Skipped) GetStoredBlocks() (blocks []string)
- func (s *Skipped) IsStored(hash *chainhash.Hash) bool
- func (s *Skipped) Len() int
- func (s *Skipped) StoreBlock(v interface{}) (err error)
- func (s *Skipped) StoreBlockPrevHash(b *Block)
- type TransactionsParser
- type Tx
Constants ¶
const FileKey = "file"
FileKey key for kv stored parsed files counter
Variables ¶
var ( // ErrEmptySliceParse cannot parse block from empty slice error ErrEmptySliceParse = errors.New("cannot parse block from empty slice") // ErrIncompleteBlockParse cannot parse block due to incomplete file error ErrIncompleteBlockParse = errors.New("cannot parse incomplete block") // ErrBlockParse cannot parse block error ErrBlockParse = errors.New("cannot parse block") // ErrBlockFromBytes cannot generate block from matched bytes error ErrBlockFromBytes = errors.New("cannot generate block from matched bytes") // ErrMagicBytesMatching cannot match magic bytes ErrMagicBytesMatching = errors.New("cannot match magic bytes") )
var ( // ErrInterrupt interrupt signal error ErrInterrupt = errors.New("parser input signal error") // ErrInterruptUnknown interrupt signal error ErrInterruptUnknown = errors.New("parser input signal unknown error") )
var ( // ErrExceededSize skipped blocks size error ErrExceededSize = errors.New("exceed skipped blocks size") // ErrCheckpointNotFound checkpoint not found error ErrCheckpointNotFound = fmt.Errorf("checkpoint %w", errorx.ErrNotFound) // ErrNoBitcoinData returned if no bitcoin data to read from ErrNoBitcoinData = errors.New("missing bitcoin data") )
var Block100000 = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash([32]byte{ 0x50, 0x12, 0x01, 0x19, 0x17, 0x2a, 0x61, 0x04, 0x21, 0xa6, 0xc3, 0x01, 0x1d, 0xd3, 0x30, 0xd9, 0xdf, 0x07, 0xb6, 0x36, 0x16, 0xc2, 0xcc, 0x1f, 0x1c, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, }), MerkleRoot: chainhash.Hash([32]byte{ 0x66, 0x57, 0xa9, 0x25, 0x2a, 0xac, 0xd5, 0xc0, 0xb2, 0x94, 0x09, 0x96, 0xec, 0xff, 0x95, 0x22, 0x28, 0xc3, 0x06, 0x7c, 0xc3, 0x8d, 0x48, 0x85, 0xef, 0xb5, 0xa4, 0xac, 0x42, 0x47, 0xe9, 0xf3, }), Timestamp: time.Unix(1293623863, 0), Bits: 0x1b04864c, Nonce: 0x10572b0f, }, Transactions: []*wire.MsgTx{ { Version: 1, TxIn: []*wire.TxIn{ { PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash{}, Index: 0xffffffff, }, SignatureScript: []byte{ 0x04, 0x4c, 0x86, 0x04, 0x1b, 0x02, 0x06, 0x02, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { Value: 0x12a05f200, PkScript: []byte{ 0x41, 0x04, 0x1b, 0x0e, 0x8c, 0x25, 0x67, 0xc1, 0x25, 0x36, 0xaa, 0x13, 0x35, 0x7b, 0x79, 0xa0, 0x73, 0xdc, 0x44, 0x44, 0xac, 0xb8, 0x3c, 0x4e, 0xc7, 0xa0, 0xe2, 0xf9, 0x9d, 0xd7, 0x45, 0x75, 0x16, 0xc5, 0x81, 0x72, 0x42, 0xda, 0x79, 0x69, 0x24, 0xca, 0x4e, 0x99, 0x94, 0x7d, 0x08, 0x7f, 0xed, 0xf9, 0xce, 0x46, 0x7c, 0xb9, 0xf7, 0xc6, 0x28, 0x70, 0x78, 0xf8, 0x01, 0xdf, 0x27, 0x6f, 0xdf, 0x84, 0xac, }, }, }, LockTime: 0, }, { Version: 1, TxIn: []*wire.TxIn{ { PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash([32]byte{ 0x03, 0x2e, 0x38, 0xe9, 0xc0, 0xa8, 0x4c, 0x60, 0x46, 0xd6, 0x87, 0xd1, 0x05, 0x56, 0xdc, 0xac, 0xc4, 0x1d, 0x27, 0x5e, 0xc5, 0x5f, 0xc0, 0x07, 0x79, 0xac, 0x88, 0xfd, 0xf3, 0x57, 0xa1, 0x87, }), Index: 0, }, SignatureScript: []byte{ 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xc3, 0x52, 0xd3, 0xdd, 0x99, 0x3a, 0x98, 0x1b, 0xeb, 0xa4, 0xa6, 0x3a, 0xd1, 0x5c, 0x20, 0x92, 0x75, 0xca, 0x94, 0x70, 0xab, 0xfc, 0xd5, 0x7d, 0xa9, 0x3b, 0x58, 0xe4, 0xeb, 0x5d, 0xce, 0x82, 0x02, 0x21, 0x00, 0x84, 0x07, 0x92, 0xbc, 0x1f, 0x45, 0x60, 0x62, 0x81, 0x9f, 0x15, 0xd3, 0x3e, 0xe7, 0x05, 0x5c, 0xf7, 0xb5, 0xee, 0x1a, 0xf1, 0xeb, 0xcc, 0x60, 0x28, 0xd9, 0xcd, 0xb1, 0xc3, 0xaf, 0x77, 0x48, 0x01, 0x41, 0x04, 0xf4, 0x6d, 0xb5, 0xe9, 0xd6, 0x1a, 0x9d, 0xc2, 0x7b, 0x8d, 0x64, 0xad, 0x23, 0xe7, 0x38, 0x3a, 0x4e, 0x6c, 0xa1, 0x64, 0x59, 0x3c, 0x25, 0x27, 0xc0, 0x38, 0xc0, 0x85, 0x7e, 0xb6, 0x7e, 0xe8, 0xe8, 0x25, 0xdc, 0xa6, 0x50, 0x46, 0xb8, 0x2c, 0x93, 0x31, 0x58, 0x6c, 0x82, 0xe0, 0xfd, 0x1f, 0x63, 0x3f, 0x25, 0xf8, 0x7c, 0x16, 0x1b, 0xc6, 0xf8, 0xa6, 0x30, 0x12, 0x1d, 0xf2, 0xb3, 0xd3, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { Value: 0x2123e300, PkScript: []byte{ 0x76, 0xa9, 0x14, 0xc3, 0x98, 0xef, 0xa9, 0xc3, 0x92, 0xba, 0x60, 0x13, 0xc5, 0xe0, 0x4e, 0xe7, 0x29, 0x75, 0x5e, 0xf7, 0xf5, 0x8b, 0x32, 0x88, 0xac, }, }, { Value: 0x108e20f00, PkScript: []byte{ 0x76, 0xa9, 0x14, 0x94, 0x8c, 0x76, 0x5a, 0x69, 0x14, 0xd4, 0x3f, 0x2a, 0x7a, 0xc1, 0x77, 0xda, 0x2c, 0x2f, 0x6b, 0x52, 0xde, 0x3d, 0x7c, 0x88, 0xac, }, }, }, LockTime: 0, }, { Version: 1, TxIn: []*wire.TxIn{ { PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash([32]byte{ 0xc3, 0x3e, 0xbf, 0xf2, 0xa7, 0x09, 0xf1, 0x3d, 0x9f, 0x9a, 0x75, 0x69, 0xab, 0x16, 0xa3, 0x27, 0x86, 0xaf, 0x7d, 0x7e, 0x2d, 0xe0, 0x92, 0x65, 0xe4, 0x1c, 0x61, 0xd0, 0x78, 0x29, 0x4e, 0xcf, }), Index: 1, }, SignatureScript: []byte{ 0x47, 0x30, 0x44, 0x02, 0x20, 0x03, 0x2d, 0x30, 0xdf, 0x5e, 0xe6, 0xf5, 0x7f, 0xa4, 0x6c, 0xdd, 0xb5, 0xeb, 0x8d, 0x0d, 0x9f, 0xe8, 0xde, 0x6b, 0x34, 0x2d, 0x27, 0x94, 0x2a, 0xe9, 0x0a, 0x32, 0x31, 0xe0, 0xba, 0x33, 0x3e, 0x02, 0x20, 0x3d, 0xee, 0xe8, 0x06, 0x0f, 0xdc, 0x70, 0x23, 0x0a, 0x7f, 0x5b, 0x4a, 0xd7, 0xd7, 0xbc, 0x3e, 0x62, 0x8c, 0xbe, 0x21, 0x9a, 0x88, 0x6b, 0x84, 0x26, 0x9e, 0xae, 0xb8, 0x1e, 0x26, 0xb4, 0xfe, 0x01, 0x41, 0x04, 0xae, 0x31, 0xc3, 0x1b, 0xf9, 0x12, 0x78, 0xd9, 0x9b, 0x83, 0x77, 0xa3, 0x5b, 0xbc, 0xe5, 0xb2, 0x7d, 0x9f, 0xff, 0x15, 0x45, 0x68, 0x39, 0xe9, 0x19, 0x45, 0x3f, 0xc7, 0xb3, 0xf7, 0x21, 0xf0, 0xba, 0x40, 0x3f, 0xf9, 0x6c, 0x9d, 0xee, 0xb6, 0x80, 0xe5, 0xfd, 0x34, 0x1c, 0x0f, 0xc3, 0xa7, 0xb9, 0x0d, 0xa4, 0x63, 0x1e, 0xe3, 0x95, 0x60, 0x63, 0x9d, 0xb4, 0x62, 0xe9, 0xcb, 0x85, 0x0f, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { Value: 0xf4240, PkScript: []byte{ 0x76, 0xa9, 0x14, 0xb0, 0xdc, 0xbf, 0x97, 0xea, 0xbf, 0x44, 0x04, 0xe3, 0x1d, 0x95, 0x24, 0x77, 0xce, 0x82, 0x2d, 0xad, 0xbe, 0x7e, 0x10, 0x88, 0xac, }, }, { Value: 0x11d260c0, PkScript: []byte{ 0x76, 0xa9, 0x14, 0x6b, 0x12, 0x81, 0xee, 0xc2, 0x5a, 0xb4, 0xe1, 0xe0, 0x79, 0x3f, 0xf4, 0xe0, 0x8a, 0xb1, 0xab, 0xb3, 0x40, 0x9c, 0xd9, 0x88, 0xac, }, }, }, LockTime: 0, }, { Version: 1, TxIn: []*wire.TxIn{ { PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash([32]byte{ 0x0b, 0x60, 0x72, 0xb3, 0x86, 0xd4, 0xa7, 0x73, 0x23, 0x52, 0x37, 0xf6, 0x4c, 0x11, 0x26, 0xac, 0x3b, 0x24, 0x0c, 0x84, 0xb9, 0x17, 0xa3, 0x90, 0x9b, 0xa1, 0xc4, 0x3d, 0xed, 0x5f, 0x51, 0xf4, }), Index: 0, }, SignatureScript: []byte{ 0x49, 0x30, 0x46, 0x02, 0x21, 0x00, 0xbb, 0x1a, 0xd2, 0x6d, 0xf9, 0x30, 0xa5, 0x1c, 0xce, 0x11, 0x0c, 0xf4, 0x4f, 0x7a, 0x48, 0xc3, 0xc5, 0x61, 0xfd, 0x97, 0x75, 0x00, 0xb1, 0xae, 0x5d, 0x6b, 0x6f, 0xd1, 0x3d, 0x0b, 0x3f, 0x4a, 0x02, 0x21, 0x00, 0xc5, 0xb4, 0x29, 0x51, 0xac, 0xed, 0xff, 0x14, 0xab, 0xba, 0x27, 0x36, 0xfd, 0x57, 0x4b, 0xdb, 0x46, 0x5f, 0x3e, 0x6f, 0x8d, 0xa1, 0x2e, 0x2c, 0x53, 0x03, 0x95, 0x4a, 0xca, 0x7f, 0x78, 0xf3, 0x01, 0x41, 0x04, 0xa7, 0x13, 0x5b, 0xfe, 0x82, 0x4c, 0x97, 0xec, 0xc0, 0x1e, 0xc7, 0xd7, 0xe3, 0x36, 0x18, 0x5c, 0x81, 0xe2, 0xaa, 0x2c, 0x41, 0xab, 0x17, 0x54, 0x07, 0xc0, 0x94, 0x84, 0xce, 0x96, 0x94, 0xb4, 0x49, 0x53, 0xfc, 0xb7, 0x51, 0x20, 0x65, 0x64, 0xa9, 0xc2, 0x4d, 0xd0, 0x94, 0xd4, 0x2f, 0xdb, 0xfd, 0xd5, 0xaa, 0xd3, 0xe0, 0x63, 0xce, 0x6a, 0xf4, 0xcf, 0xaa, 0xea, 0x4e, 0xa1, 0x4f, 0xbb, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { Value: 0xf4240, PkScript: []byte{ 0x76, 0xa9, 0x14, 0x39, 0xaa, 0x3d, 0x56, 0x9e, 0x06, 0xa1, 0xd7, 0x92, 0x6d, 0xc4, 0xbe, 0x11, 0x93, 0xc9, 0x9b, 0xf2, 0xeb, 0x9e, 0xe0, 0x88, 0xac, }, }, }, LockTime: 0, }, }, }
Block100000 defines block 100,000 of the block chain. It is used to test Block operations.
var Block181Bytes = []byte{}/* 490 elements not displayed */
Block181Bytes defines block 181 of the block chain (was helpful with my dataset). It is used to test Block operations.
var BlockOne = wire.MsgBlock{ Header: wire.BlockHeader{ Version: 1, PrevBlock: chainhash.Hash([chainhash.HashSize]byte{ 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, }), MerkleRoot: chainhash.Hash([chainhash.HashSize]byte{ 0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44, 0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67, 0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1, 0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, }), Timestamp: time.Unix(0x4966bc61, 0), Bits: 0x1d00ffff, Nonce: 0x9962e301, }, Transactions: []*wire.MsgTx{ { Version: 1, TxIn: []*wire.TxIn{ { PreviousOutPoint: wire.OutPoint{ Hash: chainhash.Hash{}, Index: 0xffffffff, }, SignatureScript: []byte{ 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, }, Sequence: 0xffffffff, }, }, TxOut: []*wire.TxOut{ { Value: 0x12a05f200, PkScript: []byte{ 0x41, 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c, 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16, 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c, 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c, 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4, 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 0xee, 0xac, }, }, }, LockTime: 0, }, }, }
BlockOne is the first block in the mainnet blockchain.
var BlockOneBytes = []byte{}/* 215 elements not displayed */
BlockOneBytes one serialized bytes.
Functions ¶
func ClientConfig ¶
func ClientConfig() *rpcclient.ConnConfig
ClientConfig returns bitcoin client config object
func CoinbaseValue ¶
CoinbaseValue returns the value the block should receive from a coinbase transaction based on number of halving happened due to block height
func GetFileParsed ¶
GetFileParsed returnes the file parsed so far
func PrepareTransactions ¶
PrepareTransactions parses the btcutil.TX array of structs and convert them in Transaction object compatible with dgraph schema TODO: here I have to provide a solution in case the parsed block contains transactions which spend each other, e.g a transaction has inputs spending output from a tx in the same block. In this case utxo are not found and txin is not prepared. To fix this I have to define the id of the transaction with interested output and link the culprit inputs through that it. The approach are two: 1) my current solution starts from the assumption that this situation is uncommon, so is better to handle it just in those uncommon cases 2) if this situation is more common than I though, well is better to check this condition before to start parsing the tx, so I'll refactor
Types ¶
type Block ¶
Block composition to enhance btcutil.Block with other receivers
func ExtractBlockFromFile ¶
ExtractBlockFromFile reads and remove magic bytes and size from file and returns Block through btcutil.NewBlockFromBytes
func (*Block) CheckBlock ¶
CheckBlock checks if block is correctly initialized just checking hash and height fields have some value
type Blockchain ¶
type Blockchain struct { Maps []mmap.MMap Network chaincfg.Params // contains filtered or unexported fields }
Blockchain data structure composed by the memory mapped files in array of mmaps and network conofiguration
func NewBlockchain ¶
func NewBlockchain(db kv.DB, network chaincfg.Params) *Blockchain
NewBlockchain singleton pattern return always the same instance of blockchain. In the first time initializes the blockchain
func (*Blockchain) Head ¶
func (b *Blockchain) Head() (last block.Block, err error)
Head returns the last block in the blockchain
func (*Blockchain) Height ¶
func (b *Blockchain) Height() (h int32, err error)
Height returns the height of the last block in the blockchain (currently synced)
type CheckPoint ¶
type CheckPoint struct {
// contains filtered or unexported fields
}
CheckPoint represents the last parse state
func ParseFile ¶
func ParseFile(p *Parser, c CheckPoint, file *[]uint8) (check CheckPoint, err error)
ParseFile walks through the raw file and extract blocks
type InputParser ¶
InputParser worker wrapper for parsing inputs in sync pool
func (*InputParser) Work ¶
func (w *InputParser) Work() (err error)
Work interface to execute input parser worker operations
type OutputParser ¶
OutputParser worker wrapper for parsing inputs in sync pool
func (*OutputParser) Work ¶
func (w *OutputParser) Work() (err error)
Work interface to execute output parser worker operations
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser defines the objects involved in the parsing of Bitcoin blockchain The involved objects include the parsed structure, the kind of parser, storage instances and some channel to manage the state of the parsing session
func NewParser ¶
func NewParser(blockchain *Blockchain, client *rpcclient.Client, db kv.DB, skipped *Skipped, utxoset *utxoset.UtxoSet, c *cache.Cache, interrupt chan int) Parser
NewParser return a new instance to Bitcoin blockchai parser
func (*Parser) FindCheckPoint ¶
func (p *Parser) FindCheckPoint(rawChain [][]uint8) (check CheckPoint, err error)
FindCheckPoint restores the parsed files' state from last parsing and return a CheckPoint instance the keep parsing
func (*Parser) InfinitelyParse ¶
InfinitelyParse parses the blockchain starting from scratch when it reaches the end in order to implement a real time mechanism
type Skipped ¶
type Skipped struct {
// contains filtered or unexported fields
}
Skipped instance of key value store designed to treat block structs
func (*Skipped) DeleteBlock ¶
DeleteBlock inserts in the db the block as []byte passed
func (*Skipped) GetBlock ¶
GetBlock returns a *Block looking for the block corresponding to the hash passed
func (*Skipped) GetStoredBlocks ¶
GetStoredBlocks is an utility functions that returns the list of stored blocks hash
func (*Skipped) IsStored ¶
IsStored returns true if the block corresponding to passed hash is stored in db
func (*Skipped) StoreBlock ¶
StoreBlock inserts in the db the block as []byte passed
func (*Skipped) StoreBlockPrevHash ¶
StoreBlockPrevHash inserts in the db the block as []byte passed, using the previous hash as key
type TransactionsParser ¶
TransactionsParser worker wrapper for parsing transactions in sync pool
func (*TransactionsParser) Work ¶
func (w *TransactionsParser) Work() (err error)
Work interface to execute transactions parser worker operations
type Tx ¶
Tx transaction type
func (*Tx) IsCoinbase ¶
IsCoinbase returns true if the transaction is a coinbase transaction
func (*Tx) IsCoinjoin ¶
IsCoinjoin returns true is the tx is a coinjoin transaction