From 4448c57ba8058358ea879446794de4adc4c036da Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Tue, 6 Nov 2018 18:41:13 +0100 Subject: [PATCH] Introduce BitcoinType and EthereumType distinction of blockchains --- bchain/baseparser.go | 6 +-- bchain/coins/btc/bitcoinrpc.go | 4 +- bchain/coins/eth/ethparser.go | 10 ++--- bchain/coins/eth/ethrpc.go | 4 +- ...empool_utxo.go => mempool_bitcoin_type.go} | 22 +++++----- ...ol_nonutxo.go => mempool_ethereum_type.go} | 18 ++++---- bchain/types.go | 29 +++++++++---- db/bulkconnect.go | 9 ++-- db/rocksdb.go | 20 ++++----- db/rocksdb_test.go | 42 +++++++++---------- db/sync.go | 6 +-- docs/config.md | 4 +- server/public_test.go | 7 ++-- tests/dbtestdata/dbtestdata.go | 4 +- tests/dbtestdata/fakechain.go | 26 ++++++------ 15 files changed, 112 insertions(+), 99 deletions(-) rename bchain/{mempool_utxo.go => mempool_bitcoin_type.go} (86%) rename bchain/{mempool_nonutxo.go => mempool_ethereum_type.go} (81%) diff --git a/bchain/baseparser.go b/bchain/baseparser.go index 48bb752e..d8a878ae 100644 --- a/bchain/baseparser.go +++ b/bchain/baseparser.go @@ -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 diff --git a/bchain/coins/btc/bitcoinrpc.go b/bchain/coins/btc/bitcoinrpc.go index 9e978743..8b69e8a2 100644 --- a/bchain/coins/btc/bitcoinrpc.go +++ b/bchain/coins/btc/bitcoinrpc.go @@ -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 } diff --git a/bchain/coins/eth/ethparser.go b/bchain/coins/eth/ethparser.go index d76aa6bf..90341cd5 100644 --- a/bchain/coins/eth/ethparser.go +++ b/bchain/coins/eth/ethparser.go @@ -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 } diff --git a/bchain/coins/eth/ethrpc.go b/bchain/coins/eth/ethrpc.go index 8be6e5ea..b1faa435 100644 --- a/bchain/coins/eth/ethrpc.go +++ b/bchain/coins/eth/ethrpc.go @@ -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 } diff --git a/bchain/mempool_utxo.go b/bchain/mempool_bitcoin_type.go similarity index 86% rename from bchain/mempool_utxo.go rename to bchain/mempool_bitcoin_type.go index 86fe6a5e..6cd30a24 100644 --- a/bchain/mempool_utxo.go +++ b/bchain/mempool_bitcoin_type.go @@ -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 diff --git a/bchain/mempool_nonutxo.go b/bchain/mempool_ethereum_type.go similarity index 81% rename from bchain/mempool_nonutxo.go rename to bchain/mempool_ethereum_type.go index c0151c50..08484135 100644 --- a/bchain/mempool_nonutxo.go +++ b/bchain/mempool_ethereum_type.go @@ -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() diff --git a/bchain/types.go b/bchain/types.go index 749adde7..59d05d39 100644 --- a/bchain/types.go +++ b/bchain/types.go @@ -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 diff --git a/db/bulkconnect.go b/db/bulkconnect.go index 60ca7a64..7221acad 100644 --- a/db/bulkconnect.go +++ b/db/bulkconnect.go @@ -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 diff --git a/db/rocksdb.go b/db/rocksdb.go index dcd8044c..822958e1 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -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++ { diff --git a/db/rocksdb_test.go b/db/rocksdb_test.go index 771bde20..4d89b6b9 100644 --- a/db/rocksdb_test.go +++ b/db/rocksdb_test.go @@ -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) { diff --git a/db/sync.go b/db/sync.go index 6bae828f..c408bb72 100644 --- a/db/sync.go +++ b/db/sync.go @@ -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 diff --git a/docs/config.md b/docs/config.md index 509edd8c..9c796b16 100644 --- a/docs/config.md +++ b/docs/config.md @@ -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. diff --git a/server/public_test.go b/server/public_test.go index f2f2a4ba..6b72853b 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -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 @@ -584,7 +584,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() @@ -594,5 +594,4 @@ func Test_PublicServer_UTXO(t *testing.T) { httpTests(t, ts) socketioTests(t, ts) - } diff --git a/tests/dbtestdata/dbtestdata.go b/tests/dbtestdata/dbtestdata.go index 1c4ad328..3f0a92d2 100644 --- a/tests/dbtestdata/dbtestdata.go +++ b/tests/dbtestdata/dbtestdata.go @@ -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, diff --git a/tests/dbtestdata/fakechain.go b/tests/dbtestdata/fakechain.go index d29740b9..b7ef7cba 100644 --- a/tests/dbtestdata/fakechain.go +++ b/tests/dbtestdata/fakechain.go @@ -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