Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking balance bug #497

Open
Leozolt opened this issue Sep 2, 2022 · 13 comments
Open

Breaking balance bug #497

Leozolt opened this issue Sep 2, 2022 · 13 comments

Comments

@Leozolt
Copy link

Leozolt commented Sep 2, 2022

Recently discovered that a transaction got deducted double on explorer balance.

Screenshot_from_2022-08-30_15-28-28
See how the balance goes from 16k to 14k?

Now there is another coin where i didnt check all the transactions but there surely is a bug somewhere...

Screenshot from 2022-09-02 22-44-13

Hope you find the bug.

@furcalor
Copy link

furcalor commented Sep 3, 2022

This most likely is an issue with either the daemon or the explorer missing a block. Will do a re sync and check to see if that is the case, which I assume it is.,

@Leozolt
Copy link
Author

Leozolt commented Sep 3, 2022

The first example should leadt to the bug. The second example should demonstrate that its a recurring bug (its reproduceable) not a missing block. But if a resinc helps all good, which I assume that it wont help. In the first example, I send 1000 to the the block producer, that potentially also approved the transaction. In the second example I send the funds to an axchange addres, that might also be involved in block creation but on that second example I cant confirm. But the funds i send to the exchange addres seem to be decuted double.. Ill have to look those transactions up and veryfy if the balance gets a double deduction, which i dont really mind doing since I posted the problem here think I have done enough to lead you guys in the right direction to solve the issue, and I wont be able to fix the code or do a pull request.

@Leozolt
Copy link
Author

Leozolt commented Sep 3, 2022

Ok I found something, I dont know how to explain, but I think that here the transaction was reorganized in a way that the funds seem to partially come from another address. So only the portion that was directly deducted from my addres are considered for the explorer Balance (-542 instead of -2000 in this example). Hope the Images give better insight what I mean. Btw I took the screenshot early but awaited block maturity before posting this.

Screenshot from 2022-09-03 16-39-29
https://explorer.kawkawcoin.org/address/KWQnsVw5XpS8TLT4NWEWP3HftB1VdxbBk1

Screenshot from 2022-09-03 16-39-35
https://explorer.kawkawcoin.org/tx/d9d335550997520ae9e4123de0fbfde0bcfc5e5ab95356650ba6c5401e7ee565

I hope this helps.

@Leozolt
Copy link
Author

Leozolt commented Sep 3, 2022

This most likely is an issue with either the daemon or the explorer missing a block. Will do a re sync and check to see if that is the case, which I assume it is.,

You could be right with the deamon, could it be some kind of missing communication / compability issue between the explorer and the daemon?

@uaktags
Copy link
Collaborator

uaktags commented Sep 4, 2022

So I'm trying to follow along:
Using a single account as reference: KWQnsVw5XpS8TLT4NWEWP3HftB1VdxbBk1

You're seeing that you have less balance on the explorer than you do in the wallet itself.
This leads me to believe there are probably nonstandard transactions being handled at some level.

The output and input transactions are handled here in code respectively:

explorer/lib/explorer.js

Lines 493 to 540 in 064134c

prepare_vout: function(vout, txid, vin, cb) {
var arr_vout = [];
var arr_vin = [];
arr_vin = vin;
module.exports.syncLoop(vout.length, function (loop) {
var i = loop.iteration();
// make sure vout has an address
if (vout[i].scriptPubKey.type != 'nonstandard' && vout[i].scriptPubKey.type != 'nulldata') {
// check if vout address is unique, if so add it array, if not add its amount to existing index
//console.log('vout:' + i + ':' + txid);
module.exports.is_unique(arr_vout, vout[i].scriptPubKey.addresses[0], function(unique, index) {
if (unique == true) {
// unique vout
module.exports.convert_to_satoshi(parseFloat(vout[i].value), function(amount_sat){
arr_vout.push({addresses: vout[i].scriptPubKey.addresses[0], amount: amount_sat});
loop.next();
});
} else {
// already exists
module.exports.convert_to_satoshi(parseFloat(vout[i].value), function(amount_sat){
arr_vout[index].amount = arr_vout[index].amount + amount_sat;
loop.next();
});
}
});
} else {
// no address, move to next vout
loop.next();
}
}, function(){
if (vout[0].scriptPubKey.type == 'nonstandard') {
if ( arr_vin.length > 0 && arr_vout.length > 0 ) {
if (arr_vin[0].addresses == arr_vout[0].addresses) {
//PoS
arr_vout[0].amount = arr_vout[0].amount - arr_vin[0].amount;
arr_vin.shift();
return cb(arr_vout, arr_vin);
} else {
return cb(arr_vout, arr_vin);
}
} else {
return cb(arr_vout, arr_vin);
}
} else {
return cb(arr_vout, arr_vin);
}
});
},

