Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

helpers_test.gno

3.19 Kb · 109 lines
  1package game32
  2
  3import (
  4	"encoding/hex"
  5	"strconv"
  6	"strings"
  7	"testing"
  8	"time"
  9
 10	"gno.land/p/nt/testutils/v0"
 11)
 12
 13// Public key of the deterministic TEST-ONLY signer (scripts/game29-test-vectors.mjs,
 14// seed = sha256("gnomoji-game29-test-signer")). Not used anywhere but tests.
 15const testSignerPub = "faec207b91ab599b1e51652602843fcb52275922e8dab39bed3a21034cece6f1"
 16
 17func setup() address {
 18	if admin == address("") {
 19		admin = testutils.TestAddress("deployer")
 20		operator = admin
 21	}
 22	if len(claimSignerPubKey) != 32 {
 23		claimSignerPubKey, _ = hex.DecodeString(testSignerPub)
 24	}
 25	return admin
 26}
 27
 28func ta(name string) address { return testutils.TestAddress(name) }
 29
 30func bal(a address, coin string) uint64 { return balOf(a.String(), coin) }
 31
 32// voucher returns (nonce, expiry, sigHex) for a server voucher. Signatures
 33// come from voucherVectors (generated). A missing vector is logged so the
 34// generator can sign it, and an invalid signature is returned.
 35func voucher(t *testing.T, kind string, player address, payload string) (int64, int64, string) {
 36	nonce := LastNonce(player.String()) + 1
 37	expiry := time.Now().Unix() + 600
 38	return nonce, expiry, sigFor(t, kind, player, nonce, expiry, payload)
 39}
 40
 41// safeCompactAchPayload wraps compactAchPayload with a recover so that
 42// cross-kind tests (e.g. signing an "ach" voucher over a claim payload) don't
 43// crash the test helper. An unparseable payload falls back to the raw string —
 44// the resulting signature will be wrong and the realm will reject it, which is
 45// exactly what those rejection tests expect.
 46func safeCompactAchPayload(payload string) (result string) {
 47	defer func() {
 48		if r := recover(); r != nil {
 49			result = payload // fall back to raw payload on parse error
 50		}
 51	}()
 52	return compactAchPayload(payload)
 53}
 54
 55func sigFor(t *testing.T, kind string, player address, nonce, expiry int64, payload string) string {
 56	// Compact the payload to match the v2 VoucherMessage format.
 57	compact := payload
 58	if kind == "claim" {
 59		compact = compactClaimPayload(payload)
 60	} else if kind == "ach" {
 61		compact = safeCompactAchPayload(payload)
 62	}
 63	msg := VoucherMessage(kind, player.String(), nonce, expiry, compact)
 64	if s, ok := voucherVectors[msg]; ok {
 65		return s
 66	}
 67	// Regenerate with: node scripts/game29-test-vectors.mjs
 68	panic("MISSING_VOUCHER " + hex.EncodeToString([]byte(msg)) + " END")
 69}
 70
 71func give(a address, coin string, amt uint64) { creditBal(a.String(), coin, amt) }
 72
 73func allowanceFor(addr address, r int) uint64 {
 74	js := ClaimAllowance(addr.String())
 75	key := `"r` + strconv.Itoa(r) + `":`
 76	i := strings.Index(js, key) + len(key)
 77	j := i
 78	for j < len(js) && js[j] >= '0' && js[j] <= '9' {
 79		j++
 80	}
 81	v, _ := strconv.ParseUint(js[i:j], 10, 64)
 82	return v
 83}
 84
 85func mustAbort(t *testing.T, what string, abort any, wantSub string) {
 86	if abort == nil {
 87		t.Errorf("%s: expected abort, got success", what)
 88		return
 89	}
 90	msg := ""
 91	switch v := abort.(type) {
 92	case string:
 93		msg = v
 94	case error:
 95		msg = v.Error()
 96	default:
 97		msg = "?"
 98	}
 99	if wantSub != "" && !strings.Contains(msg, wantSub) {
100		t.Errorf("%s: aborted with %q, want it to contain %q", what, msg, wantSub)
101	}
102}
103
104func h(choice, salt string) string { return moveHash(choice, salt) }
105
106func h0(s string) string {
107	x := sha256Sum(s)
108	return x
109}