|
|
@ -19,7 +19,16 @@ import ( |
|
|
|
"time" |
|
|
|
"time" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var utxoPoolMutex sync.Mutex |
|
|
|
type txGenSettings struct { |
|
|
|
|
|
|
|
numOfAddress int |
|
|
|
|
|
|
|
crossShard bool |
|
|
|
|
|
|
|
maxNumTxsPerBatch int |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
|
|
|
utxoPoolMutex sync.Mutex |
|
|
|
|
|
|
|
setting txGenSettings |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
@ -35,12 +44,10 @@ var utxoPoolMutex sync.Mutex |
|
|
|
// Params:
|
|
|
|
// Params:
|
|
|
|
// shardId - the shardId for current shard
|
|
|
|
// shardId - the shardId for current shard
|
|
|
|
// dataNodes - nodes containing utxopools of all shards
|
|
|
|
// dataNodes - nodes containing utxopools of all shards
|
|
|
|
// maxNumTxs - the max number of txs to generate
|
|
|
|
|
|
|
|
// crossShard - whether to generate cross shard txs
|
|
|
|
|
|
|
|
// Returns:
|
|
|
|
// Returns:
|
|
|
|
// all single-shard txs
|
|
|
|
// all single-shard txs
|
|
|
|
// all cross-shard txs
|
|
|
|
// all cross-shard txs
|
|
|
|
func generateSimulatedTransactions(shardId int, dataNodes []*node.Node, maxNumTxs int, crossShard bool) ([]*blockchain.Transaction, []*blockchain.Transaction) { |
|
|
|
func generateSimulatedTransactions(shardId int, dataNodes []*node.Node) ([]*blockchain.Transaction, []*blockchain.Transaction) { |
|
|
|
/* |
|
|
|
/* |
|
|
|
UTXO map structure: |
|
|
|
UTXO map structure: |
|
|
|
address - [ |
|
|
|
address - [ |
|
|
@ -75,14 +82,16 @@ UTXOLOOP: |
|
|
|
|
|
|
|
|
|
|
|
// Loop over all utxos for the txId
|
|
|
|
// Loop over all utxos for the txId
|
|
|
|
for index, value := range utxoMap { |
|
|
|
for index, value := range utxoMap { |
|
|
|
if txsCount >= maxNumTxs { |
|
|
|
if txsCount >= setting.maxNumTxsPerBatch { |
|
|
|
break UTXOLOOP |
|
|
|
break UTXOLOOP |
|
|
|
} |
|
|
|
} |
|
|
|
randNum := rand.Intn(100) |
|
|
|
randNum := rand.Intn(100) |
|
|
|
|
|
|
|
|
|
|
|
// 30% sample rate to select UTXO to use for new transactions
|
|
|
|
// 30% sample rate to select UTXO to use for new transactions
|
|
|
|
if randNum < 30 { |
|
|
|
if randNum >= 30 { |
|
|
|
if crossShard && randNum < 10 { // 30% cross shard transactions: add another txinput from another shard
|
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if setting.crossShard && randNum < 10 { // 1/3 cross shard transactions: add another txinput from another shard
|
|
|
|
// shard with neighboring Id
|
|
|
|
// shard with neighboring Id
|
|
|
|
crossShardId := (int(dataNodes[shardId].Consensus.ShardID) + 1) % len(dataNodes) |
|
|
|
crossShardId := (int(dataNodes[shardId].Consensus.ShardID) + 1) % len(dataNodes) |
|
|
|
|
|
|
|
|
|
|
@ -122,12 +131,12 @@ UTXOLOOP: |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Spend the utxo from the current shard to a random address in [0 - N)
|
|
|
|
// Spend the utxo from the current shard to a random address in [0 - N)
|
|
|
|
txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(10000)), dataNodes[shardId].Consensus.ShardID} |
|
|
|
txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(setting.numOfAddress)), dataNodes[shardId].Consensus.ShardID} |
|
|
|
txOutputs := []blockchain.TXOutput{txout} |
|
|
|
txOutputs := []blockchain.TXOutput{txout} |
|
|
|
|
|
|
|
|
|
|
|
// Spend the utxo from the other shard, if any, to a random address in [0 - N)
|
|
|
|
// Spend the utxo from the other shard, if any, to a random address in [0 - N)
|
|
|
|
if crossTxin != nil { |
|
|
|
if crossTxin != nil { |
|
|
|
crossTxout := blockchain.TXOutput{crossUtxoValue, strconv.Itoa(rand.Intn(10000)), uint32(crossShardId)} |
|
|
|
crossTxout := blockchain.TXOutput{crossUtxoValue, strconv.Itoa(rand.Intn(setting.numOfAddress)), uint32(crossShardId)} |
|
|
|
txOutputs = append(txOutputs, crossTxout) |
|
|
|
txOutputs = append(txOutputs, crossTxout) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -142,7 +151,7 @@ UTXOLOOP: |
|
|
|
txin := blockchain.TXInput{txId, index, address, dataNodes[shardId].Consensus.ShardID} |
|
|
|
txin := blockchain.TXInput{txId, index, address, dataNodes[shardId].Consensus.ShardID} |
|
|
|
|
|
|
|
|
|
|
|
// Spend the utxo to a random address in [0 - N)
|
|
|
|
// Spend the utxo to a random address in [0 - N)
|
|
|
|
txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(10000)), dataNodes[shardId].Consensus.ShardID} |
|
|
|
txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(setting.numOfAddress)), dataNodes[shardId].Consensus.ShardID} |
|
|
|
tx := blockchain.Transaction{[32]byte{}, []blockchain.TXInput{txin}, []blockchain.TXOutput{txout}, nil} |
|
|
|
tx := blockchain.Transaction{[32]byte{}, []blockchain.TXInput{txin}, []blockchain.TXOutput{txout}, nil} |
|
|
|
tx.SetID() |
|
|
|
tx.SetID() |
|
|
|
|
|
|
|
|
|
|
@ -152,7 +161,6 @@ UTXOLOOP: |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
utxoPoolMutex.Unlock() |
|
|
|
utxoPoolMutex.Unlock() |
|
|
|
|
|
|
|
|
|
|
|
return txs, crossTxs |
|
|
|
return txs, crossTxs |
|
|
@ -250,8 +258,10 @@ func main() { |
|
|
|
config := readConfigFile(*configFile) |
|
|
|
config := readConfigFile(*configFile) |
|
|
|
leaders, shardIds := getLeadersAndShardIds(&config) |
|
|
|
leaders, shardIds := 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
|
|
|
|
crossShard := len(shardIds) > 1 |
|
|
|
setting.crossShard = len(shardIds) > 1 |
|
|
|
|
|
|
|
setting.maxNumTxsPerBatch = *maxNumTxsPerBatch |
|
|
|
|
|
|
|
|
|
|
|
// TODO(Richard): refactor this chuck to a single method
|
|
|
|
// TODO(Richard): refactor this chuck to a single method
|
|
|
|
// Setup a logger to stdout and log file.
|
|
|
|
// Setup a logger to stdout and log file.
|
|
|
@ -267,8 +277,8 @@ func main() { |
|
|
|
nodes := []*node.Node{} |
|
|
|
nodes := []*node.Node{} |
|
|
|
for _, shardId := range shardIds { |
|
|
|
for _, shardId := range shardIds { |
|
|
|
node := node.New(&consensus.Consensus{ShardID: shardId}) |
|
|
|
node := node.New(&consensus.Consensus{ShardID: shardId}) |
|
|
|
// Assign many fake addresses so we have enough address to place with at first
|
|
|
|
// Assign many fake addresses so we have enough address to play with at first
|
|
|
|
node.AddTestingAddresses(10000) |
|
|
|
node.AddTestingAddresses(setting.numOfAddress) |
|
|
|
nodes = append(nodes, node) |
|
|
|
nodes = append(nodes, node) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -321,7 +331,7 @@ func main() { |
|
|
|
allCrossTxs := []*blockchain.Transaction{} |
|
|
|
allCrossTxs := []*blockchain.Transaction{} |
|
|
|
// Generate simulated transactions
|
|
|
|
// Generate simulated transactions
|
|
|
|
for i, leader := range leaders { |
|
|
|
for i, leader := range leaders { |
|
|
|
txs, crossTxs := generateSimulatedTransactions(i, nodes, *maxNumTxsPerBatch, crossShard) |
|
|
|
txs, crossTxs := generateSimulatedTransactions(i, nodes) |
|
|
|
allCrossTxs = append(allCrossTxs, crossTxs...) |
|
|
|
allCrossTxs = append(allCrossTxs, crossTxs...) |
|
|
|
|
|
|
|
|
|
|
|
log.Debug("[Generator] Sending single-shard txs ...", "leader", leader, "numTxs", len(txs), "numCrossTxs", len(crossTxs)) |
|
|
|
log.Debug("[Generator] Sending single-shard txs ...", "leader", leader, "numTxs", len(txs), "numCrossTxs", len(crossTxs)) |
|
|
|