灵符lingfu
L

ling-wallet

↓ 0 downloads

Ling Wallet: a post-quantum privacy-coin wallet, full node and HyperTorus miner for LNG

Windows · x86-64 ✕Linux · x86-64 ✕LingOS · x86-64LingOS · Pi 5 ARM64 ✕
Keywords wallet, cryptocurrency, lng, node, miner, ling
lingfu install ling-wallet
LicenseMIT
Authorsling-lin
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (116)

ling/ui/torus.ling
# torus.ling — HyperTorus visualizer. The miner's 4-torus walk samples are
# placed on a Clifford torus in S3, rotated in the xw and yz planes, projected
# 4D -> 3D -> 2D and drawn as glowing points with a trail, over a faint torus
# grid and the TETRA tetrahedron. Several visualizers can coexist by name.

bind TZ_CAP = 640
bind TZ_U32 = 4294967296
bind TZ_R = 0.7071067811865476

fn twist_color(twist, w) {
    return roygbiv(((twist % 4) * 2 + sel(w >= 2147483648, 1, 0)) % 7)
}

fn tz_clear(n) {
    st_lclear(n + "_x")
    st_lclear(n + "_y")
    st_lclear(n + "_z")
    st_lclear(n + "_w")
    st_lclear(n + "_c")
    st_lclear(n + "_b")
    st_set(n + "_count", 0)
    st_set(n + "_head", 0)
    st_set(n + "_last", 0 - 1)
    st_set(n + "_hp", [])
}

# Feed a trace (list of [x, y, z, w, twist]); keeps every 6th step and the head.
fn tz_feed(n, trace, t) {
    bind tl = len(trace)
    if tl == 0 { return () }
    bind hp = list_get(trace, tl - 1)
    if list_get(hp, 0) == st_get(n + "_last", 0 - 1) { return () }
    st_set(n + "_last", list_get(hp, 0))
    st_set(n + "_hp", hp)
    bind i = 0
    while i < tl {
        if i % 6 == 0 || i == tl - 1 {
            bind p = list_get(trace, i)
            bind a1 = list_get(p, 0) / TZ_U32 * 6.283185307179586
            bind a2 = list_get(p, 1) / TZ_U32 * 6.283185307179586
            bind slot = st_get(n + "_head", 0)
            st_lset(n + "_x", slot, cos(a1) * TZ_R)
            st_lset(n + "_y", slot, sin(a1) * TZ_R)
            st_lset(n + "_z", slot, cos(a2) * TZ_R)
            st_lset(n + "_w", slot, sin(a2) * TZ_R)
            st_lset(n + "_c", slot, twist_color(list_get(p, 4), list_get(p, 3)))
            st_lset(n + "_b", slot, t)
            st_set(n + "_head", (slot + 1) % TZ_CAP)
            st_set(n + "_count", min(TZ_CAP, st_get(n + "_count", 0) + 1))
        }
        bind i = i + 1
    }
}

fn tz_head(n) { return st_get(n + "_hp", []) }

# The per-frame view coefficients.
fn tz_view(t, cx, cy, scale) {
    bind a = t * 0.23
    bind b = t * 0.141
    bind yaw = sin(t * 0.05) * 0.6
    return [sin(a), cos(a), sin(b), cos(b), sin(yaw), cos(yaw), sin(0.42), cos(0.42), cx, cy, scale]
}

# Project a point; returns [sx, sy, depth] with depth 1 = near.
fn tz_project(v, x, y, z, w) {
    bind sa = list_get(v, 0)
    bind ca = list_get(v, 1)
    bind sb = list_get(v, 2)
    bind cb = list_get(v, 3)
    bind x1 = x * ca - w * sa
    bind w1 = x * sa + w * ca
    bind y1 = y * cb - z * sb
    bind z1 = y * sb + z * cb
    bind k4 = 1 / (1.75 - w1)
    bind x2 = x1 * k4
    bind y2 = y1 * k4
    bind z2 = z1 * k4
    bind sy = list_get(v, 4)
    bind cy = list_get(v, 5)
    bind x3 = x2 * cy + z2 * sy
    bind z3 = z2 * cy - x2 * sy
    bind stl = list_get(v, 6)
    bind ct = list_get(v, 7)
    bind y4 = y2 * ct - z3 * stl
    bind z4 = y2 * stl + z3 * ct
    bind k3 = 2.6 / (2.6 + z4) * list_get(v, 10)
    return [list_get(v, 8) + x3 * k3, list_get(v, 9) - y4 * k3, clampf((1 - z4) * 0.5, 0, 1)]
}