explorer/lib/explorer.js

Lines 580 to 607 in 064134c

prepare_vin: function(tx, cb) {
var arr_vin = [];
module.exports.syncLoop(tx.vin.length, function (loop) {
var i = loop.iteration();
module.exports.get_input_addresses(tx.vin[i], tx.vout, function(addresses){
if (addresses && addresses.length) {
//console.log('vin');
module.exports.is_unique(arr_vin, addresses[0].hash, function(unique, index) {
if (unique == true) {
module.exports.convert_to_satoshi(parseFloat(addresses[0].amount), function(amount_sat){
arr_vin.push({addresses:addresses[0].hash, amount:amount_sat});
loop.next();
});
} else {
module.exports.convert_to_satoshi(parseFloat(addresses[0].amount), function(amount_sat){
arr_vin[index].amount = arr_vin[index].amount + amount_sat;
loop.next();
});
}
});
} else {
loop.next();
}
});
}, function(){
return cb(arr_vin);
});
}

So if the explorer balance is less than the wallet, we're most likely not detecting the KWQ address correctly in a tx where that address is the vout (receiving end).

Looking at the tx you mentioned (d9d3355)
we have the following inputs:

const txes = [
      'eec5deff42d3471a105753bc1aa9733cca995b5eef966152f44236abedf16308',
      'c0ca6a1aa15555d66d7b13c9c19ae7a35d7ee79b098002696d15476bbd86f30d',
      '25017a10a4bd9a0ffa37a457584171c8479d657e64383159d6b8b70d4ee55610',
      '1841ee091431450167685281f4333313c2ddaa4e7a9cf146c9daac77a4d0d217',
'9dc9f04ae92053c2392a3306b4cf77a342fc6149ac1734912be2f2b63a38cb28',
'1605593e27fac7fa0391b81d6abc8876ffd53c08436d594d813b8cecaa65882b',
'ea3894bbc826e1c0020ed91867b73e6896c2d8e50ec56d8721f61b15df5dac31',
'a6b6a160d87df808b5aaf6579abbf1d8025ca42d7ec17e5bae2e7b2e0919f437',
'c5fb880687f0df6eeebc5e72338928f90c7da2cb15304292452c7bf7b6ac0348',
'453d4ceb08c66bdb27c1c23903ddc683933ab15226c5539e061be0c07b73675f',
'a4647a5cc52574b760d74c99878c2c97cf55fdf957f31d54e63c418136129660',
'3392d1b433c55e3599f69b0108239b8797168963ded5eb5ba3e2e38712cad56a',
'5bdff088a4d2dcbe89548f1b68aad6b79adaa58854defc5c39381f9255846171',
'2d7e99a9d8e20525ab2c96248e7f06b2056e7903357af564f405e4e536b97780',
'80593edf19f5244fafac469e351d962d87ea619fbf8ffa933907e7e9110b5d8e',
'fd23adb6712dabf54d0acea83b3fa3b7123aa9920f3376ed206e013aa4913d90',
'c5b63f740a3025d320ca2191ba8690db78a9c0242ee3f630f9d65a5e993b1698',
'd362b270f41ec5de6379c546f9a8490a968598e759e349443f8eeea9916490a1',
'c6fdf1c8a31e0e399c3f0039be9ba7e29cabb6d494f6dc1fb579fcb81142e8a2',
'893516c5cdc2c5d65eb5d298d9382b6da646c728e8f0d3d3b5a5583feef59aa5',
'b662f2e892a3a22ac6c925da4c592e514cb22e4e733dba2a169fbd1fb66572bc',
'8998c1987959684d70f28400c320c77261f525ab4c028c779b104fdfaae8e3c4',
'a8318c75b5000a2fca4c18988addbdfca1371508ff3a12fbaa36bb7c00646edf',
'06eb837ab3d01fe5555e98831ecb36c513c4cf94aaad42d4c5f3a6cad8f439e7',
'a7c7592077de06b6bf524abe61d82f7d7e27cde8aa8ec5d302e3cf9c25b09be9',
'f6a9511dc7b3eee84c172e77a8b116669bfcdc1973b211bebd1173141eaba4ee',
'c1cc2f732649488ad654720c1f916ce9ba68e4d28d586cd848c92f1b0c6b93f4',
'fe687fa53e0bb40058319ed1fb838dac5124e792eb17542b7e26518c4fdca2f5'  
]

