Search
Search

Transaction: CuVQPcZ...V5ua

Status
Succeeded
Transaction Fee
0.00071 
Deposit Value
0 
Gas Used
7 Tgas
Attached Gas
200 Tgas
Created
March 19, 2024 at 8:30:47pm
Hash
CuVQPcZhDpwXsK9ptGvpNVLDtHeyATmmDjLhL6SAV5ua

Actions

Called method: 'register' in contract: dev-q…tform.near
Arguments:
{ "function_name": "bitmap_v1", "code": "\n function bitmapToString(buffer) {\n return buffer.reduce((r, b) => r + b.toString(2).padStart(8, \"0\"), \"\");\n }\n\n context.db.ActionsIndex.select();\n\n // bit packing: converts array of indexes to a bitmap packed into Uint8Array\n // example: [0,1,6] -> \"11000010\" -> [194]\n function indexArrayToBitmap(arr) {\n const lastItem = arr[arr.length - 1];\n return arr.reduce((bytes, bit) => {\n bytes[Math.floor(bit / 8)] |= 1 << (7 - (bit % 8));\n return bytes;\n }, new Uint8Array(Math.floor(lastItem / 8) + 2));\n }\n\n // example: [0,1,6] -> \"11000010\"\n function indexArrayToBitmapString(arr) {\n return bitmapToString(indexArrayToBitmap(arr));\n }\n\n // example: \"0101\" -> [1,3]\n function bitmapStringToIndexArray(strBits) {\n const result = [];\n for (let i = 0; i < strBits.length; i++) {\n if (strBits[i] === \"1\") {\n result.push(i);\n }\n }\n return result;\n }\n\n function strBitmapToBitmap(strBits) {\n const bytes = new Uint8Array(Math.ceil(strBits.length / 8));\n for (let bit = 0; bit < strBits.length; bit++) {\n if (strBits[bit] === \"1\") {\n bytes[Math.floor(bit / 8)] |= 1 << (7 - (bit % 8));\n }\n }\n return bytes;\n }\n\n // computes Elias gamma coding for number x. Returns a string.\n // Examples: https://en.wikipedia.org/wiki/Elias_gamma_coding\n function eliasGamma(x) {\n if (x === 0) return \"\";\n if (x === 1) return \"1\";\n const N = Math.floor(Math.log2(x));\n const encN = \"1\".padStart(N + 1, \"0\");\n const encRemainer = (x - 2 ** N).toString(2).padStart(N, \"0\");\n //console.log(`x=${x}: N=${N}, r=${(2**N)}`)\n return encN + encRemainer;\n }\n\n // returns first number x and corresponding coded string length of the first occurrence of\n // Elias gamma coding. E.g. for \"0101\" returns {x:2,len:3}\n function decodeEliasGammaFirstEntry(strBits) {\n if (strBits === \"\") return { x: 0, len: 0 };\n const N = strBits.indexOf(\"1\");\n if (N < 0) {\n return { x: 0, len: strBits.length };\n }\n const remainder = strBits.slice(N + 1, 2 * N + 1);\n return { x: 2 ** N + (parseInt(remainder, 2) || 0), len: 2 * N + 1 };\n }\n\n // stores first char (0 or 1) and then repeats alternating repeating sequences using Elias gamma coding\n // pads the resulting string at the end with '0's for length to be divisible by 8\n function compressBitmapString(strBit) {\n let target = strBit[0];\n let result = target;\n let targetLen = 0;\n for (let i = 0; i < strBit.length; i++) {\n if (strBit[i] === target) {\n targetLen++;\n } else {\n result += eliasGamma(targetLen);\n target = target === \"0\" ? \"1\" : \"0\";\n targetLen = 1;\n }\n }\n result += eliasGamma(targetLen);\n return result.padEnd(Math.ceil(result.length / 8) * 8, \"0\");\n }\n\n function decompressBitmapString(compressedStrBit) {\n let target = compressedStrBit[0];\n let result = \"\";\n let remainder = compressedStrBit.slice(1);\n while (remainder.length) {\n const { x, len } = decodeEliasGammaFirstEntry(remainder);\n result += target.repeat(x);\n target = target === \"0\" ? \"1\" : \"0\";\n remainder = remainder.slice(len);\n if (len === 0) break; // we won't find any Elias gamma here, exiting\n }\n return result;\n }\n\n function decompressBase64(compressedBase64) {\n if (!compressedBase64 || compressedBase64 === \"\") {\n return new Uint8Array(0);\n }\n const bitmap = bitmapToString(Buffer.from(compressedBase64, \"base64\"));\n return decompressBitmapString(bitmap);\n }\n\n function indexArrayFromCompressedBase64(compressedBase64) {\n const decompressedBase64 = decompressBase64(compressedBase64);\n return bitmapStringToIndexArray(decompressedBase64);\n }\n\n function addIndexCompressed(compressedBase64, index) {\n const decompressedBase64 = decompressBase64(compressedBase64);\n const strBits = bitmapToString(\n indexArrayToBitmap([\n ...bitmapStringToIndexArray(decompressedBase64),\n index,\n ])\n );\n const compressed = compressBitmapString(strBits);\n return Buffer.from(strBitmapToBitmap(compressed)).toString(\"base64\");\n }\n const blockDate = new Date(\n new Date(block.streamerMessage.block.header.timestamp / 1000000)\n .toISOString()\n .substring(0, 10)\n );\n const actionsByReceiver = block.actions().reduce((groups, action) => {\n (groups[action.receiverId] ||= []).push(action);\n return groups;\n }, {});\n const allReceivers = Object.keys(actionsByReceiver);\n console.log(`There are ${allReceivers.length} receivers in this block.`);\n const currIndexes = await context.db.ActionsIndex.select(\n allReceivers.map((receiverId) => ({\n block_date: blockDate,\n receiver_id: receiverId,\n }))\n );\n\n // await Promise.all(\n // allReceivers.map(async (receiverId) => {\n // const currentIndex = await context.db.ActionsIndex.select(\n // {\n // block_date: blockDate,\n // receiver_id: receiverId,\n // },\n // 1\n // );\n // return {\n // receiverId,\n // currentIndex: currentIndex ? currentIndex[0] : null,\n // };\n // })\n // );\n const upserts = allReceivers.map((receiverId) => {\n const currentIndex =\n currIndexes.find((i) => i.receiver_id === receiverId) ?? \"\";\n const blockDiff =\n block.blockHeight - (currentIndex?.first_block_height ?? 0);\n const newBitmap = addIndexCompressed(currentIndex?.bitmap ?? \"\", blockDiff);\n return {\n first_block_height: block.blockHeight,\n block_date: blockDate,\n receiver_id: receiverId,\n bitmap: newBitmap,\n };\n });\n await context.db.ActionsIndex.upsert(\n upserts,\n [\"block_date\", \"receiver_id\"],\n [\"bitmap\"]\n );\n // await Promise.all(\n // currIndexes.map(async ({ receiverId, currentIndex }) => {\n // const blockDiff =\n // block.blockHeight - (currentIndex?.first_block_height ?? 0);\n // const newBitmap = addIndexCompressed(currentIndex?.bitmap || \"\", blockDiff);\n // return context.db.ActionsIndex.upsert({\n // first_block_height: block.blockHeight,\n // block_date: blockDate,\n // receiver_id: receiverId,\n // bitmap: newBitmap,\n // }, ['block_date', 'receiver_id'], ['bitmap']);\n // // if (currentIndex) {\n // // const newBitmap = addIndexCompressed(currentIndex.bitmap, blockDiff);\n // // return context.db.ActionsIndex.update(\n // // { block_date: new Date(blockDate), receiver_id: receiverId },\n // // { block_date: blockDate, receiver_id: receiverId, bitmap: newBitmap }\n // // );\n // // } else {\n // // return context.db.ActionsIndex.insert({\n // // first_block_height: block.blockHeight,\n // // block_date: blockDate,\n // // receiver_id: receiverId,\n // // bitmap: addIndexCompressed(\"\", [0]),\n // // });\n // // }\n // })\n // );\n", "schema": "CREATE TABLE\n \"actions_index\" (\n \"block_date\" DATE NOT NULL,\n \"receiver_id\" TEXT NOT NULL,\n \"first_block_height\" NUMERIC(20) NOT NULL,\n \"bitmap\" TEXT NOT NULL,\n PRIMARY KEY (\"block_date\", \"receiver_id\")\n )\n", "start_block": "CONTINUE", "rule": { "kind": "ACTION_ANY", "affected_account_id": "*", "status": "SUCCESS" } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
2 Tgas
Tokens Burned:
0.00024 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
4 Tgas
Tokens Burned:
0.00047 
Called method: 'register' in contract: dev-q…tform.near
Arguments:
{ "function_name": "bitmap_v1", "code": "\n function bitmapToString(buffer) {\n return buffer.reduce((r, b) => r + b.toString(2).padStart(8, \"0\"), \"\");\n }\n\n context.db.ActionsIndex.select();\n\n // bit packing: converts array of indexes to a bitmap packed into Uint8Array\n // example: [0,1,6] -> \"11000010\" -> [194]\n function indexArrayToBitmap(arr) {\n const lastItem = arr[arr.length - 1];\n return arr.reduce((bytes, bit) => {\n bytes[Math.floor(bit / 8)] |= 1 << (7 - (bit % 8));\n return bytes;\n }, new Uint8Array(Math.floor(lastItem / 8) + 2));\n }\n\n // example: [0,1,6] -> \"11000010\"\n function indexArrayToBitmapString(arr) {\n return bitmapToString(indexArrayToBitmap(arr));\n }\n\n // example: \"0101\" -> [1,3]\n function bitmapStringToIndexArray(strBits) {\n const result = [];\n for (let i = 0; i < strBits.length; i++) {\n if (strBits[i] === \"1\") {\n result.push(i);\n }\n }\n return result;\n }\n\n function strBitmapToBitmap(strBits) {\n const bytes = new Uint8Array(Math.ceil(strBits.length / 8));\n for (let bit = 0; bit < strBits.length; bit++) {\n if (strBits[bit] === \"1\") {\n bytes[Math.floor(bit / 8)] |= 1 << (7 - (bit % 8));\n }\n }\n return bytes;\n }\n\n // computes Elias gamma coding for number x. Returns a string.\n // Examples: https://en.wikipedia.org/wiki/Elias_gamma_coding\n function eliasGamma(x) {\n if (x === 0) return \"\";\n if (x === 1) return \"1\";\n const N = Math.floor(Math.log2(x));\n const encN = \"1\".padStart(N + 1, \"0\");\n const encRemainer = (x - 2 ** N).toString(2).padStart(N, \"0\");\n //console.log(`x=${x}: N=${N}, r=${(2**N)}`)\n return encN + encRemainer;\n }\n\n // returns first number x and corresponding coded string length of the first occurrence of\n // Elias gamma coding. E.g. for \"0101\" returns {x:2,len:3}\n function decodeEliasGammaFirstEntry(strBits) {\n if (strBits === \"\") return { x: 0, len: 0 };\n const N = strBits.indexOf(\"1\");\n if (N < 0) {\n return { x: 0, len: strBits.length };\n }\n const remainder = strBits.slice(N + 1, 2 * N + 1);\n return { x: 2 ** N + (parseInt(remainder, 2) || 0), len: 2 * N + 1 };\n }\n\n // stores first char (0 or 1) and then repeats alternating repeating sequences using Elias gamma coding\n // pads the resulting string at the end with '0's for length to be divisible by 8\n function compressBitmapString(strBit) {\n let target = strBit[0];\n let result = target;\n let targetLen = 0;\n for (let i = 0; i < strBit.length; i++) {\n if (strBit[i] === target) {\n targetLen++;\n } else {\n result += eliasGamma(targetLen);\n target = target === \"0\" ? \"1\" : \"0\";\n targetLen = 1;\n }\n }\n result += eliasGamma(targetLen);\n return result.padEnd(Math.ceil(result.length / 8) * 8, \"0\");\n }\n\n function decompressBitmapString(compressedStrBit) {\n let target = compressedStrBit[0];\n let result = \"\";\n let remainder = compressedStrBit.slice(1);\n while (remainder.length) {\n const { x, len } = decodeEliasGammaFirstEntry(remainder);\n result += target.repeat(x);\n target = target === \"0\" ? \"1\" : \"0\";\n remainder = remainder.slice(len);\n if (len === 0) break; // we won't find any Elias gamma here, exiting\n }\n return result;\n }\n\n function decompressBase64(compressedBase64) {\n if (!compressedBase64 || compressedBase64 === \"\") {\n return new Uint8Array(0);\n }\n const bitmap = bitmapToString(Buffer.from(compressedBase64, \"base64\"));\n return decompressBitmapString(bitmap);\n }\n\n function indexArrayFromCompressedBase64(compressedBase64) {\n const decompressedBase64 = decompressBase64(compressedBase64);\n return bitmapStringToIndexArray(decompressedBase64);\n }\n\n function addIndexCompressed(compressedBase64, index) {\n const decompressedBase64 = decompressBase64(compressedBase64);\n const strBits = bitmapToString(\n indexArrayToBitmap([\n ...bitmapStringToIndexArray(decompressedBase64),\n index,\n ])\n );\n const compressed = compressBitmapString(strBits);\n return Buffer.from(strBitmapToBitmap(compressed)).toString(\"base64\");\n }\n const blockDate = new Date(\n new Date(block.streamerMessage.block.header.timestamp / 1000000)\n .toISOString()\n .substring(0, 10)\n );\n const actionsByReceiver = block.actions().reduce((groups, action) => {\n (groups[action.receiverId] ||= []).push(action);\n return groups;\n }, {});\n const allReceivers = Object.keys(actionsByReceiver);\n console.log(`There are ${allReceivers.length} receivers in this block.`);\n const currIndexes = await context.db.ActionsIndex.select(\n allReceivers.map((receiverId) => ({\n block_date: blockDate,\n receiver_id: receiverId,\n }))\n );\n\n // await Promise.all(\n // allReceivers.map(async (receiverId) => {\n // const currentIndex = await context.db.ActionsIndex.select(\n // {\n // block_date: blockDate,\n // receiver_id: receiverId,\n // },\n // 1\n // );\n // return {\n // receiverId,\n // currentIndex: currentIndex ? currentIndex[0] : null,\n // };\n // })\n // );\n const upserts = allReceivers.map((receiverId) => {\n const currentIndex =\n currIndexes.find((i) => i.receiver_id === receiverId) ?? \"\";\n const blockDiff =\n block.blockHeight - (currentIndex?.first_block_height ?? 0);\n const newBitmap = addIndexCompressed(currentIndex?.bitmap ?? \"\", blockDiff);\n return {\n first_block_height: block.blockHeight,\n block_date: blockDate,\n receiver_id: receiverId,\n bitmap: newBitmap,\n };\n });\n await context.db.ActionsIndex.upsert(\n upserts,\n [\"block_date\", \"receiver_id\"],\n [\"bitmap\"]\n );\n // await Promise.all(\n // currIndexes.map(async ({ receiverId, currentIndex }) => {\n // const blockDiff =\n // block.blockHeight - (currentIndex?.first_block_height ?? 0);\n // const newBitmap = addIndexCompressed(currentIndex?.bitmap || \"\", blockDiff);\n // return context.db.ActionsIndex.upsert({\n // first_block_height: block.blockHeight,\n // block_date: blockDate,\n // receiver_id: receiverId,\n // bitmap: newBitmap,\n // }, ['block_date', 'receiver_id'], ['bitmap']);\n // // if (currentIndex) {\n // // const newBitmap = addIndexCompressed(currentIndex.bitmap, blockDiff);\n // // return context.db.ActionsIndex.update(\n // // { block_date: new Date(blockDate), receiver_id: receiverId },\n // // { block_date: blockDate, receiver_id: receiverId, bitmap: newBitmap }\n // // );\n // // } else {\n // // return context.db.ActionsIndex.insert({\n // // first_block_height: block.blockHeight,\n // // block_date: blockDate,\n // // receiver_id: receiverId,\n // // bitmap: addIndexCompressed(\"\", [0]),\n // // });\n // // }\n // })\n // );\n", "schema": "CREATE TABLE\n \"actions_index\" (\n \"block_date\" DATE NOT NULL,\n \"receiver_id\" TEXT NOT NULL,\n \"first_block_height\" NUMERIC(20) NOT NULL,\n \"bitmap\" TEXT NOT NULL,\n PRIMARY KEY (\"block_date\", \"receiver_id\")\n )\n", "start_block": "CONTINUE", "rule": { "kind": "ACTION_ANY", "affected_account_id": "*", "status": "SUCCESS" } }
Empty result
Registering function bitmap_v1 for account nearpavel.near
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.06959  to nearpavel.near
Empty result
No logs