- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 3.3k
 
add the right prunable hash per tx to pruned get_blocks.bin call #10137
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
base: master
Are you sure you want to change the base?
add the right prunable hash per tx to pruned get_blocks.bin call #10137
Conversation
| 
           This adds >32B per transaction for  Also, the RPC minor version should to be bumped since a feature was added.  | 
    
| 
           The current   | 
    
| 
           Sorry, I was under the impression that null hashes don't get serialized in   | 
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for taking this on! Once the below issues are addressed, I will be willing to approve.
| throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str())); | ||
| 
               | 
          ||
| crypto::hash prunable_hash = *(const crypto::hash*)v.mv_data; | ||
| current_block.second.push_back(std::make_pair(prunable_hash, std::move(tx_blob))); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NACK replacing the TXID with the prunable hash, this silently breaks the API of BlockchainDB. If we must update the API here, the function signature should be a breaking change so that downstream fails to compile. That, or we can write a new get_blocks_from() method override and implement the older override with the newer override so that it's non-breaking.
| if (pruned) { | ||
| // get the prunable hash | ||
| 
               | 
          ||
| // Look up each transaction's tx_id | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can skip the TXID -> tx index lookup by using already existing tx_id (terrible name 😢) variable. Tx on-chain indices are assigned in ascending order by 1) block, then 2) txs in block in specified order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm trying to understand this and your  next #10137 (comment) .   if you mean it would be enough just to do result = mdb_cursor_get(m_cur_txs_prunable_hash, &val_tx_id, &v, op); instead of first fetching the tx index, that doesn't work for txs_prunable_hash table like it would for txs_pruned or txs_prunabletables. it gives the same prunable hash over over for all txs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean that you should do a MDB_SET op first to first set the cursor to the entry at tx_id for the first transaction in the list, then do MDB_NEXT afterwards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late reply. Had a busy week. So it looks like I miss the MDB_SET that happens inside this if block 
monero/src/blockchain_db/lmdb/db_lmdb.cpp
Line 3301 in d32b5bf
| if (skip_coinbase) | 
MDB_SET for tables txs_prunable and txs_pruned is inside the if block. I checked BlockchainLMDB::get_blocks_from is always called with skip_coinbase is true and it looks like the function won't return as intended if that were to be passed as false since those tables would also be calling MDB_NEXT before MDB_SET. Indeed, when I compiled it with false, monero-wallet-cli couldn't scan the chain. It immediately throws exception Error: refresh failed: internal error: Exception in thread pool. Blocks received: 0.
So I believe there is a bug there. If skip_coinbase is  necessary for that function to work properly it shouldn't be a parameter? I think the original intention was to actually skip the coinbase tx in each block by retrieving the tx and ignoring the value of  the call so that cursor moves to the next tx when calling with MDB_NEXT and that works as intended if we wanted to skip the coinbase txs but otherwise it misses the MDB_SET op to those tables. So a fix would be to always call MDB_SETand only ignore the value if skip_coinbase is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the skip_coinbase=false thing is a bug. I opened #10166 to fix it. Perhaps you could rebase this PR on top of that? But yes, generally, you should do MDB_SET once and then MDB_NEXT afterwards for sequential keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I can rebase once that pr is merged 👍
Fixes #10120 .
This approach uses the already existing
bsreturn type fromfind_blockchain_supplementfunction call instead of fetching the prunable hashes separately. The second of thebstypestd::vector<std::pair<crypto::hash, cryptonote::blobdata>>It appears to be used for tx hash and pruned tx blob if pruned istrue. However that tx hash is never used, so this approach uses that place for prunable hash and passes it to the return type accordingly.This behavior might be documented or another approach might have been fetching prunable hashes separately after the
find_blockchain_supplementcall. This approach is chosen not to make that second call to the db and for its simplicity.Comments are welcome!