Add unit test for pack/unpack txAddress
This commit is contained in:
parent
a2bbf3f9de
commit
fb93c9ff7a
@ -478,17 +478,7 @@ func (d *RocksDB) storeTxAddresses(wb *gorocksdb.WriteBatch, am map[string]*txAd
|
||||
varBuf := make([]byte, maxPackedBigintBytes)
|
||||
buf := make([]byte, 1024)
|
||||
for txID, ta := range am {
|
||||
buf = buf[:0]
|
||||
l := packVaruint(uint(len(ta.inputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range ta.inputs {
|
||||
buf = appendTxAddress(buf, varBuf, &ta.inputs[i])
|
||||
}
|
||||
l = packVaruint(uint(len(ta.outputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range ta.outputs {
|
||||
buf = appendTxAddress(buf, varBuf, &ta.outputs[i])
|
||||
}
|
||||
buf = packTxAddresses(ta, buf, varBuf)
|
||||
wb.PutCF(d.cfh[cfTxAddresses], []byte(txID), buf)
|
||||
}
|
||||
return nil
|
||||
@ -508,19 +498,6 @@ func (d *RocksDB) storeBalances(wb *gorocksdb.WriteBatch, abm map[string]*addrBa
|
||||
return nil
|
||||
}
|
||||
|
||||
func appendTxAddress(buf []byte, varBuf []byte, txa *txAddress) []byte {
|
||||
la := len(txa.addrID)
|
||||
if txa.spent {
|
||||
la = ^la
|
||||
}
|
||||
l := packVarint(la, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
buf = append(buf, txa.addrID...)
|
||||
l = packBigint(&txa.valueSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
return buf
|
||||
}
|
||||
|
||||
func (d *RocksDB) storeAndCleanupBlockTxids(wb *gorocksdb.WriteBatch, block *bchain.Block, txids [][]byte) error {
|
||||
pl := d.chainParser.PackedTxidLen()
|
||||
buf := make([]byte, pl*len(txids))
|
||||
@ -582,6 +559,38 @@ func (d *RocksDB) getTxAddresses(btxID []byte) (*txAddresses, error) {
|
||||
if len(buf) < 2 {
|
||||
return nil, nil
|
||||
}
|
||||
return unpackTxAddresses(buf)
|
||||
}
|
||||
|
||||
func packTxAddresses(ta *txAddresses, buf []byte, varBuf []byte) []byte {
|
||||
buf = buf[:0]
|
||||
l := packVaruint(uint(len(ta.inputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range ta.inputs {
|
||||
buf = appendTxAddress(&ta.inputs[i], buf, varBuf)
|
||||
}
|
||||
l = packVaruint(uint(len(ta.outputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range ta.outputs {
|
||||
buf = appendTxAddress(&ta.outputs[i], buf, varBuf)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
func appendTxAddress(txa *txAddress, buf []byte, varBuf []byte) []byte {
|
||||
la := len(txa.addrID)
|
||||
if txa.spent {
|
||||
la = ^la
|
||||
}
|
||||
l := packVarint(la, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
buf = append(buf, txa.addrID...)
|
||||
l = packBigint(&txa.valueSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
return buf
|
||||
}
|
||||
|
||||
func unpackTxAddresses(buf []byte) (*txAddresses, error) {
|
||||
ta := txAddresses{}
|
||||
inputs, l := unpackVaruint(buf)
|
||||
ta.inputs = make([]txAddress, inputs)
|
||||
@ -601,7 +610,7 @@ func unpackTxAddress(ta *txAddress, buf []byte) int {
|
||||
al, l := unpackVarint(buf)
|
||||
if al < 0 {
|
||||
ta.spent = true
|
||||
al ^= al
|
||||
al = ^al
|
||||
}
|
||||
ta.addrID = make([]byte, al)
|
||||
copy(ta.addrID, buf[l:l+al])
|
||||
|
||||
@ -23,6 +23,13 @@ import (
|
||||
// for number n, the packing is: 2*n if n>=0 else 2*(-n)-1
|
||||
// takes only 1 byte if abs(n)<127
|
||||
|
||||
func bitcoinTestnetParser() *btc.BitcoinParser {
|
||||
return &btc.BitcoinParser{
|
||||
BaseParser: &bchain.BaseParser{BlockAddressesToKeep: 1},
|
||||
Params: btc.GetChainParams("test"),
|
||||
}
|
||||
}
|
||||
|
||||
func setupRocksDB(t *testing.T, p bchain.BlockChainParser) *RocksDB {
|
||||
tmp, err := ioutil.TempDir("", "testdb")
|
||||
if err != nil {
|
||||
@ -546,10 +553,7 @@ func testTxCache(t *testing.T, d *RocksDB, b *bchain.Block, tx *bchain.Tx) {
|
||||
// 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) {
|
||||
d := setupRocksDB(t, &testBitcoinParser{
|
||||
BitcoinParser: &btc.BitcoinParser{
|
||||
BaseParser: &bchain.BaseParser{BlockAddressesToKeep: 1},
|
||||
Params: btc.GetChainParams("test"),
|
||||
},
|
||||
BitcoinParser: bitcoinTestnetParser(),
|
||||
})
|
||||
defer closeAndDestroyRocksDB(t, d)
|
||||
|
||||
@ -880,3 +884,139 @@ func Test_packBigint_unpackBigint(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func addressToOutput(addr string, parser *btc.BitcoinParser) []byte {
|
||||
b, err := parser.AddressToOutputScript(addr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
||||
parser := bitcoinTestnetParser()
|
||||
tests := []struct {
|
||||
name string
|
||||
hex string
|
||||
data *txAddresses
|
||||
}{
|
||||
{
|
||||
name: "1",
|
||||
hex: "022c001443aac20a116e09ea4f7914be1c55e4c17aa600b7002c001454633aa8bd2e552bd4e89c01e73c1b7905eb58460811207cb68a199872012d001443aac20a116e09ea4f7914be1c55e4c17aa600b70101",
|
||||
data: &txAddresses{
|
||||
inputs: []txAddress{
|
||||
{
|
||||
addrID: addressToOutput("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
||||
valueSat: *big.NewInt(0),
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("tb1q233n429a9e2jh48gnsq7w0qm0yz7kkzx0qczw8", parser),
|
||||
valueSat: *big.NewInt(1234123421342341234),
|
||||
},
|
||||
},
|
||||
outputs: []txAddress{
|
||||
{
|
||||
addrID: addressToOutput("tb1qgw4vyzs3dcy75nmezjlpc40yc9a2vq9hghdyt2", parser),
|
||||
valueSat: *big.NewInt(1),
|
||||
spent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "2",
|
||||
hex: "032ea9149eb21980dc9d413d8eac27314938b9da920ee53e8705021918f2c02ea91409f70b896169c37981d2b54b371df0d81a136a2c870501dd7e28c02ea914e371782582a4addb541362c55565d2cdf56f6498870501a1e35ec0052fa9141d9ca71efa36d814424ea6ca1437e67287aebe348705012aadcac02ea91424fbc77cdc62702ade74dcf989c15e5d3f9240bc870501664894c02fa914afbfb74ee994c7d45f6698738bc4226d065266f7870501a1e35ec03276a914d2a37ce20ac9ec4f15dd05a7c6e8e9fbdb99850e88ac043b9943603376a9146b2044146a4438e6e5bfbc65f147afeb64d14fbb88ac05012a05f200",
|
||||
data: &txAddresses{
|
||||
inputs: []txAddress{
|
||||
{
|
||||
addrID: addressToOutput("2N7iL7AvS4LViugwsdjTB13uN4T7XhV1bCP", parser),
|
||||
valueSat: *big.NewInt(9011000000),
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("2Mt9v216YiNBAzobeNEzd4FQweHrGyuRHze", parser),
|
||||
valueSat: *big.NewInt(8011000000),
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("2NDyqJpHvHnqNtL1F9xAeCWMAW8WLJmEMyD", parser),
|
||||
valueSat: *big.NewInt(7011000000),
|
||||
},
|
||||
},
|
||||
outputs: []txAddress{
|
||||
{
|
||||
addrID: addressToOutput("2MuwoFGwABMakU7DCpdGDAKzyj2nTyRagDP", parser),
|
||||
valueSat: *big.NewInt(5011000000),
|
||||
spent: true,
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("2Mvcmw7qkGXNWzkfH1EjvxDcNRGL1Kf2tEM", parser),
|
||||
valueSat: *big.NewInt(6011000000),
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("2N9GVuX3XJGHS5MCdgn97gVezc6EgvzikTB", parser),
|
||||
valueSat: *big.NewInt(7011000000),
|
||||
spent: true,
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("mzii3fuRSpExMLJEHdHveW8NmiX8MPgavk", parser),
|
||||
valueSat: *big.NewInt(999900000),
|
||||
},
|
||||
{
|
||||
addrID: addressToOutput("mqHPFTRk23JZm9W1ANuEFtwTYwxjESSgKs", parser),
|
||||
valueSat: *big.NewInt(5000000000),
|
||||
spent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty address",
|
||||
hex: "01000204d2020002162e010162",
|
||||
data: &txAddresses{
|
||||
inputs: []txAddress{
|
||||
{
|
||||
addrID: []byte{},
|
||||
valueSat: *big.NewInt(1234),
|
||||
},
|
||||
},
|
||||
outputs: []txAddress{
|
||||
{
|
||||
addrID: []byte{},
|
||||
valueSat: *big.NewInt(5678),
|
||||
},
|
||||
{
|
||||
addrID: []byte{},
|
||||
valueSat: *big.NewInt(98),
|
||||
spent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
hex: "0000",
|
||||
data: &txAddresses{
|
||||
inputs: []txAddress{},
|
||||
outputs: []txAddress{},
|
||||
},
|
||||
},
|
||||
}
|
||||
varBuf := make([]byte, maxPackedBigintBytes)
|
||||
buf := make([]byte, 1024)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
b := packTxAddresses(tt.data, buf, varBuf)
|
||||
hex := hex.EncodeToString(b)
|
||||
if !reflect.DeepEqual(hex, tt.hex) {
|
||||
t.Errorf("packTxAddresses() = %v, want %v", hex, tt.hex)
|
||||
}
|
||||
got1, err := unpackTxAddresses(b)
|
||||
if err != nil {
|
||||
t.Errorf("unpackTxAddresses() error = %v", err)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got1, tt.data) {
|
||||
t.Errorf("unpackTxAddresses() = %+v, want %+v", got1, tt.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user