Testing that out with the following led to the same vin in your screenshot:

const axios = require('axios');

async function runit(){
    const txes = [
        'eec5deff42d3471a105753bc1aa9733cca995b5eef966152f44236abedf16308',
        'c0ca6a1aa15555d66d7b13c9c19ae7a35d7ee79b098002696d15476bbd86f30d',
        '25017a10a4bd9a0ffa37a457584171c8479d657e64383159d6b8b70d4ee55610',
        '1841ee091431450167685281f4333313c2ddaa4e7a9cf146c9daac77a4d0d217',
  '9dc9f04ae92053c2392a3306b4cf77a342fc6149ac1734912be2f2b63a38cb28',
  '1605593e27fac7fa0391b81d6abc8876ffd53c08436d594d813b8cecaa65882b',
  'ea3894bbc826e1c0020ed91867b73e6896c2d8e50ec56d8721f61b15df5dac31',
  'a6b6a160d87df808b5aaf6579abbf1d8025ca42d7ec17e5bae2e7b2e0919f437',
  'c5fb880687f0df6eeebc5e72338928f90c7da2cb15304292452c7bf7b6ac0348',
  '453d4ceb08c66bdb27c1c23903ddc683933ab15226c5539e061be0c07b73675f',
  'a4647a5cc52574b760d74c99878c2c97cf55fdf957f31d54e63c418136129660',
  '3392d1b433c55e3599f69b0108239b8797168963ded5eb5ba3e2e38712cad56a',
  '5bdff088a4d2dcbe89548f1b68aad6b79adaa58854defc5c39381f9255846171',
  '2d7e99a9d8e20525ab2c96248e7f06b2056e7903357af564f405e4e536b97780',
  '80593edf19f5244fafac469e351d962d87ea619fbf8ffa933907e7e9110b5d8e',
  'fd23adb6712dabf54d0acea83b3fa3b7123aa9920f3376ed206e013aa4913d90',
  'c5b63f740a3025d320ca2191ba8690db78a9c0242ee3f630f9d65a5e993b1698',
  'd362b270f41ec5de6379c546f9a8490a968598e759e349443f8eeea9916490a1',
  'c6fdf1c8a31e0e399c3f0039be9ba7e29cabb6d494f6dc1fb579fcb81142e8a2',
  '893516c5cdc2c5d65eb5d298d9382b6da646c728e8f0d3d3b5a5583feef59aa5',
  'b662f2e892a3a22ac6c925da4c592e514cb22e4e733dba2a169fbd1fb66572bc',
  '8998c1987959684d70f28400c320c77261f525ab4c028c779b104fdfaae8e3c4',
  'a8318c75b5000a2fca4c18988addbdfca1371508ff3a12fbaa36bb7c00646edf',
  '06eb837ab3d01fe5555e98831ecb36c513c4cf94aaad42d4c5f3a6cad8f439e7',
  'a7c7592077de06b6bf524abe61d82f7d7e27cde8aa8ec5d302e3cf9c25b09be9',
  'f6a9511dc7b3eee84c172e77a8b116669bfcdc1973b211bebd1173141eaba4ee',
  'c1cc2f732649488ad654720c1f916ce9ba68e4d28d586cd848c92f1b0c6b93f4',
  'fe687fa53e0bb40058319ed1fb838dac5124e792eb17542b7e26518c4fdca2f5'  
  ];
  let balance = 0;

  for(let i = 0; i<txes.length; i++){
    const res = await axios.get(`https://explorer.kawkawcoin.org/api/getrawtransaction?txid=${txes[i]}&decrypt=1`);
    for(let n = 0; n <res.data.vout.length; n++){
        if(res.data.vout[n].scriptPubKey.addresses.includes("KWQnsVw5XpS8TLT4NWEWP3HftB1VdxbBk1")){
            balance += res.data.vout[n].value;
        }
    }
  }
  console.log(balance);
  process.abort();

}
runit();

