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

cryptonote_basic: remove unused to_script[_hash] vin/vout #8865

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jeffro256
Copy link
Contributor

Structs were added 9 years ago and have yet to be used

@jeffro256 jeffro256 force-pushed the rm_unused_vin_vout branch from ca94696 to 4f46d5a Compare May 26, 2023 05:43
Copy link
Contributor

@vtnerd vtnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you run this patch and validated the entire blockchain? Were these types allowed at any point? Could "stuck" funds be sent to them?

@jeffro256
Copy link
Contributor Author

Have you run this patch and validated the entire blockchain?

No, not yet, but that's a good idea.

Were these types allowed at any point?

If you look at the blockchain.cpp code, you can see that when visiting these types of vin/vout variants, validation always fails, with no exceptions.

Could "stuck" funds be sent to them?

I believe the tx will fail validation if they are ever attempted to be used.

@jeffro256
Copy link
Contributor Author

You can run this python script on a machine running monerod locally to convince yourself that the script/scripthash vin/vout types never appear on-chain:

import bisect
import json
import random
import requests

my_daemon_address = 'localhost:18081'
timeout_secs = 10

def invoke_json(addr, uri, json_data):
	resp = requests.post("http://" + addr + '/' + uri, json=json_data, timeout=timeout_secs)
	assert(resp.status_code == 200)
	resp_json = resp.json()
	if 'json_rpc' not in uri:
		assert(resp_json['status'] == 'OK')
	return resp_json

def invoke_json_rpc(addr, method, params):
	json_data = {'method': method, 'params': params}
	resp_json = invoke_json(addr, 'json_rpc', json_data)
	result = resp_json.get('result')
	error = resp_json.get('error')
	if error:
		print(error)
		raise ValueError("Error response in JSONRPC")
	return result

def get_height(addr):
	return invoke_json(addr, 'get_height', {})['height']

def get_block_txs_by_height(addr, height):
	result = invoke_json_rpc(addr, 'get_block', { 'height': height })
	block_json = json.loads(result['json'])
	return block_json['miner_tx'], block_json['tx_hashes']

def get_transactions(addr, tx_hashes):
	if not tx_hashes:
		return []
	result = invoke_json(addr, 'get_transactions', { 'txs_hashes': tx_hashes, 'decode_as_json': True, 'prune': True })
	assert(len(result['txs']) == len(tx_hashes))
	return [json.loads(tx['as_json']) for tx in result['txs']]

def extend_vinvout_map(txin_vs, txout_target_vs, tx):
	for txin_v in tx['vin']:
		assert(len(txin_v) == 1)
		vintype = next(iter(txin_v))
		if vintype not in txin_vs:
			txin_vs[vintype] = 0
		txin_vs[vintype] += 1
	for tx_out in tx['vout']:
		txout_target_v = tx_out['target']
		assert(len(txout_target_v) == 1)
		vouttype = next(iter(txout_target_v))
		if vouttype not in txout_target_vs:
			txout_target_vs[vouttype] = 0
		txout_target_vs[vouttype] += 1		

def main():
	top_height = get_height(my_daemon_address)
	txin_vs = {}
	txout_target_vs = {}
	print("Blockchain height:", top_height)
	
	for current_height in range(top_height):
		if current_height % 1000 == 0:
			print(current_height, '/', top_height)
		if current_height % 10000 == 0:
			print("tx in types: ", txin_vs)
			print("tx out types: ", txout_target_vs)
		miner_tx, block_tx_hashes = get_block_txs_by_height(my_daemon_address, current_height)
		block_txs = get_transactions(my_daemon_address, block_tx_hashes)
		extend_vinvout_map(txin_vs, txout_target_vs, miner_tx)
		for block_tx in block_txs:
			extend_vinvout_map(txin_vs, txout_target_vs, block_tx)
	print("Done scanning!")
	print("tx in types: ", txin_vs)
	print("tx out types: ", txout_target_vs)

if __name__ == '__main__':
	main()

This scans all txs on the entire chain, including miner transactions, and creates a histogram of all all/output types, outputting the results every 10K blocks.

@jeffro256 jeffro256 force-pushed the rm_unused_vin_vout branch from 4f46d5a to 5d3da15 Compare May 29, 2023 23:34
@jeffro256 jeffro256 marked this pull request as draft June 15, 2023 05:17
Structs were added 9 years ago and have yet to be used. I created a variant placeholder called `reserved` which can be used to easily keep
serialization backwards compatible while removing the types from variants.
@jeffro256 jeffro256 marked this pull request as ready for review January 2, 2024 01:46
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

Successfully merging this pull request may close these issues.

2 participants