update btctxgen

pull/75/head
Richard Liu 6 years ago
parent 6b3083a6d2
commit 736f47102b
  1. 35
      client/btctxgen/main.go
  2. 77
      client/btctxiter/btctxiter.go

@ -25,6 +25,9 @@ import (
"sync" "sync"
"time" "time"
btcblockchain "github.com/btcsuite/btcd/blockchain"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/simple-rules/harmony-benchmark/blockchain" "github.com/simple-rules/harmony-benchmark/blockchain"
"github.com/simple-rules/harmony-benchmark/client" "github.com/simple-rules/harmony-benchmark/client"
"github.com/simple-rules/harmony-benchmark/client/btctxiter" "github.com/simple-rules/harmony-benchmark/client/btctxiter"
@ -34,8 +37,6 @@ import (
"github.com/simple-rules/harmony-benchmark/node" "github.com/simple-rules/harmony-benchmark/node"
"github.com/simple-rules/harmony-benchmark/p2p" "github.com/simple-rules/harmony-benchmark/p2p"
proto_node "github.com/simple-rules/harmony-benchmark/proto/node" proto_node "github.com/simple-rules/harmony-benchmark/proto/node"
"github.com/piotrnar/gocoin/lib/btc"
) )
type txGenSettings struct { type txGenSettings struct {
@ -94,31 +95,39 @@ func generateSimulatedTransactions(shardID int, dataNodes []*node.Node) ([]*bloc
LOOP: LOOP:
for true { for true {
btcTx := btcTXIter.NextTx() btcTx := btcTXIter.NextTx()
fmt.Println(btcTXIter.GetBlockIndex(), btcTXIter.GetTxIndex(), btcTx)
tx := blockchain.Transaction{} tx := blockchain.Transaction{}
isCrossShardTx := false isCrossShardTx := false
if btcTx.IsCoinBase() { if btcblockchain.IsCoinBaseTx(btcTx.MsgTx()) {
tx.TxInput = []blockchain.TXInput{*blockchain.NewTXInput(blockchain.NewOutPoint(&blockchain.TxID{}, math.MaxUint32), [20]byte{}, nodeShardID)} tx.TxInput = []blockchain.TXInput{*blockchain.NewTXInput(blockchain.NewOutPoint(&blockchain.TxID{}, math.MaxUint32), [20]byte{}, nodeShardID)}
} else { } else {
for _, btcTXI := range btcTx.TxIn { for _, btcTXI := range btcTx.MsgTx().TxIn {
btcTXIDStr := btc.NewUint256(btcTXI.Input.Hash[:]).String() btcTXIDStr := btcTXI.PreviousOutPoint.Hash.String()
txRef := utxoMapping[btcTXIDStr] txRef := utxoMapping[btcTXIDStr]
if txRef.shardID != nodeShardID { if txRef.shardID != nodeShardID {
isCrossShardTx = true isCrossShardTx = true
} }
tx.TxInput = append(tx.TxInput, *blockchain.NewTXInput(blockchain.NewOutPoint(&txRef.txID, btcTXI.Input.Vout), [20]byte{}, txRef.shardID)) tx.TxInput = append(tx.TxInput, *blockchain.NewTXInput(blockchain.NewOutPoint(&txRef.txID, btcTXI.PreviousOutPoint.Index), [20]byte{}, txRef.shardID))
} }
} }
for _, btcTXO := range btcTx.TxOut { for _, btcTXO := range btcTx.MsgTx().TxOut {
btcTXOAddr := btc.NewAddrFromPkScript(btcTXO.Pk_script, false) scriptClass, addresses, _, _ := txscript.ExtractPkScriptAddrs(
if btcTXOAddr == nil { btcTXO.PkScript, &chaincfg.MainNetParams)
log.Warn("TxOut: can't decode address") if scriptClass.String() == "pubkey" || scriptClass.String() == "pubkeyhash" {
btcTXOAddr := addresses[0]
if btcTXOAddr == nil {
log.Warn("TxOut: can't decode address")
}
var addr [20]byte
copy(addr[:], btcTXOAddr.ScriptAddress())
txo := blockchain.TXOutput{Amount: int(btcTXO.Value), Address: addr, ShardID: nodeShardID}
tx.TxOutput = append(tx.TxOutput, txo)
} }
txo := blockchain.TXOutput{Amount: int(btcTXO.Value), Address: btcTXOAddr.Hash160, ShardID: nodeShardID}
tx.TxOutput = append(tx.TxOutput, txo)
} }
tx.SetID() tx.SetID()
utxoMapping[btcTx.Hash.String()] = TXRef{tx.ID, nodeShardID} utxoMapping[btcTx.Hash().String()] = TXRef{tx.ID, nodeShardID}
if isCrossShardTx { if isCrossShardTx {
crossTxs = append(crossTxs, &tx) crossTxs = append(crossTxs, &tx)
} else { } else {

@ -3,47 +3,70 @@ package btctxiter
import ( import (
"log" "log"
"github.com/piotrnar/gocoin/lib/btc" "github.com/btcsuite/btcutil"
"github.com/piotrnar/gocoin/lib/others/blockdb"
"github.com/btcsuite/btcd/rpcclient"
"github.com/btcsuite/btcd/wire"
) )
type BTCTXIterator struct { type BTCTXIterator struct {
blockIndex int blockIndex int64
block *btc.Block block *wire.MsgBlock
txIndex int txIndex int
tx *btc.Tx tx *btcutil.Tx
blockDatabase *blockdb.BlockDB client *rpcclient.Client
} }
func (iter *BTCTXIterator) Init() { func (iter *BTCTXIterator) Init() {
// Set real Bitcoin network // Connect to local bitcoin core RPC server using HTTP POST mode.
Magic := [4]byte{0xF9, 0xBE, 0xB4, 0xD9} connCfg := &rpcclient.ConnConfig{
Host: "localhost:8332",
// Specify blocks directory User: "ricl",
iter.blockDatabase = blockdb.NewBlockDB("/Users/ricl/Library/Application Support/Bitcoin/blocks", Magic) Pass: "123",
iter.blockIndex = -1 HTTPPostMode: true, // Bitcoin core only supports HTTP POST mode
DisableTLS: true, // Bitcoin core does not provide TLS by default
}
// Notice the notification parameter is nil since notifications are
// not supported in HTTP POST mode.
var err error
iter.client, err = rpcclient.New(connCfg, nil)
if err != nil {
log.Fatal(err)
}
iter.blockIndex = 0 // the genesis block cannot retrieved. Skip it intentionally.
iter.block = nil iter.block = nil
iter.nextBlock() iter.nextBlock()
// defer iter.client.Shutdown()
} }
// Move to the next transaction // Move to the next transaction
func (iter *BTCTXIterator) NextTx() *btc.Tx { func (iter *BTCTXIterator) NextTx() *btcutil.Tx {
iter.txIndex++ iter.txIndex++
if iter.txIndex >= iter.block.TxCount { hashes, err := iter.block.TxHashes()
if err != nil {
log.Println("Failed to get tx hashes", iter.blockIndex, iter.txIndex, err)
return nil
}
if iter.txIndex >= len(hashes) {
iter.nextBlock() iter.nextBlock()
iter.txIndex++ iter.txIndex++
} }
iter.tx = iter.block.Txs[iter.txIndex] iter.tx, err = iter.client.GetRawTransaction(&hashes[iter.txIndex])
if err != nil {
log.Println("Failed to get raw tx", iter.blockIndex, iter.txIndex, hashes[iter.txIndex], err)
return nil
}
log.Println("get raw tx", iter.blockIndex, iter.txIndex, hashes[iter.txIndex], iter.tx)
return iter.tx return iter.tx
} }
// Gets the index/height of the current block // Gets the index/height of the current block
func (iter *BTCTXIterator) GetBlockIndex() int { func (iter *BTCTXIterator) GetBlockIndex() int64 {
return iter.blockIndex return iter.blockIndex
} }
// Gets the current block // Gets the current block
func (iter *BTCTXIterator) GetBlock() *btc.Block { func (iter *BTCTXIterator) GetBlock() *wire.MsgBlock {
return iter.block return iter.block
} }
@ -53,7 +76,7 @@ func (iter *BTCTXIterator) GetTxIndex() int {
} }
// Gets the current transaction // Gets the current transaction
func (iter *BTCTXIterator) GetTx() *btc.Tx { func (iter *BTCTXIterator) GetTx() *btcutil.Tx {
return iter.tx return iter.tx
} }
@ -63,20 +86,16 @@ func (iter *BTCTXIterator) resetTx() {
} }
// Move to the next block // Move to the next block
func (iter *BTCTXIterator) nextBlock() *btc.Block { func (iter *BTCTXIterator) nextBlock() *wire.MsgBlock {
iter.blockIndex++ iter.blockIndex++
dat, err := iter.blockDatabase.FetchNextBlock() hash, err := iter.client.GetBlockHash(iter.blockIndex)
if dat == nil || err != nil { if err != nil {
log.Println("END of DB file") log.Println("Failed to get block hash at", iter.blockIndex)
} }
iter.block, err = btc.NewBlock(dat[:]) iter.block, err = iter.client.GetBlock(hash)
if err != nil { if err != nil {
println("Block inconsistent:", err.Error()) log.Println("Failed to get block", iter.blockIndex, iter.block)
} }
iter.block.BuildTxList()
iter.resetTx() iter.resetTx()
return iter.block return iter.block

Loading…
Cancel
Save