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)
|
varBuf := make([]byte, maxPackedBigintBytes)
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
for txID, ta := range am {
|
for txID, ta := range am {
|
||||||
buf = buf[:0]
|
buf = packTxAddresses(ta, buf, varBuf)
|
||||||
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])
|
|
||||||
}
|
|
||||||
wb.PutCF(d.cfh[cfTxAddresses], []byte(txID), buf)
|
wb.PutCF(d.cfh[cfTxAddresses], []byte(txID), buf)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -508,19 +498,6 @@ func (d *RocksDB) storeBalances(wb *gorocksdb.WriteBatch, abm map[string]*addrBa
|
|||||||
return nil
|
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 {
|
func (d *RocksDB) storeAndCleanupBlockTxids(wb *gorocksdb.WriteBatch, block *bchain.Block, txids [][]byte) error {
|
||||||
pl := d.chainParser.PackedTxidLen()
|
pl := d.chainParser.PackedTxidLen()
|
||||||
buf := make([]byte, pl*len(txids))
|
buf := make([]byte, pl*len(txids))
|
||||||
@ -582,6 +559,38 @@ func (d *RocksDB) getTxAddresses(btxID []byte) (*txAddresses, error) {
|
|||||||
if len(buf) < 2 {
|
if len(buf) < 2 {
|
||||||
return nil, nil
|
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{}
|
ta := txAddresses{}
|
||||||
inputs, l := unpackVaruint(buf)
|
inputs, l := unpackVaruint(buf)
|
||||||
ta.inputs = make([]txAddress, inputs)
|
ta.inputs = make([]txAddress, inputs)
|
||||||
@ -601,7 +610,7 @@ func unpackTxAddress(ta *txAddress, buf []byte) int {
|
|||||||
al, l := unpackVarint(buf)
|
al, l := unpackVarint(buf)
|
||||||
if al < 0 {
|
if al < 0 {
|
||||||
ta.spent = true
|
ta.spent = true
|
||||||
al ^= al
|
al = ^al
|
||||||
}
|
}
|
||||||
ta.addrID = make([]byte, al)
|
ta.addrID = make([]byte, al)
|
||||||
copy(ta.addrID, buf[l:l+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
|
// for number n, the packing is: 2*n if n>=0 else 2*(-n)-1
|
||||||
// takes only 1 byte if abs(n)<127
|
// 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 {
|
func setupRocksDB(t *testing.T, p bchain.BlockChainParser) *RocksDB {
|
||||||
tmp, err := ioutil.TempDir("", "testdb")
|
tmp, err := ioutil.TempDir("", "testdb")
|
||||||
if err != nil {
|
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
|
// 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) {
|
func TestRocksDB_Index_UTXO(t *testing.T) {
|
||||||
d := setupRocksDB(t, &testBitcoinParser{
|
d := setupRocksDB(t, &testBitcoinParser{
|
||||||
BitcoinParser: &btc.BitcoinParser{
|
BitcoinParser: bitcoinTestnetParser(),
|
||||||
BaseParser: &bchain.BaseParser{BlockAddressesToKeep: 1},
|
|
||||||
Params: btc.GetChainParams("test"),
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
defer closeAndDestroyRocksDB(t, d)
|
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