Search Apps Documentation Source Content File Folder Download Copy Actions Download

verifier.gno

3.01 Kb · 106 lines
  1package chunk
  2
  3// This file manages chunk data for integrity verification.
  4// Verifier storage: BTree(worldID -> *BTree(chunkKey -> verifier)).
  5
  6import (
  7	"gno.land/p/akkadia/v0/accesscontrol"
  8	"gno.land/r/akkadia/v0/admin"
  9)
 10
 11// ==================== Chunk Verifier ====================
 12
 13// SetChunkVerifier stores verifier for a specific chunk key of a world.
 14func SetChunkVerifier(cur realm, worldID uint32, chunkKey string, verifier string) {
 15	assertNotFrozen()
 16	accesscontrol.AssertIsAdminOrOperator(0, cur, admin.IsAdmin, admin.IsOperator)
 17
 18	canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 19	verifierStore.Set(worldID, canonicalChunkKey, verifier)
 20}
 21
 22// SetChunkVerifiers sets multiple chunk verifiers at once using direct string traversal.
 23// chunkKeys and verifiers are comma-separated strings with matching item counts.
 24// Example: chunkKeys="100000002:0_0,100000002:0_1", verifiers="a1b2c3d4,e5f6a7b8"
 25func SetChunkVerifiers(cur realm, worldID uint32, chunkKeys string, verifiers string) {
 26	assertNotFrozen()
 27	accesscontrol.AssertIsAdminOrOperator(0, cur, admin.IsAdmin, admin.IsOperator)
 28
 29	if chunkKeys == "" {
 30		panic("chunkKeys must not be empty")
 31	}
 32	if verifiers == "" {
 33		panic("verifiers must not be empty")
 34	}
 35
 36	keyStart, valStart := 0, 0
 37	keyIdx, valIdx := 0, 0
 38	count := 0
 39
 40	for {
 41		for keyIdx < len(chunkKeys) && chunkKeys[keyIdx] != ',' {
 42			keyIdx++
 43		}
 44		for valIdx < len(verifiers) && verifiers[valIdx] != ',' {
 45			valIdx++
 46		}
 47
 48		key := chunkKeys[keyStart:keyIdx]
 49		val := verifiers[valStart:valIdx]
 50
 51		if val == "" {
 52			panic("empty verifier not allowed")
 53		}
 54
 55		// Keep this loop streaming. Building temporary []string values for every
 56		// key/verifier pair increases gas sharply on large batch calls.
 57		count++
 58		assertBatchLimit("chunkKeys", count)
 59		canonicalChunkKey := normalizeChunkKey(worldID, key)
 60		verifierStore.Set(worldID, canonicalChunkKey, val)
 61
 62		keyEnd := keyIdx >= len(chunkKeys)
 63		valEnd := valIdx >= len(verifiers)
 64
 65		if keyEnd != valEnd {
 66			panic("chunkKeys and verifiers count mismatch")
 67		}
 68		if keyEnd {
 69			break
 70		}
 71
 72		keyIdx++
 73		valIdx++
 74		keyStart = keyIdx
 75		valStart = valIdx
 76	}
 77}
 78
 79// GetChunkVerifier retrieves verifier for a specific chunk key of a world.
 80func GetChunkVerifier(worldID uint32, chunkKey string) string {
 81	assertMigrationStateAvailable()
 82	canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 83	verifier, found := verifierStore.Get(worldID, canonicalChunkKey)
 84	if !found {
 85		return ""
 86	}
 87	return verifier
 88}
 89
 90// ListChunkVerifiers retrieves verifiers for multiple chunk keys of a world.
 91func ListChunkVerifiers(worldID uint32, chunkKeys ...string) []map[string]string {
 92	assertMigrationStateAvailable()
 93	assertListLimit("chunkKeys", len(chunkKeys))
 94	result := []map[string]string{}
 95	for _, chunkKey := range chunkKeys {
 96		canonicalChunkKey := normalizeChunkKey(worldID, chunkKey)
 97		verifier, found := verifierStore.Get(worldID, canonicalChunkKey)
 98		if found {
 99			result = append(result, map[string]string{
100				"chunkKey": canonicalChunkKey,
101				"verifier": verifier,
102			})
103		}
104	}
105	return result
106}