-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
datagen: add datagen functions for testing reporter #190
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,97 @@ | ||||||
package datagen | ||||||
|
||||||
import ( | ||||||
"math/big" | ||||||
"math/rand" | ||||||
|
||||||
"github.com/babylonchain/babylon/btctxformatter" | ||||||
"github.com/btcsuite/btcd/blockchain" | ||||||
"github.com/btcsuite/btcd/chaincfg" | ||||||
"github.com/btcsuite/btcd/chaincfg/chainhash" | ||||||
"github.com/btcsuite/btcd/wire" | ||||||
) | ||||||
|
||||||
func GenRandomBlock(numBabylonTxs int, prevHash *chainhash.Hash) (*wire.MsgBlock, *btctxformatter.RawBtcCheckpoint) { | ||||||
var ( | ||||||
randomTxs []*wire.MsgTx | ||||||
rawCkpt *btctxformatter.RawBtcCheckpoint | ||||||
) | ||||||
|
||||||
if numBabylonTxs == 2 { | ||||||
randomTxs, rawCkpt = GenRandomBabylonTxPair() | ||||||
} else if numBabylonTxs == 1 { | ||||||
randomTxs, _ = GenRandomBabylonTxPair() | ||||||
randomTxs[1] = GenRandomTx() | ||||||
rawCkpt = nil | ||||||
} else { | ||||||
randomTxs = []*wire.MsgTx{GenRandomTx(), GenRandomTx()} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about start with
And update both in the first |
||||||
rawCkpt = nil | ||||||
} | ||||||
coinbaseTx := createCoinbaseTx(rand.Int31(), &chaincfg.SimNetParams) | ||||||
msgTxs := []*wire.MsgTx{coinbaseTx} | ||||||
msgTxs = append(msgTxs, randomTxs...) | ||||||
|
||||||
// calculate correct Merkle root | ||||||
merkleRoot := calcMerkleRoot(msgTxs) | ||||||
// don't apply any difficulty | ||||||
difficulty, _ := new(big.Int).SetString("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16) | ||||||
workBits := blockchain.BigToCompact(difficulty) | ||||||
|
||||||
header := GenRandomBtcdHeader() | ||||||
header.MerkleRoot = merkleRoot | ||||||
header.Bits = workBits | ||||||
if prevHash == nil { | ||||||
header.PrevBlock = chainhash.DoubleHashH(GenRandomByteArray(10)) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||||||
} else { | ||||||
header.PrevBlock = *prevHash | ||||||
} | ||||||
// find a nonce that satisfies difficulty | ||||||
SolveBlock(header) | ||||||
|
||||||
block := &wire.MsgBlock{ | ||||||
Header: *header, | ||||||
Transactions: msgTxs, | ||||||
} | ||||||
return block, rawCkpt | ||||||
} | ||||||
|
||||||
func GenRandomBlockchainWithBabylonTx(n uint64, partialPercentage float32, fullPercentage float32) ([]*wire.MsgBlock, int, []*btctxformatter.RawBtcCheckpoint) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, comments would be appreciated. |
||||||
blocks := []*wire.MsgBlock{} | ||||||
numCkptSegs := 0 | ||||||
rawCkpts := []*btctxformatter.RawBtcCheckpoint{} | ||||||
// percentage should be [0, 1] | ||||||
if partialPercentage < 0 || partialPercentage > 1 { | ||||||
return blocks, 0, rawCkpts | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since this might silently make some tests pass, maybe we should panic here? It demonstrates wrong usage by a developer. |
||||||
} | ||||||
if fullPercentage < 0 || fullPercentage > 1 { | ||||||
return blocks, 0, rawCkpts | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same |
||||||
} | ||||||
// n should be > 0 | ||||||
if n == 0 { | ||||||
return blocks, 0, rawCkpts | ||||||
} | ||||||
|
||||||
// genesis block | ||||||
genesisBlock, rawCkpt := GenRandomBlock(0, nil) | ||||||
blocks = append(blocks, genesisBlock) | ||||||
rawCkpts = append(rawCkpts, rawCkpt) | ||||||
|
||||||
// blocks after genesis | ||||||
for i := uint64(1); i < n; i++ { | ||||||
var msgBlock *wire.MsgBlock | ||||||
prevHash := blocks[len(blocks)-1].BlockHash() | ||||||
if rand.Float32() < partialPercentage { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the |
||||||
msgBlock, rawCkpt = GenRandomBlock(1, &prevHash) | ||||||
numCkptSegs += 1 | ||||||
} else if rand.Float32() < partialPercentage+fullPercentage { | ||||||
msgBlock, rawCkpt = GenRandomBlock(2, &prevHash) | ||||||
numCkptSegs += 2 | ||||||
} else { | ||||||
msgBlock, rawCkpt = GenRandomBlock(0, &prevHash) | ||||||
} | ||||||
|
||||||
blocks = append(blocks, msgBlock) | ||||||
rawCkpts = append(rawCkpts, rawCkpt) | ||||||
} | ||||||
return blocks, numCkptSegs, rawCkpts | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ import ( | |
"runtime" | ||
"time" | ||
|
||
"github.com/babylonchain/babylon/btctxformatter" | ||
bbn "github.com/babylonchain/babylon/types" | ||
btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types" | ||
"github.com/btcsuite/btcd/blockchain" | ||
|
@@ -315,11 +316,104 @@ func CreateBlockWithTransaction( | |
proof, err := btcctypes.SpvProofFromHeaderAndTransactions(headerBytes.MustMarshal(), txBytes, 1) | ||
|
||
if err != nil { | ||
panic("couldnt calculate prroof") | ||
panic("could not calculate proof") | ||
} | ||
|
||
return &BtcHeaderWithProof{ | ||
HeaderBytes: headerBytes, | ||
SpvProof: proof, | ||
} | ||
} | ||
|
||
func GenRandomTx() *wire.MsgTx { | ||
// structure of the below tx is from https://github.com/btcsuite/btcd/blob/master/wire/msgtx_test.go | ||
tx := &wire.MsgTx{ | ||
Version: 1, | ||
TxIn: []*wire.TxIn{ | ||
{ | ||
PreviousOutPoint: wire.OutPoint{ | ||
Hash: chainhash.HashH(GenRandomByteArray(10)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can also use: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
Index: rand.Uint32(), | ||
}, | ||
SignatureScript: GenRandomByteArray(10), | ||
Sequence: rand.Uint32(), | ||
}, | ||
}, | ||
TxOut: []*wire.TxOut{ | ||
{ | ||
Value: rand.Int63(), | ||
PkScript: GenRandomByteArray(80), | ||
}, | ||
}, | ||
LockTime: 0, | ||
} | ||
|
||
return tx | ||
} | ||
|
||
func GenRandomBabylonTxPair() ([]*wire.MsgTx, *btctxformatter.RawBtcCheckpoint) { | ||
txs := []*wire.MsgTx{GenRandomTx(), GenRandomTx()} | ||
builder := txscript.NewScriptBuilder() | ||
|
||
// fake a raw checkpoint | ||
rawBTCCkpt := GetRandomRawBtcCheckpoint() | ||
// encode raw checkpoint to two halves | ||
firstHalf, secondHalf, err := btctxformatter.EncodeCheckpointData( | ||
btctxformatter.TestTag(48), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use a random value instead of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not straightforward to do. Vigilante and Babylon need to use a consistent tag. So if we want to use a random tag, then we need to feed vigilante and this function with the same tag when testing vigilante. Left a TODO on this. |
||
btctxformatter.CurrentVersion, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a historical record of older versions? Might be useful to test with other ones as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep it would be good to have. At least we need to remember the last version we are using, so that we don't repeat ourselves with inconsistent tag format. |
||
rawBTCCkpt, | ||
) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
dataScript1, err := builder.AddOp(txscript.OP_RETURN).AddData(firstHalf).Script() | ||
if err != nil { | ||
panic(err) | ||
} | ||
txs[0].TxOut[0] = wire.NewTxOut(0, dataScript1) | ||
|
||
// reset builder | ||
builder = txscript.NewScriptBuilder() | ||
|
||
dataScript2, err := builder.AddOp(txscript.OP_RETURN).AddData(secondHalf).Script() | ||
if err != nil { | ||
panic(err) | ||
} | ||
txs[1].TxOut[0] = wire.NewTxOut(0, dataScript2) | ||
|
||
return txs, rawBTCCkpt | ||
} | ||
|
||
func GenRandomBabylonTx() *wire.MsgTx { | ||
tx := GenRandomTx() | ||
builder := txscript.NewScriptBuilder() | ||
|
||
// fake a raw checkpoint | ||
rawBTCCkpt := GetRandomRawBtcCheckpoint() | ||
// encode raw checkpoint to two halves | ||
firstHalf, secondHalf, err := btctxformatter.EncodeCheckpointData( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use |
||
btctxformatter.TestTag(48), | ||
btctxformatter.CurrentVersion, | ||
rawBTCCkpt, | ||
) | ||
if err != nil { | ||
panic(err) | ||
} | ||
idx := rand.Intn(2) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or even better, if we use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea 👍 |
||
if idx == 0 { | ||
dataScript, err := builder.AddOp(txscript.OP_RETURN).AddData(firstHalf).Script() | ||
if err != nil { | ||
panic(err) | ||
} | ||
tx.TxOut[0] = wire.NewTxOut(0, dataScript) | ||
} else { | ||
dataScript, err := builder.AddOp(txscript.OP_RETURN).AddData(secondHalf).Script() | ||
if err != nil { | ||
panic(err) | ||
} | ||
tx.TxOut[0] = wire.NewTxOut(0, dataScript) | ||
} | ||
|
||
return tx | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments would be appreciated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I suggest that this function is called
GenRandomBtcdBlock
to comply with theGenRandomBtcdHeader
function.