So i don't see any issue with that transaction.
Looking at your screenshot, I see the same amounts showing for the incoming txes as what your explorer is showing as well.

Can you pull a transaction list from your daemon/wallet and compare the transaction amounts to what your explorer has. Maybe find the transaction that may be missing or incorrectly parsed so that we can look at it.

As of right now, it's just going to be a needle in a haystack for anyone else to try to help.

@uaktags
Copy link
Collaborator

uaktags commented Sep 4, 2022

As for "-542 instead of -2000 in this example" this is because your account didn't provide 2000 dollars in this transaction, you provided 542 and address k9z7 provided the rest.

So doublecheck, do you have 2 wallet addresses in your wallet? If so, there's your problem. You're mistaking an aggregated wallet of multiple pubkeys with a single pubkey.

https://explorer.kawkawcoin.org/address/K9z7FsLwZcPF3KzQFYjjqamUg1LySogLE9
At the time of writing:
K9z7 has 22k KAW
KWQn has 22.526k KAW
Total = 44.526k KAW which is pretty close to accurate. Especially if you may have another pubkey available.

@Leozolt
Copy link
Author

Leozolt commented Sep 4, 2022

oooh ok now I got it, I used 2 different receiving addresses and completely forgot that, because of that, I need to check both to get the balance for that private key. If you accept tips in KAW let me know your address.

On the other hand, I still cant figure out the double deduction in explorer for the snark address https://snark.mining4people.com/address/SUPREMEFx4nsVWFrAFBGLFkbDvJAQ4qjk6 shown in the the very first picture. Ill try to pull a transaction list for that wallet and come back.

Thank you very much so far for the wonderfull lesson!

@uaktags
Copy link
Collaborator

uaktags commented Sep 4, 2022

Unfortunately I do not have an answer for the snark issue. To me, it looks like something got doubled, but there's nothing in the official unmodified code for 1.7.4 that would cause the duplication AFAIK.

The amount that's different is exactly 2x the amount shown for the vout/vins. The same thing happened on the flip side for STd SYTR from that transaction. They both received double what they should have, but all other transactions appear to be fine.
https://snark.mining4people.com/api/getrawtransaction?txid=7d5f01e5423d57814bd77dd49bb6b6a4fedd1eddf536fc1098f8384a82d25d36&decrypt=1
also shows the correct information.

