update btctxgen

pull/53/head
Richard Liu 6 years ago
parent 90fac0f1ab
commit ca3ed368b1
  1. 132
      client/btctxgen/main.go
  2. 4
      client/btctxiter/btctxiter.go
  3. 29
      deploy_btctx.sh

@ -12,13 +12,13 @@ import (
"harmony-benchmark/log" "harmony-benchmark/log"
"harmony-benchmark/node" "harmony-benchmark/node"
"harmony-benchmark/p2p" "harmony-benchmark/p2p"
"math/rand"
"sync" "sync"
"time" "time"
"github.com/piotrnar/gocoin/lib/btc"
) )
type txGenSettings struct { type txGenSettings struct {
numOfAddress int
crossShard bool crossShard bool
maxNumTxsPerBatch int maxNumTxsPerBatch int
} }
@ -29,21 +29,6 @@ var (
btcTXIter btctxiter.BTCTXIterator btcTXIter btctxiter.BTCTXIterator
) )
type TxInfo struct {
// Global Input
shardID int
dataNodes []*node.Node
// Temp Input
id [32]byte
index int
value int
address string
// Output
txs []*blockchain.Transaction
crossTxs []*blockchain.Transaction
txCount int
}
// Generates at most "maxNumTxs" number of simulated transactions based on the current UtxoPools of all shards. // Generates at most "maxNumTxs" number of simulated transactions based on the current UtxoPools of all shards.
// The transactions are generated by going through the existing utxos and // The transactions are generated by going through the existing utxos and
// randomly select a subset of them as the input for each new transaction. The output // randomly select a subset of them as the input for each new transaction. The output
@ -63,90 +48,78 @@ type TxInfo struct {
// all cross-shard txs // all cross-shard txs
func generateSimulatedTransactions(shardID int, dataNodes []*node.Node) ([]*blockchain.Transaction, []*blockchain.Transaction) { func generateSimulatedTransactions(shardID int, dataNodes []*node.Node) ([]*blockchain.Transaction, []*blockchain.Transaction) {
/* /*
UTXO map structure: UTXO map structure:
address - [ {
txId1 - [ address: {
outputIndex1 - value1 txID: {
outputIndex2 - value2 outputIndex: value
] }
txId2 - [ }
outputIndex1 - value1 }
outputIndex2 - value2
]
]
*/ */
utxoPoolMutex.Lock() utxoPoolMutex.Lock()
txInfo := TxInfo{} txs := []*blockchain.Transaction{}
txInfo.shardID = shardID crossTxs := []*blockchain.Transaction{}
txInfo.dataNodes = dataNodes
txInfo.txCount = 0
UTXOLOOP:
// Loop over all addresses
for address, txMap := range dataNodes[shardID].UtxoPool.UtxoMap {
txInfo.address = address
// Loop over all txIds for the address
for txIdStr, utxoMap := range txMap {
// Parse TxId
id, err := hex.DecodeString(txIdStr)
if err != nil {
continue
}
copy(txInfo.id[:], id[:])
// Loop over all utxos for the txId nodeShardID := dataNodes[shardID].Consensus.ShardID
for index, value := range utxoMap { cnt := 0
txInfo.index = index
txInfo.value = value
randNum := rand.Intn(100) LOOP:
// 30% sample rate to select UTXO to use for new transactions for true {
if randNum >= 30 { blk := btcTXIter.IterateBTCTX()
continue blk.BuildTxList()
for _, btcTx := range blk.Txs {
tx := blockchain.Transaction{}
// tx.ID = tx.Hash.String()
if btcTx.IsCoinBase() {
// TxIn coinbase, newly generated coins
prevTxID := [32]byte{}
// TODO: merge txID with txIndex
tx.TxInput = []blockchain.TXInput{blockchain.TXInput{prevTxID, -1, "", nodeShardID}}
} else {
for _, txi := range btcTx.TxIn {
tx.TxInput = append(tx.TxInput, blockchain.TXInput{txi.Input.Hash, int(txi.Input.Vout), "", nodeShardID})
} }
generateSingleShardTx(&txInfo) }
if txInfo.txCount >= setting.maxNumTxsPerBatch {
break UTXOLOOP for _, txo := range btcTx.TxOut {
txoAddr := btc.NewAddrFromPkScript(txo.Pk_script, false)
if txoAddr == nil {
log.Warn("TxOut: can't decode address")
} }
txout := blockchain.TXOutput{int(txo.Value), txoAddr.String(), nodeShardID}
tx.TxOutput = append(tx.TxOutput, txout)
}
tx.SetID()
txs = append(txs, &tx)
log.Debug("[Generator] transformed btc tx", "block height", btcTXIter.GetIndex(), "txi", len(tx.TxInput), "txo", len(tx.TxOutput), "txCount", cnt)
cnt++
if cnt >= setting.maxNumTxsPerBatch {
break LOOP
} }
} }
} }
utxoPoolMutex.Unlock()
log.Debug("[Generator] generated transations", "single-shard", len(txInfo.txs), "cross-shard", len(txInfo.crossTxs))
return txInfo.txs, txInfo.crossTxs
}
func generateSingleShardTx(txInfo *TxInfo) {
// nodeShardID := txInfo.dataNodes[txInfo.shardID].Consensus.ShardID
// blk := btcTXIter.IterateBTCTX()
// Add the utxo as new tx input utxoPoolMutex.Unlock()
// txin := blockchain.TXInput{txInfo.id, txInfo.index, txInfo.address, nodeShardID}
// // Spend the utxo to a random address in [0 - N)
// txout := blockchain.TXOutput{txInfo.value, strconv.Itoa(rand.Intn(setting.numOfAddress)), nodeShardID}
// tx := blockchain.Transaction{[32]byte{}, []blockchain.TXInput{txin}, []blockchain.TXOutput{txout}, nil}
// tx.SetID()
// txInfo.txs = append(txInfo.txs, &tx) log.Debug("[Generator] generated transations", "single-shard", len(txs), "cross-shard", len(crossTxs))
txInfo.txCount++ return txs, crossTxs
} }
// A utility func that counts the total number of utxos in a pool. // A utility func that counts the total number of utxos in a pool.
func countNumOfUtxos(utxoPool *blockchain.UTXOPool) int { func countNumOfUtxos(utxoPool *blockchain.UTXOPool) int {
countAll := 0 countAll := 0
for _, utxoMap := range utxoPool.UtxoMap { for _, utxoMap := range utxoPool.UtxoMap {
for txIdStr, val := range utxoMap { for txIDStr, val := range utxoMap {
_ = val _ = val
id, err := hex.DecodeString(txIdStr) id, err := hex.DecodeString(txIDStr)
if err != nil { if err != nil {
continue continue
} }
txId := [32]byte{} txID := [32]byte{}
copy(txId[:], id[:]) copy(txID[:], id[:])
for _, utxo := range val { for _, utxo := range val {
_ = utxo _ = utxo
countAll++ countAll++
@ -190,7 +163,7 @@ func initClient(clientNode *node.Node, clientPort string, leaders *[]p2p.Peer, n
func main() { func main() {
configFile := flag.String("config_file", "local_config.txt", "file containing all ip addresses and config") configFile := flag.String("config_file", "local_config.txt", "file containing all ip addresses and config")
maxNumTxsPerBatch := flag.Int("max_num_txs_per_batch", 100000, "number of transactions to send per message") maxNumTxsPerBatch := flag.Int("max_num_txs_per_batch", 100, "number of transactions to send per message")
logFolder := flag.String("log_folder", "latest", "the folder collecting the logs of this execution") logFolder := flag.String("log_folder", "latest", "the folder collecting the logs of this execution")
flag.Parse() flag.Parse()
@ -198,7 +171,6 @@ func main() {
config, _ := configr.ReadConfigFile(*configFile) config, _ := configr.ReadConfigFile(*configFile)
leaders, shardIDs := configr.GetLeadersAndShardIds(&config) leaders, shardIDs := configr.GetLeadersAndShardIds(&config)
setting.numOfAddress = 10000
// Do cross shard tx if there are more than one shard // Do cross shard tx if there are more than one shard
setting.crossShard = len(shardIDs) > 1 setting.crossShard = len(shardIDs) > 1
setting.maxNumTxsPerBatch = *maxNumTxsPerBatch setting.maxNumTxsPerBatch = *maxNumTxsPerBatch

@ -36,3 +36,7 @@ func (iter *BTCTXIterator) IterateBTCTX() *btc.Block {
blk.BuildTxList() blk.BuildTxList()
return blk return blk
} }
func (iter *BTCTXIterator) GetIndex() int {
return iter.index
}

@ -0,0 +1,29 @@
# Kill nodes if any
./kill_node.sh
# Since `go run` will generate a temporary exe every time,
# On windows, your system will pop up a network security dialog for each instance
# and you won't be able to turn it off. With `go build` generating one
# exe, the dialog will only pop up once at the very first time.
# Also it's recommended to use `go build` for testing the whole exe.
go build -o bin/benchmark
go build -o bin/btctxgen client/btctxgen/main.go
# Create a tmp folder for logs
t=`date +"%Y%m%d-%H%M%S"`
log_folder="tmp_log/log-$t"
mkdir -p $log_folder
# Start nodes
config=$1
while IFS='' read -r line || [[ -n "$line" ]]; do
IFS=' ' read ip port mode shardId <<< $line
#echo $ip $port $mode
if [ "$mode" != "client" ]; then
./bin/benchmark -ip $ip -port $port -config_file $config -log_folder $log_folder&
fi
done < $config
# Generate transactions
./bin/btctxgen -config_file $config -log_folder $log_folder
Loading…
Cancel
Save