fn tz_draw(n, x, y, w, h, t, active, detail) {
    clip_push(x, y, w, h)
    bind cx = x + w / 2
    bind cy = y + h / 2 + 6
    bind mn = min(w, h)
    bind v = tz_view(t, cx, cy, mn * 0.42)
    # tz_project inlined for the grid and the walk samples (a call and a list
    # per point was most of the frame); these are its coefficients.
    bind sa = list_get(v, 0)
    bind ca = list_get(v, 1)
    bind sb = list_get(v, 2)
    bind cb = list_get(v, 3)
    bind ys = list_get(v, 4)
    bind yc = list_get(v, 5)
    bind ts = list_get(v, 6)
    bind tc = list_get(v, 7)
    bind sk = 2.6 * list_get(v, 10)

    bind rr = mn * 0.46
    px_ring(cx, cy, rr, C_LINE_FAINT, 1)
    px_ring(cx, cy, rr * 0.5, C_LINE_FAINT, 0.7)
    hline(x + 8, floor(cy), w - 16, C_LINE_FAINT, 0.8)
    vline(floor(cx), y + 8, h - 16, C_LINE_FAINT, 0.8)
    # 72 ticks; (ux, uy) steps round the circle by a fixed rotation
    bind dc = cos(6.283185307179586 / 72)
    bind ds = sin(6.283185307179586 / 72)
    bind ux = 1
    bind uy = 0
    bind i = 0
    while i < 72 {
        bind l = 3
        if i % 6 == 0 { bind l = 8 }
        px_line(cx + ux * rr, cy + uy * rr, cx + ux * (rr - l), cy + uy * (rr - l), C_LINE_SOFT, 0.8)
        bind nx = ux * dc - uy * ds
        bind uy = ux * ds + uy * dc
        bind ux = nx
        bind i = i + 1
    }

    # torus grid: loops of constant theta1 and theta2
    bind loops = sel(detail, 12, 8)
    bind steps = sel(detail, 36, 24)
    bind dc = cos(6.283185307179586 / steps)
    bind ds = sin(6.283185307179586 / steps)
    bind k = 0
    while k < 2 {
        bind gcol = sel(k == 0, C_INDIGO, C_BLUE)
        bind li = 0
        while li < loops {
            bind fixed = li / loops * 6.283185307179586
            bind fc = cos(fixed) * TZ_R
            bind fs = sin(fixed) * TZ_R
            bind vc = TZ_R
            bind vs = 0
            bind px = 0
            bind py = 0
            bind pd = 0
            bind s = 0
            while s <= steps {
                bind gx = fc
                bind gy = fs
                bind gz = vc
                bind gw = vs
                if k > 0 {
                    bind gx = vc
                    bind gy = vs
                    bind gz = fc
                    bind gw = fs
                }
                bind k4 = 1 / (1.75 - gx * sa - gw * ca)
                bind x1 = (gx * ca - gw * sa) * k4
                bind y1 = (gy * cb - gz * sb) * k4
                bind z1 = (gy * sb + gz * cb) * k4
                bind z3 = z1 * yc - x1 * ys
                bind z4 = y1 * ts + z3 * tc
                bind k3 = sk / (2.6 + z4)
                bind qx = cx + (x1 * yc + z1 * ys) * k3
                bind qy = cy - (y1 * tc - z3 * ts) * k3
                bind d = (1 - z4) * 0.5
                if d < 0 { bind d = 0 }
                if d > 1 { bind d = 1 }
                if s > 0 { px_line(px, py, qx, qy, gcol, 0.06 + 0.08 * (pd + d)) }
                bind px = qx
                bind py = qy
                bind pd = d
                bind nv = vc * dc - vs * ds
                bind vs = vc * ds + vs * dc
                bind vc = nv
                bind s = s + 1
            }
            bind li = li + 1
        }
        bind k = k + 1
    }

    # tetrahedron
    bind tetra = [[1, 1, 1, 0 - 1], [1, 0 - 1, 0 - 1, 1], [0 - 1, 1, 0 - 1, 1], [0 - 1, 0 - 1, 1, 1]]
    bind tv = []
    bind j = 0
    while j < 4 {
        bind tp = list_get(tetra, j)
        bind tv = list_push(tv, tz_project(v, list_get(tp, 0) * 0.5, list_get(tp, 1) * 0.5, list_get(tp, 2) * 0.5, list_get(tp, 3) * 0.5))
        bind j = j + 1
    }
    bind ia = 0
    while ia < 4 {
        bind ib = ia + 1
        while ib < 4 {
            bind pa = list_get(tv, ia)
            bind pb = list_get(tv, ib)
            bind ax = list_get(pa, 0)
            bind ay = list_get(pa, 1)
            bind dx = (list_get(pb, 0) - ax) / 28
            bind dy = (list_get(pb, 1) - ay) / 28
            bind dd = 0
            while dd < 28 {
                px_line(ax + dx * dd, ay + dy * dd, ax + dx * (dd + 1), ay + dy * (dd + 1), C_VIOLET, 0.35)
                bind dd = dd + 2
            }
            bind ib = ib + 1
        }
        bind ia = ia + 1
    }
    bind hp = tz_head(n)
    bind hv = 0 - 1
    if len(hp) > 3 { bind hv = floor(list_get(hp, 3) / 1073741824) }
    bind vi = 0
    while vi < 4 {
        bind p = list_get(tv, vi)
        bind hi = hv == vi && active
        bind sz = sel(hi, 6, 4)
        bind vc2 = sel(hi, lift(C_VIOLET, 0.4), C_VIOLET)
        bind qx = list_get(p, 0)
        bind qy = list_get(p, 1)
        line(qx - sz, qy, qx, qy - sz, vc2, 0.9)
        line(qx, qy - sz, qx + sz, qy, vc2, 0.9)
        line(qx + sz, qy, qx, qy + sz, vc2, 0.9)
        line(qx, qy + sz, qx - sz, qy, vc2, 0.9)
        t_text(F_MONO, 16, qx + 9, qy + 4, "V" + num_str(vi), shade(vc2, 0.2))
        bind vi = vi + 1
    }

    # walk samples, oldest first, then a trail through the newest
    bind cnt = st_get(n + "_count", 0)
    bind head = st_get(n + "_head", 0)
    bind start = (head - cnt + TZ_CAP) % TZ_CAP
    bind life = 2.6
    bind tail_n = 40
    bind lx = 0
    bind ly = 0
    bind lc = 0
    # the sample lists fetched once (a shared reference, not a copy): one store call each, not one per sample
    bind lxs = st_get(n + "_x", [])
    bind lys = st_get(n + "_y", [])
    bind lzs = st_get(n + "_z", [])
    bind lws = st_get(n + "_w", [])
    bind lcs = st_get(n + "_c", [])
    bind lbs = st_get(n + "_b", [])
    bind m = 0
    while m < cnt {
        bind slot = (start + m) % TZ_CAP
        bind gx = list_get(lxs, slot)
        bind gw = list_get(lws, slot)
        bind gy = list_get(lys, slot)
        bind gz = list_get(lzs, slot)
        bind k4 = 1 / (1.75 - gx * sa - gw * ca)
        bind x1 = (gx * ca - gw * sa) * k4
        bind y1 = (gy * cb - gz * sb) * k4
        bind z1 = (gy * sb + gz * cb) * k4
        bind z3 = z1 * yc - x1 * ys
        bind z4 = y1 * ts + z3 * tc
        bind k3 = sk / (2.6 + z4)
        bind qx = cx + (x1 * yc + z1 * ys) * k3
        bind qy = cy - (y1 * tc - z3 * ts) * k3
        bind d = (1 - z4) * 0.5
        if d < 0 { bind d = 0 }
        if d > 1 { bind d = 1 }
        bind col = list_get(lcs, slot)
        bind fade = 1 - (t - list_get(lbs, slot)) / life
        if fade < 0.12 { bind fade = 0.12 }
        if fade > 1 { bind fade = 1 }
        bind al = fade * (0.25 + 0.75 * d)
        px_disc(qx, qy, 1.6 + 1.4 * d, col, 0.45 * al)
        px_rect(floor(qx), floor(qy), 1, 1, C_TEXT_STRONG, 0.4 * al)
        if m > cnt - tail_n && m > 0 {
            bind tk = (m - (cnt - tail_n)) / tail_n
            px_line(lx, ly, qx, qy, col, 0.05 + 0.3 * tk * tk)
        }
        bind lx = qx
        bind ly = qy
        bind lc = col
        bind m = m + 1
    }
    if cnt > 0 && active {
        bind pulse = 0.6 + 0.4 * sin(t * 6)
        glow(lx, ly, 9, lc, 0.6 * pulse)
        ring(lx, ly, 7, C_TEXT_STRONG, 0.8)
        if hv >= 0 {
            bind pv = list_get(tv, hv)
            line(lx, ly, list_get(pv, 0), list_get(pv, 1), lift(C_VIOLET, 0.3), 0.45)
        }
    }
    clip_pop()
}

← Back to index