I think the only way to really figure out whats going on is a resync of those blocks with some debugging messages in place to capture what is going on with the operations at that time. Looking at that 1 block (https://snark.mining4people.com/block/000000000003837eb594ba3a175bc04cc63ef9bdfa37fb7e73295f5fe1d45528) is proving to be problematic for the balances.

Unfortunately, I'm just not seeing the root for that issue at this time. It feels like something got doubled, which I can only wonder would happen if the code was either A) modified, or somehow the sync happened 2x on that 1 block (perhaps at the end of 1 batch for a cron and the start of another batch from a cron?).

Thinking over that:

explorer/scripts/sync.js

Lines 125 to 129 in 064134c

is_locked(function (exists) {
if (exists) {
console.log("Script already running..");
process.exit(0);
} else {

The sync shouldn't allow for any other cron to start due to the above locks, however, we rely on "stats.last" for the last height we worked on during the last run as seen here:

explorer/scripts/sync.js

Lines 188 to 194 in 064134c

} else if (mode == 'update') {
db.update_tx_db(settings.coin, stats.last, stats.count, settings.update_timeout, function(){
db.update_richlist('received', function(){
db.update_richlist('balance', function(){
db.get_stats(settings.coin, function(nstats){
console.log('update complete (block: %s)', nstats.last);
exit();

So i'm wondering if its possible that at the time that it ran, since we set the stats.last to the previous height we worked on (not the current we're on

last: block_height - 1,
). Then when it ran the first time, it properly started the calculations, and saved them, but didn't save the txes themselves correctly. So when it ran again, it saw this as a tx that was never done, and did the calculations a second time, and properly saved the tx, however with a duplication of values.

I don't see this actually being the issue though, as that should be a widespread problem vs a single block on a single coin, but that's just my working theory. If you're the snark admin, then I'd look at the above and throw some stops in place. If you can make a test environment with your current data. It may be beneficial to remove everything about that block's txes (there's 4 of them) and manually set the stats.last to a block or two before that block, and run update again.

@Leozolt
Copy link
Author

Leozolt commented Sep 4, 2022

To get more specific to the transaction, It was a tip to the mining4people pool, and the pool found the block too. Maybe an edge case?

https://snark.mining4people.com/block/000000000003837eb594ba3a175bc04cc63ef9bdfa37fb7e73295f5fe1d45528

Had a hard time extracting this but here is what the wallet lists for the transaction in question:
{
"address": "STdmAgShfT9C4BtHTyDk2uy2NUaBdRDnWA",
"category": "send",
"amount": -1000.00000000,
"label": "explorer",
"vout": 1,
"fee": -0.00000978,
"confirmations": 1246,
"instantlock": false,
"instantlock_internal": false,
"chainlock": false,
"blockhash": "000000000003837eb594ba3a175bc04cc63ef9bdfa37fb7e73295f5fe1d45528",
"blockindex": 3,
"blocktime": 1661865121,
"txid": "7d5f01e5423d57814bd77dd49bb6b6a4fedd1eddf536fc1098f8384a82d25d36",
"walletconflicts": [
],
"time": 1661864355,
"timereceived": 1661864355,
"abandoned": false
}

Now I know how so I could list all the transactions all since the beginning of that address, but there nothing I could really do myself on that chunk of data.

Alternatively I could transfer 92% to another private key, leave the rest as bounty and send you that private key for debugging and keeping whats left on the wallet?

@uaktags
Copy link
Collaborator

uaktags commented Sep 4, 2022 via email

@Leozolt
Copy link
Author

Leozolt commented Sep 4, 2022

@furcalor Hope this all helps.
@uaktags Let me know if you accept tips in the concerned coins

Thank you

@uaktags
Copy link
Collaborator

uaktags commented Sep 4, 2022

Certainly, just got this guy created:
KLfb4wQf1oRXzup2MN4cB2GzfbAhcE8tRx

Appreciate it!
I will also say, as KAW is using team-exor's fork maintained by (@joeuhren), perhaps that may be something to try for SNARK/Mining4People just to see if there is a bug in this older codebase vs something more maintained.

@Leozolt
Copy link
Author

Leozolt commented Sep 5, 2022

@uaktags Just a quick notification that i tipped you. Not that you forget about it and maybe abandon the funds. Btw, I tried your websites on your profile and they both have an issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants