Public
Edited
Mar 2, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
full_trie_chart
Insert cell
insertionIndex = {
const res = [];
for (const blockHash of r.keys(blocks)) {
const index = getInsertionIndexByBlockHash(blockHash);
res.push({ blockHash, inserted: index.inserted, removed: index.removed });
}
return res;
}
Insert cell
Insert cell
Insert cell
import { chart as full_trie_chart } with {
fullTrie as data,
COLOR_SCHEMA as colorSchema,
height as height,
nodeRadius as nodeRadius,
simulationStrenth as simulationStrength
} from "@whiteand/force-directed-graph"
Insert cell
simulationStrenth = -700
Insert cell
fullTrie = calculateFullTrie(
fullTrieBlocks,
selectedBlockHash,
finalizedBlockHash
)
Insert cell
nodeRadius = () => 20
Insert cell
height = 800
Insert cell
selectedBlockTrie = selectedBlockHash
? getTrieForBlockHash(selectedBlockHash)
: { nodes: [], links: [] }
Insert cell
COLOR_SCHEMA = ({
colors: ["#666", "#0f0", "#f00", "#00f", "yellow"],
DEFAULT: 0,
INSERTED: 1,
DELETED: 2,
FINALIZED: 3,
ALL: 4
})
Insert cell
Insert cell
function getInsertionIndexByBlockHash(blockHash) {
const block = blocks[blockHash];
if (!block) return { inserted: [], removed: [] };
const prev_trie = getTrieForBlockHash(block.prev);
const current_trie = getTrieForBlockHash(blockHash);
const removed = [];
const added = [];
for (const node of prev_trie.nodes) {
if (current_trie.nodes.some((n) => n.id === node.id)) continue;
removed.push(node.id);
}
for (const node of prev_trie.nodes) {
if (current_trie.nodes.some((n) => n.id === node.id)) continue;
added.push(node.id);
}
return { inserted: added, removed };
}
Insert cell
Insert cell
selected_block_ancestors = getAncestorsHashes(selectedBlockHash)
Insert cell
function getAncestorsHashes(bh) {
if (!blocks[bh]) return [];
const block = blocks[bh];
let child = block;

const res = [];
while (child.prev != null) {
res.push(child.prev);
child = child.prev != null ? blocks[child.prev] : null;
}
return res;
}
Insert cell
function getTrieForBlockHash(blockHash) {
const nodes = [];
const links = [];
let nodeHashByNodeId = {};
const accounts = getAccountsOnBlockHash(blockHash);
for (const node of accountsTreeSchema.nodes) {
let hash = node.indices.reduce(
(hash, ind) => hash + ind + (accounts[ind] || "_"),
""
);
nodeHashByNodeId[node.id] = hash;
nodes.push({
id: hash,
blockHash,
nodeId: node.id,
group: COLOR_SCHEMA.DEFAULT,
runtime: 1,
name: hash,
label: "A"
});
}
for (const link of accountsTreeSchema.links) {
links.push({
source: nodeHashByNodeId[link[0]],
target: nodeHashByNodeId[link[1]],
type: ""
});
}

return { nodes, links };
}
Insert cell
blocks_accounts = {
const res = {};
for (const block of r.keys(blocks)) {
const accounts = getAccountsOnBlockHash(block);
res[block] = accounts;
}
return res;
}
Insert cell
Insert cell
Insert cell
selected_block_accounts = getAccountsOnBlockHash(selectedBlockHash)
Insert cell
function getAccountsOnBlockHash(bh) {
if (!bh || !full_blocks[bh]) return initial_accounts;
let block = full_blocks[bh];
let prevAccounts =
block.prev == null ? initial_accounts : getAccountsOnBlockHash(block.prev);
return block.txs.reduce((accs, tx) => applyTx(accs, tx), prevAccounts);
}
Insert cell
Insert cell
Insert cell
function applyTx(accounts, tx) {
const newAccounts = [...accounts];
newAccounts[tx.changes[0]] += tx.changes[1];
if (newAccounts[tx.changes[0]].toString().length != 1)
throw new Error("Keep accounts 0 <= balance < 10");
return newAccounts;
}
Insert cell
Insert cell
Insert cell
Insert cell
r = import("https://cdn.skypack.dev/ramda@0.28")
Insert cell
import { ForceGraph } from "@d3/force-directed-graph"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more