Add extended index option - vin.txid
This commit is contained in:
parent
d52832f6f7
commit
708f96cf57
@ -844,6 +844,10 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
|
||||
if err != nil {
|
||||
glog.Errorf("tai.Addresses error %v, tx %v, input %v, tai %+v", err, txid, i, tai)
|
||||
}
|
||||
if w.db.HasExtendedIndex() {
|
||||
vin.Txid = tai.Txid
|
||||
vin.Vout = tai.Vout
|
||||
}
|
||||
aggregateAddresses(addresses, vin.Addresses, vin.IsAddress)
|
||||
}
|
||||
vouts := make([]Vout, len(ta.Outputs))
|
||||
@ -882,6 +886,11 @@ func (w *Worker) txFromTxAddress(txid string, ta *db.TxAddresses, bi *db.BlockIn
|
||||
Vin: vins,
|
||||
Vout: vouts,
|
||||
}
|
||||
if w.chainParser.SupportsVSize() {
|
||||
r.VSize = int(ta.VSize)
|
||||
} else {
|
||||
r.Size = int(ta.VSize)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
116
db/rocksdb.go
116
db/rocksdb.go
@ -415,6 +415,9 @@ type outpoint struct {
|
||||
type TxInput struct {
|
||||
AddrDesc bchain.AddressDescriptor
|
||||
ValueSat big.Int
|
||||
// extended index properties
|
||||
Txid string
|
||||
Vout uint32
|
||||
}
|
||||
|
||||
// Addresses converts AddressDescriptor of the input to array of strings
|
||||
@ -424,9 +427,10 @@ func (ti *TxInput) Addresses(p bchain.BlockChainParser) ([]string, bool, error)
|
||||
|
||||
// TxOutput holds output data of the transaction in TxAddresses
|
||||
type TxOutput struct {
|
||||
AddrDesc bchain.AddressDescriptor
|
||||
Spent bool
|
||||
ValueSat big.Int
|
||||
AddrDesc bchain.AddressDescriptor
|
||||
Spent bool
|
||||
ValueSat big.Int
|
||||
// extended index properties
|
||||
SpentTxid string
|
||||
SpentIndex uint32
|
||||
SpentHeight uint32
|
||||
@ -442,6 +446,8 @@ type TxAddresses struct {
|
||||
Height uint32
|
||||
Inputs []TxInput
|
||||
Outputs []TxOutput
|
||||
// extended index properties
|
||||
VSize uint32
|
||||
}
|
||||
|
||||
// Utxo holds information about unspent transaction output
|
||||
@ -596,13 +602,21 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses add
|
||||
}
|
||||
blockTxIDs[txi] = btxID
|
||||
ta := TxAddresses{Height: block.Height}
|
||||
if d.extendedIndex {
|
||||
if tx.VSize > 0 {
|
||||
ta.VSize = uint32(tx.VSize)
|
||||
} else {
|
||||
ta.VSize = uint32(len(tx.Hex))
|
||||
}
|
||||
}
|
||||
ta.Outputs = make([]TxOutput, len(tx.Vout))
|
||||
txAddressesMap[string(btxID)] = &ta
|
||||
blockTxAddresses[txi] = &ta
|
||||
for i, output := range tx.Vout {
|
||||
for i := range tx.Vout {
|
||||
output := &tx.Vout[i]
|
||||
tao := &ta.Outputs[i]
|
||||
tao.ValueSat = output.ValueSat
|
||||
addrDesc, err := d.chainParser.GetAddrDescFromVout(&output)
|
||||
addrDesc, err := d.chainParser.GetAddrDescFromVout(output)
|
||||
if err != nil || len(addrDesc) == 0 || len(addrDesc) > maxAddrDescLen {
|
||||
if err != nil {
|
||||
// do not log ErrAddressMissing, transactions can be without to address (for example eth contracts)
|
||||
@ -652,7 +666,8 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses add
|
||||
ta := blockTxAddresses[txi]
|
||||
ta.Inputs = make([]TxInput, len(tx.Vin))
|
||||
logged := false
|
||||
for i, input := range tx.Vin {
|
||||
for i := range tx.Vin {
|
||||
input := &tx.Vin[i]
|
||||
tai := &ta.Inputs[i]
|
||||
btxID, err := d.chainParser.PackTxid(input.Txid)
|
||||
if err != nil {
|
||||
@ -695,6 +710,8 @@ func (d *RocksDB) processAddressesBitcoinType(block *bchain.Block, addresses add
|
||||
spentOutput.SpentTxid = tx.Txid
|
||||
spentOutput.SpentIndex = uint32(i)
|
||||
spentOutput.SpentHeight = block.Height
|
||||
tai.Txid = input.Txid
|
||||
tai.Vout = input.Vout
|
||||
}
|
||||
if len(spentOutput.AddrDesc) == 0 {
|
||||
if !logged {
|
||||
@ -951,10 +968,14 @@ func (d *RocksDB) packTxAddresses(ta *TxAddresses, buf []byte, varBuf []byte) []
|
||||
buf = buf[:0]
|
||||
l := packVaruint(uint(ta.Height), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
if d.extendedIndex {
|
||||
l = packVaruint(uint(ta.VSize), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
}
|
||||
l = packVaruint(uint(len(ta.Inputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range ta.Inputs {
|
||||
buf = appendTxInput(&ta.Inputs[i], buf, varBuf)
|
||||
buf = d.appendTxInput(&ta.Inputs[i], buf, varBuf)
|
||||
}
|
||||
l = packVaruint(uint(len(ta.Outputs)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
@ -964,13 +985,38 @@ func (d *RocksDB) packTxAddresses(ta *TxAddresses, buf []byte, varBuf []byte) []
|
||||
return buf
|
||||
}
|
||||
|
||||
func appendTxInput(txi *TxInput, buf []byte, varBuf []byte) []byte {
|
||||
func (d *RocksDB) appendTxInput(txi *TxInput, buf []byte, varBuf []byte) []byte {
|
||||
la := len(txi.AddrDesc)
|
||||
l := packVaruint(uint(la), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
buf = append(buf, txi.AddrDesc...)
|
||||
l = packBigint(&txi.ValueSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
var l int
|
||||
if d.extendedIndex {
|
||||
if txi.Txid == "" {
|
||||
// coinbase transaction
|
||||
la = ^la
|
||||
}
|
||||
l = packVarint(la, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
buf = append(buf, txi.AddrDesc...)
|
||||
l = packBigint(&txi.ValueSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
if la >= 0 {
|
||||
btxID, err := d.chainParser.PackTxid(txi.Txid)
|
||||
if err != nil {
|
||||
if err != bchain.ErrTxidMissing {
|
||||
glog.Error("Cannot pack txid ", txi.Txid)
|
||||
}
|
||||
btxID = make([]byte, d.chainParser.PackedTxidLen())
|
||||
}
|
||||
buf = append(buf, btxID...)
|
||||
l = packVaruint(uint(txi.Vout), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
}
|
||||
} else {
|
||||
l = packVaruint(uint(la), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
buf = append(buf, txi.AddrDesc...)
|
||||
l = packBigint(&txi.ValueSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
@ -1049,7 +1095,7 @@ func packAddrBalance(ab *AddrBalance, buf, varBuf []byte) []byte {
|
||||
l = packBigint(&ab.BalanceSat, varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for _, utxo := range ab.Utxos {
|
||||
// if Vout < 0, utxo is marked as spent
|
||||
// if Vout < 0, utxo is marked as spent and removed from the entry
|
||||
if utxo.Vout >= 0 {
|
||||
buf = append(buf, utxo.BtxID...)
|
||||
l = packVaruint(uint(utxo.Vout), varBuf)
|
||||
@ -1067,11 +1113,16 @@ func (d *RocksDB) unpackTxAddresses(buf []byte) (*TxAddresses, error) {
|
||||
ta := TxAddresses{}
|
||||
height, l := unpackVaruint(buf)
|
||||
ta.Height = uint32(height)
|
||||
if d.extendedIndex {
|
||||
vsize, ll := unpackVaruint(buf[l:])
|
||||
ta.VSize = uint32(vsize)
|
||||
l += ll
|
||||
}
|
||||
inputs, ll := unpackVaruint(buf[l:])
|
||||
l += ll
|
||||
ta.Inputs = make([]TxInput, inputs)
|
||||
for i := uint(0); i < inputs; i++ {
|
||||
l += unpackTxInput(&ta.Inputs[i], buf[l:])
|
||||
l += d.unpackTxInput(&ta.Inputs[i], buf[l:])
|
||||
}
|
||||
outputs, ll := unpackVaruint(buf[l:])
|
||||
l += ll
|
||||
@ -1082,12 +1133,35 @@ func (d *RocksDB) unpackTxAddresses(buf []byte) (*TxAddresses, error) {
|
||||
return &ta, nil
|
||||
}
|
||||
|
||||
func unpackTxInput(ti *TxInput, buf []byte) int {
|
||||
al, l := unpackVaruint(buf)
|
||||
ti.AddrDesc = append([]byte(nil), buf[l:l+int(al)]...)
|
||||
al += uint(l)
|
||||
ti.ValueSat, l = unpackBigint(buf[al:])
|
||||
return l + int(al)
|
||||
func (d *RocksDB) unpackTxInput(ti *TxInput, buf []byte) int {
|
||||
if d.extendedIndex {
|
||||
al, l := unpackVarint(buf)
|
||||
var coinbase bool
|
||||
if al < 0 {
|
||||
coinbase = true
|
||||
al = ^al
|
||||
}
|
||||
ti.AddrDesc = append([]byte(nil), buf[l:l+al]...)
|
||||
al += l
|
||||
ti.ValueSat, l = unpackBigint(buf[al:])
|
||||
al += l
|
||||
if !coinbase {
|
||||
l = d.chainParser.PackedTxidLen()
|
||||
ti.Txid, _ = d.chainParser.UnpackTxid(buf[al : al+l])
|
||||
al += l
|
||||
var i uint
|
||||
i, l = unpackVaruint(buf[al:])
|
||||
ti.Vout = uint32(i)
|
||||
al += l
|
||||
}
|
||||
return al
|
||||
} else {
|
||||
al, l := unpackVaruint(buf)
|
||||
ti.AddrDesc = append([]byte(nil), buf[l:l+int(al)]...)
|
||||
al += uint(l)
|
||||
ti.ValueSat, l = unpackBigint(buf[al:])
|
||||
return l + int(al)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *RocksDB) unpackTxOutput(to *TxOutput, buf []byte) int {
|
||||
|
||||
@ -1016,21 +1016,28 @@ func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "extendedIndex 1",
|
||||
hex: "e0390317a9149eb21980dc9d413d8eac27314938b9da920ee53e8705021918f2c017a91409f70b896169c37981d2b54b371df0d81a136a2c870501dd7e28c017a914e371782582a4addb541362c55565d2cdf56f6498870501a1e35ec0052fa9141d9ca71efa36d814424ea6ca1437e67287aebe348705012aadcac000b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa38400081ce8685592ea91424fbc77cdc62702ade74dcf989c15e5d3f9240bc870501664894c02fa914afbfb74ee994c7d45f6698738bc4226d065266f7870501a1e35ec0effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75ef17a1f4233276a914d2a37ce20ac9ec4f15dd05a7c6e8e9fbdb99850e88ac043b9943603376a9146b2044146a4438e6e5bfbc65f147afeb64d14fbb88ac05012a05f2007c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25a9956d8396f32a",
|
||||
hex: "e0398241032ea9149eb21980dc9d413d8eac27314938b9da920ee53e8705021918f2c0c50c7ce2f5670fd52de738288299bd854a85ef1bb304f62f35ced1bd49a8a810002ea91409f70b896169c37981d2b54b371df0d81a136a2c870501dd7e28c0e96672c7fcc8da131427fcea7e841028614813496a56c11e8a6185c16861c495012ea914e371782582a4addb541362c55565d2cdf56f6498870501a1e35ec0ed308c72f9804dfeefdbb483ef8fd1e638180ad81d6b33f4b58d36d19162fa6d8106052fa9141d9ca71efa36d814424ea6ca1437e67287aebe348705012aadcac000b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa38400081ce8685592ea91424fbc77cdc62702ade74dcf989c15e5d3f9240bc870501664894c02fa914afbfb74ee994c7d45f6698738bc4226d065266f7870501a1e35ec0effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75ef17a1f4233276a914d2a37ce20ac9ec4f15dd05a7c6e8e9fbdb99850e88ac043b9943603376a9146b2044146a4438e6e5bfbc65f147afeb64d14fbb88ac05012a05f2007c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25a9956d8396f32a",
|
||||
data: &TxAddresses{
|
||||
Height: 12345,
|
||||
VSize: 321,
|
||||
Inputs: []TxInput{
|
||||
{
|
||||
AddrDesc: addressToAddrDesc("2N7iL7AvS4LViugwsdjTB13uN4T7XhV1bCP", parser),
|
||||
ValueSat: *big.NewInt(9011000000),
|
||||
Txid: "c50c7ce2f5670fd52de738288299bd854a85ef1bb304f62f35ced1bd49a8a810",
|
||||
Vout: 0,
|
||||
},
|
||||
{
|
||||
AddrDesc: addressToAddrDesc("2Mt9v216YiNBAzobeNEzd4FQweHrGyuRHze", parser),
|
||||
ValueSat: *big.NewInt(8011000000),
|
||||
Txid: "e96672c7fcc8da131427fcea7e841028614813496a56c11e8a6185c16861c495",
|
||||
Vout: 1,
|
||||
},
|
||||
{
|
||||
AddrDesc: addressToAddrDesc("2NDyqJpHvHnqNtL1F9xAeCWMAW8WLJmEMyD", parser),
|
||||
ValueSat: *big.NewInt(7011000000),
|
||||
Txid: "ed308c72f9804dfeefdbb483ef8fd1e638180ad81d6b33f4b58d36d19162fa6d",
|
||||
Vout: 134,
|
||||
},
|
||||
},
|
||||
Outputs: []TxOutput{
|
||||
@ -1072,9 +1079,10 @@ func Test_packTxAddresses_unpackTxAddresses(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "extendedIndex empty address",
|
||||
hex: "baef9a1501000204d2020002162e010162fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db03e039",
|
||||
hex: "baef9a152d01010204d2020002162e010162fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db03e039",
|
||||
data: &TxAddresses{
|
||||
Height: 123456789,
|
||||
VSize: 45,
|
||||
Inputs: []TxInput{
|
||||
{
|
||||
AddrDesc: []byte(nil),
|
||||
|
||||
@ -59,8 +59,8 @@
|
||||
</div>
|
||||
<div class="row footer">
|
||||
<div class="col-sm-12 col-md-4">
|
||||
{{if $tx.FeesSat}}
|
||||
Fee {{amountSpan $tx.FeesSat $data "txvalue copyable ms-3"}}
|
||||
{{if $tx.FeesSat}}{{$fpb := feePerByte $tx}}
|
||||
Fee {{amountSpan $tx.FeesSat $data "txvalue copyable ms-3"}}{{if $fpb}} <span class="fw-normal small">({{$fpb}})</span>{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-8 text-end">
|
||||
|
||||
Loading…
Reference in New Issue
Block a user