main: fixed bug with overlapping address index keys
There was a bug where the spending address index could have the same key as the receiving address index if the input and output indexes matched. This lead to the output always overwriting the input index leading to incorrect balances with missing spent amounts. This patch separates the two so that they have unique keys so balances will be correctly calculated.
This commit is contained in:
parent
3d90427d0b
commit
70600ae1ff
|
@ -145,7 +145,7 @@ class AddressIndexTest(BitcoinTestFramework):
|
||||||
tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))]
|
tx.vin = [CTxIn(COutPoint(int(spending_txid, 16), 0))]
|
||||||
send_amount = 1 * 100000000 + 12840
|
send_amount = 1 * 100000000 + 12840
|
||||||
change_amount = amount - send_amount - 10000
|
change_amount = amount - send_amount - 10000
|
||||||
tx.vout = [CTxOut(send_amount, scriptPubKey), CTxOut(change_amount, scriptPubKey2)]
|
tx.vout = [CTxOut(change_amount, scriptPubKey2), CTxOut(send_amount, scriptPubKey)]
|
||||||
tx.rehash()
|
tx.rehash()
|
||||||
|
|
||||||
signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
|
signed_tx = self.nodes[0].signrawtransaction(binascii.hexlify(tx.serialize()).decode("utf-8"))
|
||||||
|
|
|
@ -2527,10 +2527,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
const CTxOut &prevout = view.GetOutputFor(tx.vin[j]);
|
||||||
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
if (prevout.scriptPubKey.IsPayToScriptHash()) {
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+2, prevout.scriptPubKey.begin()+22);
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, j), prevout.nValue * -1));
|
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||||
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
} else if (prevout.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
vector<unsigned char> hashBytes(prevout.scriptPubKey.begin()+3, prevout.scriptPubKey.begin()+23);
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, j), prevout.nValue * -1));
|
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, j, true), prevout.nValue * -1));
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2564,10 +2564,10 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
|
|
||||||
if (out.scriptPubKey.IsPayToScriptHash()) {
|
if (out.scriptPubKey.IsPayToScriptHash()) {
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+2, out.scriptPubKey.begin()+22);
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k), out.nValue));
|
addressIndex.push_back(make_pair(CAddressIndexKey(2, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
|
||||||
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
} else if (out.scriptPubKey.IsPayToPublicKeyHash()) {
|
||||||
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
vector<unsigned char> hashBytes(out.scriptPubKey.begin()+3, out.scriptPubKey.begin()+23);
|
||||||
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k), out.nValue));
|
addressIndex.push_back(make_pair(CAddressIndexKey(1, uint160(hashBytes), pindex->nHeight, i, txhash, k, false), out.nValue));
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,6 +338,7 @@ struct CAddressIndexKey {
|
||||||
unsigned int txindex;
|
unsigned int txindex;
|
||||||
uint256 txhash;
|
uint256 txhash;
|
||||||
size_t outindex;
|
size_t outindex;
|
||||||
|
bool spending;
|
||||||
|
|
||||||
size_t GetSerializeSize(int nType, int nVersion) const {
|
size_t GetSerializeSize(int nType, int nVersion) const {
|
||||||
return 65;
|
return 65;
|
||||||
|
@ -351,6 +352,8 @@ struct CAddressIndexKey {
|
||||||
ser_writedata32be(s, txindex);
|
ser_writedata32be(s, txindex);
|
||||||
txhash.Serialize(s, nType, nVersion);
|
txhash.Serialize(s, nType, nVersion);
|
||||||
ser_writedata32(s, outindex);
|
ser_writedata32(s, outindex);
|
||||||
|
char f = spending;
|
||||||
|
ser_writedata8(s, f);
|
||||||
}
|
}
|
||||||
template<typename Stream>
|
template<typename Stream>
|
||||||
void Unserialize(Stream& s, int nType, int nVersion) {
|
void Unserialize(Stream& s, int nType, int nVersion) {
|
||||||
|
@ -360,16 +363,19 @@ struct CAddressIndexKey {
|
||||||
txindex = ser_readdata32be(s);
|
txindex = ser_readdata32be(s);
|
||||||
txhash.Unserialize(s, nType, nVersion);
|
txhash.Unserialize(s, nType, nVersion);
|
||||||
outindex = ser_readdata32(s);
|
outindex = ser_readdata32(s);
|
||||||
|
char f = ser_readdata8(s);
|
||||||
|
spending = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex,
|
CAddressIndexKey(unsigned int addressType, uint160 addressHash, int height, int blockindex,
|
||||||
uint256 txid, size_t outputIndex) {
|
uint256 txid, size_t outputIndex, bool isSpending) {
|
||||||
type = addressType;
|
type = addressType;
|
||||||
hashBytes = addressHash;
|
hashBytes = addressHash;
|
||||||
blockHeight = height;
|
blockHeight = height;
|
||||||
txindex = blockindex;
|
txindex = blockindex;
|
||||||
txhash = txid;
|
txhash = txid;
|
||||||
outindex = outputIndex;
|
outindex = outputIndex;
|
||||||
|
spending = isSpending;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAddressIndexKey() {
|
CAddressIndexKey() {
|
||||||
|
@ -383,6 +389,7 @@ struct CAddressIndexKey {
|
||||||
txindex = 0;
|
txindex = 0;
|
||||||
txhash.SetNull();
|
txhash.SetNull();
|
||||||
outindex = 0;
|
outindex = 0;
|
||||||
|
spending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue