Last active
March 18, 2020 14:49
-
-
Save m-kus/182c5d6d776c2eb5795915776ea5f593 to your computer and use it in GitHub Desktop.
Extracting raw big map values from lmdb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import lmdb\n", | |
"import itertools\n", | |
"from pytezos import pytezos\n", | |
"from pytezos.encoding import base58_decode, base58_encode" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"env = lmdb.open('/home/mickey/.tezos-node/context')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn = env.begin()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cursor = txn.cursor()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cursor.last()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"list(itertools.islice(cursor.iternext_nodup(), 50))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"for item in itertools.islice(cursor.iternext_nodup(), 1000000):\n", | |
" if not item.startswith(b'contents'):\n", | |
" print(item)\n", | |
" break" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"len(b'B\\x00\\xfaB\\x85\\x0e\\xd7`\\xe5\\xc3\\x86\\xf9\\x84$\\x0e#\\xe0\\xd9\\x81\\x1e\\xc0 \\xb0\\xd9_\\x92\\xbb\\x06\\xe6\\xc6h\\x16')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'commit/' + base58_decode(b'BMMJdpT2d8L6iRK8KGgDkwbyqBTfLdVJ6527sQVnXpXV3npXNSr'))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"key = b'commit/' + base58_decode(b'CoUqY3A2iqYA1dfZtfsFepcCirHz6uFSpnbFw8VgvJeP3svJxwKf')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"key" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data = txn.get(key)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"pytezos.shell.blocks[339819].header()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[0:4]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(data[4:8], 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[8:40]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[40:44]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[44:48]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[48:52]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(data[52:56], 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[56:88] # predecessor" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[88:92]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(data[92:96], 'big') # timestamp" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[96:100]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(data[100:104], 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[104:109]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[109:113]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(data[113:117], 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"data[117:157]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node = txn.get(b'node/' + data[8:40])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'commit/' + data[56:88])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(b'\\x00\\x00\\x03\\x00', 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node[21:]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"int.from_bytes(node[25:29], 'big')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"node[29:61]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'node/' + node[29:61])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'node/' + b'\\x9e\\xb5\\xc6\\x8dn:_r\\xe7M\"\\xaf\\xc0\\xfc\\xb6\\x17\\xe6i\\xaa!\\x19\\x0c\\xab\\xae[\\xcc#\\xed\\xa2,I\\xf2')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def parse_node(key_hash):\n", | |
" # header 9 bytes (7 unknown, 2 flags)\n", | |
" # separator 4 bytes\n", | |
" # length of key\n", | |
" # key\n", | |
" # separator 4 bytes\n", | |
" # length of value\n", | |
" # value\n", | |
" # flag 1 byte\n", | |
" # separator 4 bytes\n", | |
" node = txn.get(b'node/' + key_hash)\n", | |
" \n", | |
" items = {}\n", | |
" ptr = 9\n", | |
" \n", | |
" while ptr < len(node): \n", | |
" ptr += 4\n", | |
"\n", | |
" key_len = int.from_bytes(node[ptr:ptr+4], 'big')\n", | |
" ptr += 4\n", | |
"\n", | |
" key = node[ptr:ptr+key_len].decode()\n", | |
" ptr += key_len\n", | |
"\n", | |
" ptr += 4\n", | |
"\n", | |
" val_len = int.from_bytes(node[ptr:ptr+4], 'big')\n", | |
" ptr += 4\n", | |
"\n", | |
" val = node[ptr:ptr+val_len]\n", | |
" ptr += val_len\n", | |
" \n", | |
" items[key] = val\n", | |
" \n", | |
" if ptr < len(node):\n", | |
" ptr += 1\n", | |
" \n", | |
" return items" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"nod = txn.get(b'node/' + data[8:40])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"nod" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n1 = parse_node(nod)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n1" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n2 = parse_node(n1['data'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n2" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n3 = parse_node(n2['contracts'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n3" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n4 = parse_node(n3['index'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n4" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n5 = parse_node(n4['originated'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"n5" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"base58_decode(b'KT1P3j1VonQytW3b2SzCnGVpjdf3oWajM79E')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"parse_node(n5['9e'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"from pprint import pformat\n", | |
"\n", | |
"\n", | |
"def read_node(txn, key_hash):\n", | |
" ptr = 9 # skip header\n", | |
" node = txn.get(b'node/' + key_hash)\n", | |
" items = {}\n", | |
" \n", | |
" def read_data():\n", | |
" nonlocal ptr\n", | |
" ptr += 4\n", | |
" length = int.from_bytes(node[ptr:ptr + 4], 'big')\n", | |
" ptr += 4\n", | |
" data = node[ptr:ptr + length]\n", | |
" ptr += length\n", | |
" return data\n", | |
" \n", | |
" while ptr < len(node):\n", | |
" key = read_data().decode()\n", | |
" val = read_data()\n", | |
" items[key] = val\n", | |
" if ptr < len(node):\n", | |
" ptr += 1 # some flag\n", | |
" \n", | |
" return items\n", | |
" \n", | |
"\n", | |
"class IrminNode:\n", | |
" \n", | |
" def __init__(self, txn, key_hash):\n", | |
" self.txn = txn\n", | |
" self.items = read_node(txn, key_hash) \n", | |
" \n", | |
" def __repr__(self):\n", | |
" return pformat(self.items)\n", | |
" \n", | |
" def __getitem__(self, item):\n", | |
" if item.startswith('KT'):\n", | |
" key_hash = base58_decode(b'KT1P3j1VonQytW3b2SzCnGVpjdf3oWajM79E').hex()\n", | |
" child = self\n", | |
" for i in range(5):\n", | |
" kh = key_hash[2 * i:2 * i + 2]\n", | |
" child = child[kh]\n", | |
" return child[key_hash[10:]]\n", | |
" else:\n", | |
" return IrminNode(txn, self.items[item])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"root = IrminNode(txn, data[8:40])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"root" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cc = root['data']['contracts']['index']['originated']['KT1P3j1VonQytW3b2SzCnGVpjdf3oWajM79E']" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cc" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"cc['big_map']" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"bmi = cc['big_map']['2f']['17']['7b']['89']['57']['c4bb8bfb1d757b465cc76024b6ae6c002dea5af493e4b3c8406e69']" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"bmi" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'contents/' + bmi.items['data'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"txn.get(b'contents/' + bmi.items['len'])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.7.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment