Fix processing of transactions in ConnectBlock
This commit is contained in:
parent
b2f24e82f9
commit
83edc33b3f
@ -374,6 +374,7 @@ func (d *RocksDB) writeAddressesUTXO(wb *gorocksdb.WriteBatch, block *bchain.Blo
|
||||
}
|
||||
addresses := make(map[string][]outpoint)
|
||||
unspentTxs := make(map[string][]byte)
|
||||
thisBlockTxs := make(map[string]struct{})
|
||||
btxIDs := make([][]byte, len(block.Txs))
|
||||
// first process all outputs, build mapping of addresses to outpoints and mappings of unspent txs to addresses
|
||||
for txi, tx := range block.Txs {
|
||||
@ -399,7 +400,9 @@ func (d *RocksDB) writeAddressesUTXO(wb *gorocksdb.WriteBatch, block *bchain.Blo
|
||||
}
|
||||
txAddrs = appendPackedAddrID(txAddrs, addrID, output.N, len(tx.Vout)-i)
|
||||
}
|
||||
unspentTxs[string(btxID)] = txAddrs
|
||||
stxID := string(btxID)
|
||||
unspentTxs[stxID] = txAddrs
|
||||
thisBlockTxs[stxID] = struct{}{}
|
||||
}
|
||||
// locate addresses spent by this tx and remove them from unspent addresses
|
||||
// keep them so that they be stored for DisconnectBlock functionality
|
||||
@ -415,30 +418,30 @@ func (d *RocksDB) writeAddressesUTXO(wb *gorocksdb.WriteBatch, block *bchain.Blo
|
||||
}
|
||||
return err
|
||||
}
|
||||
// try to find the tx in current block
|
||||
// find the tx in current block or already processed
|
||||
stxID := string(btxID)
|
||||
unspentAddrs, inThisBlock := unspentTxs[stxID]
|
||||
if !inThisBlock {
|
||||
unspentAddrs, exists := unspentTxs[stxID]
|
||||
if !exists {
|
||||
// else find it in previous blocks
|
||||
unspentAddrs, err = d.getUnspentTx(btxID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if unspentAddrs == nil {
|
||||
glog.Warningf("rocksdb: height %d, tx %v in inputs but missing in unspentTxs", block.Height, tx.Txid)
|
||||
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vin %v %v missing in unspentTxs", block.Height, tx.Txid, input.Txid, input.Vout, i)
|
||||
continue
|
||||
}
|
||||
}
|
||||
var addrID []byte
|
||||
addrID, unspentAddrs = findAndRemoveUnspentAddr(unspentAddrs, input.Vout)
|
||||
if addrID == nil {
|
||||
glog.Warningf("rocksdb: height %d, tx %v vin %v in inputs but missing in unspentTxs", block.Height, tx.Txid, i)
|
||||
glog.Warningf("rocksdb: height %d, tx %v, input tx %v vin %v %v not found in unspentAddrs", block.Height, tx.Txid, input.Txid, input.Vout, i)
|
||||
continue
|
||||
}
|
||||
// record what was removed from unspentTx
|
||||
// record what was spent in this tx
|
||||
// skip transactions that were created in this block
|
||||
saddrID := string(addrID)
|
||||
if _, exists := addresses[saddrID]; !exists {
|
||||
if _, exists := thisBlockTxs[stxID]; !exists {
|
||||
saddrID := string(addrID)
|
||||
rut := spentTxs[saddrID]
|
||||
rut = append(rut, outpoint{btxID, int32(input.Vout)})
|
||||
spentTxs[saddrID] = rut
|
||||
|
||||
@ -148,6 +148,12 @@ func getTestUTXOBlock1(t *testing.T, d *RocksDB) *bchain.Block {
|
||||
Hex: addressToPubKeyHex("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d),
|
||||
},
|
||||
},
|
||||
bchain.Vout{
|
||||
N: 2,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: addressToPubKeyHex("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d),
|
||||
},
|
||||
},
|
||||
},
|
||||
Blocktime: 22549300001,
|
||||
Time: 22549300001,
|
||||
@ -195,10 +201,12 @@ func getTestUTXOBlock2(t *testing.T, d *RocksDB) *bchain.Block {
|
||||
bchain.Tx{
|
||||
Txid: "3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71",
|
||||
Vin: []bchain.Vin{
|
||||
// spending an output in the same block
|
||||
bchain.Vin{
|
||||
Txid: "7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25",
|
||||
Vout: 0,
|
||||
},
|
||||
// spending an output in the previous block
|
||||
bchain.Vin{
|
||||
Txid: "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75",
|
||||
Vout: 1,
|
||||
@ -221,6 +229,26 @@ func getTestUTXOBlock2(t *testing.T, d *RocksDB) *bchain.Block {
|
||||
Blocktime: 22549400001,
|
||||
Time: 22549400001,
|
||||
},
|
||||
// transaction from the same address in the previous block
|
||||
bchain.Tx{
|
||||
Txid: "05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07",
|
||||
Vin: []bchain.Vin{
|
||||
bchain.Vin{
|
||||
Txid: "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75",
|
||||
Vout: 2,
|
||||
},
|
||||
},
|
||||
Vout: []bchain.Vout{
|
||||
bchain.Vout{
|
||||
N: 0,
|
||||
ScriptPubKey: bchain.ScriptPubKey{
|
||||
Hex: addressToPubKeyHex("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d),
|
||||
},
|
||||
},
|
||||
},
|
||||
Blocktime: 22549400002,
|
||||
Time: 22549400002,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -239,6 +267,7 @@ func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, noBlockAddresses bool) {
|
||||
keyPair{addressToPubKeyHex("mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", t, d) + "000370d5", "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "00", nil},
|
||||
keyPair{addressToPubKeyHex("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "04", nil},
|
||||
}); err != nil {
|
||||
{
|
||||
t.Fatal(err)
|
||||
@ -260,6 +289,7 @@ func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, noBlockAddresses bool) {
|
||||
return compareFuncBlockAddresses(t, v, []string{
|
||||
addressToPubKeyHexWithLength("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "00",
|
||||
addressToPubKeyHexWithLength("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "02",
|
||||
addressToPubKeyHexWithLength("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "04",
|
||||
})
|
||||
},
|
||||
},
|
||||
@ -273,7 +303,7 @@ func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, noBlockAddresses bool) {
|
||||
if noBlockAddresses {
|
||||
blockAddressesKp = []keyPair{}
|
||||
} else {
|
||||
// the values in cfBlockAddresses have random order, must use CompareFunc
|
||||
// the values in cfBlockAddresses are in random order, must use CompareFunc
|
||||
blockAddressesKp = []keyPair{
|
||||
keyPair{"000370d5", "",
|
||||
func(v string) bool {
|
||||
@ -282,6 +312,7 @@ func verifyAfterUTXOBlock1(t *testing.T, d *RocksDB, noBlockAddresses bool) {
|
||||
addressToPubKeyHexWithLength("mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", t, d) + "00",
|
||||
addressToPubKeyHexWithLength("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "00",
|
||||
addressToPubKeyHexWithLength("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "00",
|
||||
addressToPubKeyHexWithLength("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "00",
|
||||
})
|
||||
},
|
||||
},
|
||||
@ -308,12 +339,14 @@ func verifyAfterUTXOBlock2(t *testing.T, d *RocksDB) {
|
||||
keyPair{addressToPubKeyHex("mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", t, d) + "000370d5", "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "00", nil},
|
||||
keyPair{addressToPubKeyHex("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "000370d5", "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "04", nil},
|
||||
keyPair{addressToPubKeyHex("mzB8cYrfRwFRFAGTDzV8LkUQy5BQicxGhX", t, d) + "000370d6", "7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25" + "00" + "3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71" + "01", nil},
|
||||
keyPair{addressToPubKeyHex("mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL", t, d) + "000370d6", "7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("mwwoKQE5Lb1G4picHSHDQKg8jw424PF9SC", t, d) + "000370d6", "3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71" + "00", nil},
|
||||
keyPair{addressToPubKeyHex("mmJx9Y8ayz9h14yd9fgCW1bUKoEpkBAquP", t, d) + "000370d6", "3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71" + "02", nil},
|
||||
keyPair{addressToPubKeyHex("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "000370d6", "7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25" + "01", nil},
|
||||
keyPair{addressToPubKeyHex("mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", t, d) + "000370d6", "7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25" + "03", nil},
|
||||
keyPair{addressToPubKeyHex("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "000370d6", "05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07" + "00" + "05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07" + "01", nil},
|
||||
keyPair{addressToPubKeyHex("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "000370d6", "3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71" + "03", nil},
|
||||
}); err != nil {
|
||||
{
|
||||
@ -340,6 +373,11 @@ func verifyAfterUTXOBlock2(t *testing.T, d *RocksDB) {
|
||||
})
|
||||
},
|
||||
},
|
||||
keyPair{
|
||||
"05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07",
|
||||
addressToPubKeyHexWithLength("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "00",
|
||||
nil,
|
||||
},
|
||||
}); err != nil {
|
||||
{
|
||||
t.Fatal(err)
|
||||
@ -356,6 +394,7 @@ func verifyAfterUTXOBlock2(t *testing.T, d *RocksDB) {
|
||||
addressToPubKeyHexWithLength("mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", t, d) + "02" + "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "00",
|
||||
addressToPubKeyHexWithLength("mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", t, d) + "02" + "00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840" + "02",
|
||||
addressToPubKeyHexWithLength("2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS", t, d) + "02" + "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "02",
|
||||
addressToPubKeyHexWithLength("2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1", t, d) + "02" + "effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75" + "04",
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@ -670,9 +670,9 @@ func (s *SocketIoServer) getDetailedTransaction(txid string, opts txOpts) (res r
|
||||
}
|
||||
for _, vout := range tx.Vout {
|
||||
ao := txOutputs{
|
||||
Satoshis: int64(vout.Value * 1E8),
|
||||
Script: &vout.ScriptPubKey.Hex,
|
||||
SpentIndex: int(vout.N),
|
||||
Satoshis: int64(vout.Value * 1E8),
|
||||
Script: &vout.ScriptPubKey.Hex,
|
||||
// SpentIndex: int(vout.N),
|
||||
}
|
||||
if vout.Address != nil {
|
||||
a, err := vout.Address.EncodeAddress(opts.AddressFormat)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user