Introduce BitcoinType and EthereumType distinction of blockchains

This commit is contained in:
Martin Boehm 2018-11-06 18:41:13 +01:00
parent 13acef41d4
commit 38ba033654
15 changed files with 112 additions and 99 deletions

View File

@ -125,9 +125,9 @@ func (p *BaseParser) UnpackBlockHash(buf []byte) (string, error) {
return hex.EncodeToString(buf), nil
}
// IsUTXOChain returns true if the block chain is UTXO type, otherwise false
func (p *BaseParser) IsUTXOChain() bool {
return true
// GetChainType is type of the blockchain, default is ChainBitcoinType
func (p *BaseParser) GetChainType() ChainType {
return ChainBitcoinType
}
// PackTx packs transaction to byte array using protobuf

View File

@ -27,7 +27,7 @@ type BitcoinRPC struct {
Parser bchain.BlockChainParser
Testnet bool
Network string
Mempool *bchain.UTXOMempool
Mempool *bchain.MempoolBitcoinType
ParseBlocks bool
pushHandler func(bchain.NotificationType)
mq *bchain.MQ
@ -115,7 +115,7 @@ func (b *BitcoinRPC) GetChainInfoAndInitializeMempool(bc bchain.BlockChain) (str
}
b.mq = mq
b.Mempool = bchain.NewUTXOMempool(bc, b.ChainConfig.MempoolWorkers, b.ChainConfig.MempoolSubWorkers)
b.Mempool = bchain.NewMempoolBitcoinType(bc, b.ChainConfig.MempoolWorkers, b.ChainConfig.MempoolSubWorkers)
return chainName, nil
}

View File

@ -7,12 +7,10 @@ import (
"math/big"
"strconv"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/golang/protobuf/proto"
"github.com/juju/errors"
ethcommon "github.com/ethereum/go-ethereum/common"
)
// EthereumParser handle
@ -293,7 +291,7 @@ func (p *EthereumParser) UnpackBlockHash(buf []byte) (string, error) {
return hexutil.Encode(buf), nil
}
// IsUTXOChain returns true if the block chain is UTXO type, otherwise false
func (p *EthereumParser) IsUTXOChain() bool {
return false
// GetChainType returns TypeEthereum
func (p *EthereumParser) GetChainType() bchain.ChainType {
return bchain.ChainEthereumType
}

View File

@ -45,7 +45,7 @@ type EthereumRPC struct {
Parser *EthereumParser
Testnet bool
Network string
Mempool *bchain.NonUTXOMempool
Mempool *bchain.MempoolEthereumType
bestHeaderMu sync.Mutex
bestHeader *ethtypes.Header
bestHeaderTime time.Time
@ -185,7 +185,7 @@ func (b *EthereumRPC) Initialize() error {
}
// create mempool
b.Mempool = bchain.NewNonUTXOMempool(b)
b.Mempool = bchain.NewMempoolEthereumType(b)
return nil
}

View File

@ -23,8 +23,8 @@ type txidio struct {
io []addrIndex
}
// UTXOMempool is mempool handle.
type UTXOMempool struct {
// MempoolBitcoinType is mempool handle.
type MempoolBitcoinType struct {
chain BlockChain
mux sync.Mutex
txToInputOutput map[string][]addrIndex
@ -34,10 +34,10 @@ type UTXOMempool struct {
onNewTxAddr OnNewTxAddrFunc
}
// NewUTXOMempool creates new mempool handler.
// NewMempoolBitcoinType creates new mempool handler.
// For now there is no cleanup of sync routines, the expectation is that the mempool is created only once per process
func NewUTXOMempool(chain BlockChain, workers int, subworkers int) *UTXOMempool {
m := &UTXOMempool{
func NewMempoolBitcoinType(chain BlockChain, workers int, subworkers int) *MempoolBitcoinType {
m := &MempoolBitcoinType{
chain: chain,
chanTxid: make(chan string, 1),
chanAddrIndex: make(chan txidio, 1),
@ -68,7 +68,7 @@ func NewUTXOMempool(chain BlockChain, workers int, subworkers int) *UTXOMempool
}
// GetTransactions returns slice of mempool transactions for given address
func (m *UTXOMempool) GetTransactions(address string) ([]string, error) {
func (m *MempoolBitcoinType) GetTransactions(address string) ([]string, error) {
parser := m.chain.GetChainParser()
addrDesc, err := parser.GetAddrDescFromAddress(address)
if err != nil {
@ -78,7 +78,7 @@ func (m *UTXOMempool) GetTransactions(address string) ([]string, error) {
}
// GetAddrDescTransactions returns slice of mempool transactions for given address descriptor
func (m *UTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
func (m *MempoolBitcoinType) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
m.mux.Lock()
defer m.mux.Unlock()
outpoints := m.addrDescToTx[string(addrDesc)]
@ -89,14 +89,14 @@ func (m *UTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]str
return txs, nil
}
func (m *UTXOMempool) updateMappings(newTxToInputOutput map[string][]addrIndex, newAddrDescToTx map[string][]outpoint) {
func (m *MempoolBitcoinType) updateMappings(newTxToInputOutput map[string][]addrIndex, newAddrDescToTx map[string][]outpoint) {
m.mux.Lock()
defer m.mux.Unlock()
m.txToInputOutput = newTxToInputOutput
m.addrDescToTx = newAddrDescToTx
}
func (m *UTXOMempool) getInputAddress(input outpoint) *addrIndex {
func (m *MempoolBitcoinType) getInputAddress(input outpoint) *addrIndex {
itx, err := m.chain.GetTransactionForMempool(input.txid)
if err != nil {
glog.Error("cannot get transaction ", input.txid, ": ", err)
@ -115,7 +115,7 @@ func (m *UTXOMempool) getInputAddress(input outpoint) *addrIndex {
}
func (m *UTXOMempool) getTxAddrs(txid string, chanInput chan outpoint, chanResult chan *addrIndex) ([]addrIndex, bool) {
func (m *MempoolBitcoinType) getTxAddrs(txid string, chanInput chan outpoint, chanResult chan *addrIndex) ([]addrIndex, bool) {
tx, err := m.chain.GetTransactionForMempool(txid)
if err != nil {
glog.Error("cannot get transaction ", txid, ": ", err)
@ -170,7 +170,7 @@ func (m *UTXOMempool) getTxAddrs(txid string, chanInput chan outpoint, chanResul
// Resync gets mempool transactions and maps outputs to transactions.
// Resync is not reentrant, it should be called from a single thread.
// Read operations (GetTransactions) are safe.
func (m *UTXOMempool) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) {
func (m *MempoolBitcoinType) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) {
start := time.Now()
glog.V(1).Info("mempool: resync")
m.onNewTxAddr = onNewTxAddr

View File

@ -7,21 +7,21 @@ import (
"github.com/golang/glog"
)
// NonUTXOMempool is mempool handle of non UTXO chains
type NonUTXOMempool struct {
// MempoolEthereumType is mempool handle of EthereumType chains
type MempoolEthereumType struct {
chain BlockChain
mux sync.Mutex
txToInputOutput map[string][]addrIndex
addrDescToTx map[string][]outpoint
}
// NewNonUTXOMempool creates new mempool handler.
func NewNonUTXOMempool(chain BlockChain) *NonUTXOMempool {
return &NonUTXOMempool{chain: chain}
// NewMempoolEthereumType creates new mempool handler.
func NewMempoolEthereumType(chain BlockChain) *MempoolEthereumType {
return &MempoolEthereumType{chain: chain}
}
// GetTransactions returns slice of mempool transactions for given address
func (m *NonUTXOMempool) GetTransactions(address string) ([]string, error) {
func (m *MempoolEthereumType) GetTransactions(address string) ([]string, error) {
parser := m.chain.GetChainParser()
addrDesc, err := parser.GetAddrDescFromAddress(address)
if err != nil {
@ -31,7 +31,7 @@ func (m *NonUTXOMempool) GetTransactions(address string) ([]string, error) {
}
// GetAddrDescTransactions returns slice of mempool transactions for given address descriptor
func (m *NonUTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
func (m *MempoolEthereumType) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]string, error) {
m.mux.Lock()
defer m.mux.Unlock()
outpoints := m.addrDescToTx[string(addrDesc)]
@ -42,7 +42,7 @@ func (m *NonUTXOMempool) GetAddrDescTransactions(addrDesc AddressDescriptor) ([]
return txs, nil
}
func (m *NonUTXOMempool) updateMappings(newTxToInputOutput map[string][]addrIndex, newAddrDescToTx map[string][]outpoint) {
func (m *MempoolEthereumType) updateMappings(newTxToInputOutput map[string][]addrIndex, newAddrDescToTx map[string][]outpoint) {
m.mux.Lock()
defer m.mux.Unlock()
m.txToInputOutput = newTxToInputOutput
@ -52,7 +52,7 @@ func (m *NonUTXOMempool) updateMappings(newTxToInputOutput map[string][]addrInde
// Resync gets mempool transactions and maps outputs to transactions.
// Resync is not reentrant, it should be called from a single thread.
// Read operations (GetTransactions) are safe.
func (m *NonUTXOMempool) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) {
func (m *MempoolEthereumType) Resync(onNewTxAddr OnNewTxAddrFunc) (int, error) {
start := time.Now()
glog.V(1).Info("Mempool: resync")
txs, err := m.chain.GetMempool()

View File

@ -9,6 +9,16 @@ import (
"math/big"
)
// ChainType is type of the blockchain
type ChainType int
const (
// ChainBitcoinType is blockchain derived from bitcoin
ChainBitcoinType = ChainType(iota)
// TypeEthereum is blockchain derived from ethereum
ChainEthereumType
)
// errors with specific meaning returned by blockchain rpc
var (
// ErrBlockNotFound is returned when block is not found
@ -23,11 +33,13 @@ var (
ErrTxidMissing = errors.New("Txid missing")
)
// ScriptSig contains data about input script
type ScriptSig struct {
// Asm string `json:"asm"`
Hex string `json:"hex"`
}
// Vin contains data about tx output
type Vin struct {
Coinbase string `json:"coinbase"`
Txid string `json:"txid"`
@ -37,6 +49,7 @@ type Vin struct {
Addresses []string `json:"addresses"`
}
// ScriptPubKey contains data about output script
type ScriptPubKey struct {
// Asm string `json:"asm"`
Hex string `json:"hex,omitempty"`
@ -44,6 +57,7 @@ type ScriptPubKey struct {
Addresses []string `json:"addresses"`
}
// Vout contains data about tx output
type Vout struct {
ValueSat big.Int
JsonValue json.Number `json:"value"`
@ -66,6 +80,7 @@ type Tx struct {
Blocktime int64 `json:"blocktime,omitempty"`
}
// Block is block header and list of transactions
type Block struct {
BlockHeader
Txs []Tx `json:"tx"`
@ -93,6 +108,7 @@ type BlockInfo struct {
Txids []string `json:"tx,omitempty"`
}
// MempoolEntry is used to get data about mempool entry
type MempoolEntry struct {
Size uint32 `json:"size"`
FeeSat big.Int
@ -110,6 +126,7 @@ type MempoolEntry struct {
Depends []string `json:"depends"`
}
// ChainInfo is used to get information about blockchain
type ChainInfo struct {
Chain string `json:"chain"`
Blocks int `json:"blocks"`
@ -124,6 +141,7 @@ type ChainInfo struct {
Warnings string `json:"warnings"`
}
// RPCError defines rpc error returned by backend
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
@ -182,13 +200,10 @@ type BlockChain interface {
// BlockChainParser defines common interface to parsing and conversions of block chain data
type BlockChainParser interface {
// chain configuration description
// UTXO chains need "inputs" column in db, that map transactions to transactions that spend them
// non UTXO chains have mapping of address to input and output transactions directly in "outputs" column in db
IsUTXOChain() bool
// KeepBlockAddresses returns number of blocks which are to be kept in blockaddresses column
// and used in case of fork
// if 0 the blockaddresses column is not used at all (usually non UTXO chains)
// type of the blockchain
GetChainType() ChainType
// KeepBlockAddresses returns number of blocks which are to be kept in blockTxs column
// to be used for rollbacks
KeepBlockAddresses() int
// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
AmountToDecimalString(a *big.Int) string

View File

@ -22,7 +22,7 @@ type bulkAddresses struct {
// BulkConnect is used to connect blocks in bulk, faster but if interrupted inconsistent way
type BulkConnect struct {
d *RocksDB
isUTXO bool
chainType bchain.ChainType
bulkAddresses []bulkAddresses
bulkAddressesCount int
txAddressesMap map[string]*TxAddresses
@ -42,7 +42,7 @@ const (
func (d *RocksDB) InitBulkConnect() (*BulkConnect, error) {
bc := &BulkConnect{
d: d,
isUTXO: d.chainParser.IsUTXOChain(),
chainType: d.chainParser.GetChainType(),
txAddressesMap: make(map[string]*TxAddresses),
balances: make(map[string]*AddrBalance),
}
@ -168,11 +168,12 @@ func (b *BulkConnect) storeBulkAddresses(wb *gorocksdb.WriteBatch) error {
// ConnectBlock connects block in bulk mode
func (b *BulkConnect) ConnectBlock(block *bchain.Block, storeBlockTxs bool) error {
b.height = block.Height
if !b.isUTXO {
// for non bitcoin types connect blocks in non bulk mode
if b.chainType != bchain.ChainBitcoinType {
return b.d.ConnectBlock(block)
}
addresses := make(map[string][]outpoint)
if err := b.d.processAddressesUTXO(block, addresses, b.txAddressesMap, b.balances); err != nil {
if err := b.d.processAddressesBitcoinType(block, addresses, b.txAddressesMap, b.balances); err != nil {
return err
}
var storeAddressesChan, storeBalancesChan chan error

View File

@ -271,21 +271,21 @@ func (d *RocksDB) writeBlock(block *bchain.Block, op int) error {
}
}
isUTXO := d.chainParser.IsUTXOChain()
chainType := d.chainParser.GetChainType()
if err := d.writeHeightFromBlock(wb, block, op); err != nil {
return err
}
if isUTXO {
if chainType == bchain.ChainBitcoinType {
if op == opDelete {
// block does not contain mapping tx-> input address, which is necessary to recreate
// unspentTxs; therefore it is not possible to DisconnectBlocks this way
return errors.New("DisconnectBlock is not supported for UTXO chains")
return errors.New("DisconnectBlock is not supported for BitcoinType chains")
}
addresses := make(map[string][]outpoint)
txAddressesMap := make(map[string]*TxAddresses)
balances := make(map[string]*AddrBalance)
if err := d.processAddressesUTXO(block, addresses, txAddressesMap, balances); err != nil {
if err := d.processAddressesBitcoinType(block, addresses, txAddressesMap, balances); err != nil {
return err
}
if err := d.storeAddresses(wb, block.Height, addresses); err != nil {
@ -300,8 +300,8 @@ func (d *RocksDB) writeBlock(block *bchain.Block, op int) error {
if err := d.storeAndCleanupBlockTxs(wb, block); err != nil {
return err
}
} else {
if err := d.writeAddressesNonUTXO(wb, block, op); err != nil {
} else if chainType == bchain.ChainEthereumType {
if err := d.writeAddressesTypeEthereum(wb, block, op); err != nil {
return err
}
}
@ -375,7 +375,7 @@ func (d *RocksDB) GetAndResetConnectBlockStats() string {
return s
}
func (d *RocksDB) processAddressesUTXO(block *bchain.Block, addresses map[string][]outpoint, txAddressesMap map[string]*TxAddresses, balances map[string]*AddrBalance) error {
func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses map[string][]outpoint, txAddressesMap map[string]*TxAddresses, balances map[string]*AddrBalance) error {
blockTxIDs := make([][]byte, len(block.Txs))
blockTxAddresses := make([]*TxAddresses, len(block.Txs))
// first process all outputs so that inputs can point to txs in this block
@ -861,7 +861,7 @@ func (d *RocksDB) addAddrDescToRecords(op int, wb *gorocksdb.WriteBatch, records
return nil
}
func (d *RocksDB) writeAddressesNonUTXO(wb *gorocksdb.WriteBatch, block *bchain.Block, op int) error {
func (d *RocksDB) writeAddressesTypeEthereum(wb *gorocksdb.WriteBatch, block *bchain.Block, op int) error {
addresses := make(map[string][]outpoint)
for _, tx := range block.Txs {
btxID, err := d.chainParser.PackTxid(tx.Txid)
@ -1166,9 +1166,9 @@ func (d *RocksDB) disconnectTxAddresses(wb *gorocksdb.WriteBatch, height uint32,
return nil
}
// DisconnectBlockRangeUTXO removes all data belonging to blocks in range lower-higher
// DisconnectBlockRangeBitcoinType removes all data belonging to blocks in range lower-higher
// if they are in the range kept in the cfBlockTxids column
func (d *RocksDB) DisconnectBlockRangeUTXO(lower uint32, higher uint32) error {
func (d *RocksDB) DisconnectBlockRangeBitcoinType(lower uint32, higher uint32) error {
glog.Infof("db: disconnecting blocks %d-%d", lower, higher)
blocks := make([][]blockTxs, higher-lower+1)
for height := lower; height <= higher; height++ {

View File

@ -1,4 +1,4 @@
// +build unittest
// build unittest
package db
@ -151,7 +151,7 @@ func checkColumn(d *RocksDB, col int, kp []keyPair) error {
return nil
}
func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, afterDisconnect bool) {
func verifyAfterBitcoinTypeOBlock1(t *testing.T, d *RocksDB, afterDisconnect bool) {
if err := checkColumn(d, cfHeight, []keyPair{
keyPair{
"000370d5",
@ -232,7 +232,7 @@ func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, afterDisconnect bool) {
}
}
func verifyAfterUTXOBlock2(t *testing.T, d *RocksDB) {
func verifyAfterBitcoinTypeBlock2(t *testing.T, d *RocksDB) {
if err := checkColumn(d, cfHeight, []keyPair{
keyPair{
"000370d5",
@ -423,7 +423,7 @@ func testTxCache(t *testing.T, d *RocksDB, b *bchain.Block, tx *bchain.Tx) {
}
}
// TestRocksDB_Index_UTXO is an integration test probing the whole indexing functionality for UTXO chains
// TestRocksDB_Index_BitcoinType is an integration test probing the whole indexing functionality for BitcoinType chains
// It does the following:
// 1) Connect two blocks (inputs from 2nd block are spending some outputs from the 1st block)
// 2) GetTransactions for various addresses / low-high ranges
@ -433,25 +433,25 @@ func testTxCache(t *testing.T, d *RocksDB, b *bchain.Block, tx *bchain.Tx) {
// 6) Disconnect the block 2 using BlockTxs column
// 7) Reconnect block 2 and check
// After each step, the content of DB is examined and any difference against expected state is regarded as failure
func TestRocksDB_Index_UTXO(t *testing.T) {
func TestRocksDB_Index_BitcoinType(t *testing.T) {
d := setupRocksDB(t, &testBitcoinParser{
BitcoinParser: bitcoinTestnetParser(),
})
defer closeAndDestroyRocksDB(t, d)
// connect 1st block - will log warnings about missing UTXO transactions in txAddresses column
block1 := dbtestdata.GetTestUTXOBlock1(d.chainParser)
block1 := dbtestdata.GetTestBitcoinTypeBlock1(d.chainParser)
if err := d.ConnectBlock(block1); err != nil {
t.Fatal(err)
}
verifyAfterUTXOBlock1(t, d, false)
verifyAfterBitcoinTypeOBlock1(t, d, false)
// connect 2nd block - use some outputs from the 1st block as the inputs and 1 input uses tx from the same block
block2 := dbtestdata.GetTestUTXOBlock2(d.chainParser)
block2 := dbtestdata.GetTestBitcoinTypeBlock2(d.chainParser)
if err := d.ConnectBlock(block2); err != nil {
t.Fatal(err)
}
verifyAfterUTXOBlock2(t, d)
verifyAfterBitcoinTypeBlock2(t, d)
// get transactions for various addresses / low-high ranges
verifyGetTransactions(t, d, dbtestdata.Addr2, 0, 1000000, []txidVoutOutput{
@ -532,27 +532,27 @@ func TestRocksDB_Index_UTXO(t *testing.T) {
}
}
// DisconnectBlock for UTXO chains is not possible
// DisconnectBlock for BitcoinType chains is not possible
err = d.DisconnectBlock(block2)
if err == nil || err.Error() != "DisconnectBlock is not supported for UTXO chains" {
if err == nil || err.Error() != "DisconnectBlock is not supported for BitcoinType chains" {
t.Fatal(err)
}
verifyAfterUTXOBlock2(t, d)
verifyAfterBitcoinTypeBlock2(t, d)
// try to disconnect both blocks, however only the last one is kept, it is not possible
err = d.DisconnectBlockRangeUTXO(225493, 225494)
err = d.DisconnectBlockRangeBitcoinType(225493, 225494)
if err == nil || err.Error() != "Cannot disconnect blocks with height 225493 and lower. It is necessary to rebuild index." {
t.Fatal(err)
}
verifyAfterUTXOBlock2(t, d)
verifyAfterBitcoinTypeBlock2(t, d)
// disconnect the 2nd block, verify that the db contains only data from the 1st block with restored unspentTxs
// and that the cached tx is removed
err = d.DisconnectBlockRangeUTXO(225494, 225494)
err = d.DisconnectBlockRangeBitcoinType(225494, 225494)
if err != nil {
t.Fatal(err)
}
verifyAfterUTXOBlock1(t, d, true)
verifyAfterBitcoinTypeOBlock1(t, d, true)
if err := checkColumn(d, cfTransactions, []keyPair{}); err != nil {
{
t.Fatal(err)
@ -563,7 +563,7 @@ func TestRocksDB_Index_UTXO(t *testing.T) {
if err := d.ConnectBlock(block2); err != nil {
t.Fatal(err)
}
verifyAfterUTXOBlock2(t, d)
verifyAfterBitcoinTypeBlock2(t, d)
// test public methods for address balance and tx addresses
@ -627,7 +627,7 @@ func TestRocksDB_Index_UTXO(t *testing.T) {
}
func Test_BulkConnect_UTXO(t *testing.T) {
func Test_BulkConnect_BitcoinType(t *testing.T) {
d := setupRocksDB(t, &testBitcoinParser{
BitcoinParser: bitcoinTestnetParser(),
})
@ -642,7 +642,7 @@ func Test_BulkConnect_UTXO(t *testing.T) {
t.Fatal("DB not in DbStateInconsistent")
}
if err := bc.ConnectBlock(dbtestdata.GetTestUTXOBlock1(d.chainParser), false); err != nil {
if err := bc.ConnectBlock(dbtestdata.GetTestBitcoinTypeBlock1(d.chainParser), false); err != nil {
t.Fatal(err)
}
if err := checkColumn(d, cfBlockTxs, []keyPair{}); err != nil {
@ -651,7 +651,7 @@ func Test_BulkConnect_UTXO(t *testing.T) {
}
}
if err := bc.ConnectBlock(dbtestdata.GetTestUTXOBlock2(d.chainParser), true); err != nil {
if err := bc.ConnectBlock(dbtestdata.GetTestBitcoinTypeBlock2(d.chainParser), true); err != nil {
t.Fatal(err)
}
@ -663,7 +663,7 @@ func Test_BulkConnect_UTXO(t *testing.T) {
t.Fatal("DB not in DbStateOpen")
}
verifyAfterUTXOBlock2(t, d)
verifyAfterBitcoinTypeBlock2(t, d)
}
func Test_packBigint_unpackBigint(t *testing.T) {

View File

@ -393,9 +393,9 @@ func (w *SyncWorker) getBlockChain(out chan blockResult, done chan struct{}) {
// DisconnectBlocks removes all data belonging to blocks in range lower-higher,
func (w *SyncWorker) DisconnectBlocks(lower uint32, higher uint32, hashes []string) error {
glog.Infof("sync: disconnecting blocks %d-%d", lower, higher)
// if the chain is UTXO, always use DisconnectBlockRange
if w.chain.GetChainParser().IsUTXOChain() {
return w.db.DisconnectBlockRangeUTXO(lower, higher)
// if the chain is ChainBitcoinType, always use DisconnectBlockRange
if w.chain.GetChainParser().GetChainType() == bchain.ChainBitcoinType {
return w.db.DisconnectBlockRangeBitcoinType(lower, higher)
}
blocks := make([]*bchain.Block, len(hashes))
var err error

View File

@ -86,8 +86,8 @@ Good examples of coin configuration are
* `parse` Use binary parser for block decoding if *true* else call verbose back-end RPC method that returns
JSON. Note that verbose method is slow and not every coin support it. However there are coin implementations
that don't support binary parsing (e.g. ZCash).
* `mempool_workers` Number of workers for UTXO mempool.
* `mempool_sub_workers` Number of subworkers for UTXO mempool.
* `mempool_workers` Number of workers for BitcoinType mempool.
* `mempool_sub_workers` Number of subworkers for BitcoinType mempool.
* `block_addresses_to_keep` Number of blocks that are to be kept in blockaddresses column.
* `additional_params` Object of coin-specific params.

View File

@ -48,10 +48,10 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *c
}
d.SetInternalState(is)
// import data
if err := d.ConnectBlock(dbtestdata.GetTestUTXOBlock1(parser)); err != nil {
if err := d.ConnectBlock(dbtestdata.GetTestBitcoinTypeBlock1(parser)); err != nil {
t.Fatal(err)
}
if err := d.ConnectBlock(dbtestdata.GetTestUTXOBlock2(parser)); err != nil {
if err := d.ConnectBlock(dbtestdata.GetTestBitcoinTypeBlock2(parser)); err != nil {
t.Fatal(err)
}
return d, is, tmp
@ -575,7 +575,7 @@ func socketioTests(t *testing.T, ts *httptest.Server) {
}
}
func Test_PublicServer_UTXO(t *testing.T) {
func Test_PublicServer_BitcoinType(t *testing.T) {
s, dbpath := setupPublicHTTPServer(t)
defer closeAndDestroyPublicServer(t, s, dbpath)
s.ConnectFullPublicInterface()
@ -585,5 +585,4 @@ func Test_PublicServer_UTXO(t *testing.T) {
httpTests(t, ts)
socketioTests(t, ts)
}

View File

@ -54,7 +54,7 @@ func AddressToPubKeyHex(addr string, parser bchain.BlockChainParser) string {
return hex.EncodeToString(b)
}
func GetTestUTXOBlock1(parser bchain.BlockChainParser) *bchain.Block {
func GetTestBitcoinTypeBlock1(parser bchain.BlockChainParser) *bchain.Block {
return &bchain.Block{
BlockHeader: bchain.BlockHeader{
Height: 225493,
@ -119,7 +119,7 @@ func GetTestUTXOBlock1(parser bchain.BlockChainParser) *bchain.Block {
}
}
func GetTestUTXOBlock2(parser bchain.BlockChainParser) *bchain.Block {
func GetTestBitcoinTypeBlock2(parser bchain.BlockChainParser) *bchain.Block {
return &bchain.Block{
BlockHeader: bchain.BlockHeader{
Height: 225494,

View File

@ -45,26 +45,26 @@ func (c *fakeBlockChain) GetChainInfo() (v *bchain.ChainInfo, err error) {
Chain: c.GetNetworkName(),
Blocks: 2,
Headers: 2,
Bestblockhash: GetTestUTXOBlock2(c.parser).BlockHeader.Hash,
Bestblockhash: GetTestBitcoinTypeBlock2(c.parser).BlockHeader.Hash,
Version: "001001",
Subversion: c.GetSubversion(),
}, nil
}
func (c *fakeBlockChain) GetBestBlockHash() (v string, err error) {
return GetTestUTXOBlock2(c.parser).BlockHeader.Hash, nil
return GetTestBitcoinTypeBlock2(c.parser).BlockHeader.Hash, nil
}
func (c *fakeBlockChain) GetBestBlockHeight() (v uint32, err error) {
return GetTestUTXOBlock2(c.parser).BlockHeader.Height, nil
return GetTestBitcoinTypeBlock2(c.parser).BlockHeader.Height, nil
}
func (c *fakeBlockChain) GetBlockHash(height uint32) (v string, err error) {
b1 := GetTestUTXOBlock1(c.parser)
b1 := GetTestBitcoinTypeBlock1(c.parser)
if height == b1.BlockHeader.Height {
return b1.BlockHeader.Hash, nil
}
b2 := GetTestUTXOBlock2(c.parser)
b2 := GetTestBitcoinTypeBlock2(c.parser)
if height == b2.BlockHeader.Height {
return b2.BlockHeader.Hash, nil
}
@ -72,11 +72,11 @@ func (c *fakeBlockChain) GetBlockHash(height uint32) (v string, err error) {
}
func (c *fakeBlockChain) GetBlockHeader(hash string) (v *bchain.BlockHeader, err error) {
b1 := GetTestUTXOBlock1(c.parser)
b1 := GetTestBitcoinTypeBlock1(c.parser)
if hash == b1.BlockHeader.Hash {
return &b1.BlockHeader, nil
}
b2 := GetTestUTXOBlock2(c.parser)
b2 := GetTestBitcoinTypeBlock2(c.parser)
if hash == b2.BlockHeader.Hash {
return &b2.BlockHeader, nil
}
@ -84,11 +84,11 @@ func (c *fakeBlockChain) GetBlockHeader(hash string) (v *bchain.BlockHeader, err
}
func (c *fakeBlockChain) GetBlock(hash string, height uint32) (v *bchain.Block, err error) {
b1 := GetTestUTXOBlock1(c.parser)
b1 := GetTestBitcoinTypeBlock1(c.parser)
if hash == b1.BlockHeader.Hash || height == b1.BlockHeader.Height {
return b1, nil
}
b2 := GetTestUTXOBlock2(c.parser)
b2 := GetTestBitcoinTypeBlock2(c.parser)
if hash == b2.BlockHeader.Hash || height == b2.BlockHeader.Height {
return b2, nil
}
@ -106,11 +106,11 @@ func getBlockInfo(b *bchain.Block) *bchain.BlockInfo {
}
func (c *fakeBlockChain) GetBlockInfo(hash string) (v *bchain.BlockInfo, err error) {
b1 := GetTestUTXOBlock1(c.parser)
b1 := GetTestBitcoinTypeBlock1(c.parser)
if hash == b1.BlockHeader.Hash {
return getBlockInfo(b1), nil
}
b2 := GetTestUTXOBlock2(c.parser)
b2 := GetTestBitcoinTypeBlock2(c.parser)
if hash == b2.BlockHeader.Hash {
return getBlockInfo(b2), nil
}
@ -131,9 +131,9 @@ func getTxInBlock(b *bchain.Block, txid string) *bchain.Tx {
}
func (c *fakeBlockChain) GetTransaction(txid string) (v *bchain.Tx, err error) {
v = getTxInBlock(GetTestUTXOBlock1(c.parser), txid)
v = getTxInBlock(GetTestBitcoinTypeBlock1(c.parser), txid)
if v == nil {
v = getTxInBlock(GetTestUTXOBlock2(c.parser), txid)
v = getTxInBlock(GetTestBitcoinTypeBlock2(c.parser), txid)
}
if v != nil {
return v, nil