go-lns/pkg/covenant/rules_extra.go
Virgil 77e3c0fe17 feat(covenant): add Get alias mirrors
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-04 05:42:58 +00:00

143 lines
3.1 KiB
Go

// SPDX-License-Identifier: EUPL-1.2
package covenant
import (
"crypto/rand"
"math/big"
core "dappco.re/go/core"
"dappco.re/go/lns/pkg/primitives"
)
const grindAttempts = 500000
var grindNameChars = []byte("abcdefghijklmnopqrstuvwxyz")
func randomName(size int) (string, error) {
if size <= 0 || size > MaxNameSize {
return "", core.E("covenant.GrindName", "invalid size", nil)
}
buf := make([]byte, size)
for i := 0; i < size; i++ {
n, err := rand.Int(rand.Reader, big.NewInt(int64(len(grindNameChars))))
if err != nil {
return "", core.E("covenant.GrindName", "random source failure", err)
}
buf[i] = grindNameChars[n.Int64()]
}
return string(buf), nil
}
// GrindName searches for an available name that satisfies the current rollout
// and reservation rules. It mirrors the JS helper used by reference tests.
func GrindName(size int, height uint32, rules NameRules) (string, error) {
if size <= 0 || size > MaxNameSize {
return "", core.E("covenant.GrindName", "invalid size", nil)
}
if height < rules.AuctionStart {
height = rules.AuctionStart
}
for i := 0; i < grindAttempts; i++ {
name, err := randomName(size)
if err != nil {
return "", err
}
if !VerifyString(name) {
continue
}
hash, err := HashString(name)
if err != nil {
continue
}
if !HasRollout(hash, height, rules) {
continue
}
if HasReservedHash(hash) {
continue
}
return name, nil
}
return "", core.E("covenant.GrindName", "could not find available name", nil)
}
// GetGrindName is an alias for GrindName.
//
// name, err := covenant.GetGrindName(8, height, rules)
func GetGrindName(size int, height uint32, rules NameRules) (string, error) {
return GrindName(size, height, rules)
}
// CountOpens counts OPEN covenants in the transaction outputs.
func CountOpens(tx primitives.Transaction) int {
total := 0
for _, output := range tx.Outputs {
if output.Covenant.IsOpen() {
total++
}
}
return total
}
// GetCountOpens is an alias for CountOpens.
//
// count := covenant.GetCountOpens(tx)
func GetCountOpens(tx primitives.Transaction) int {
return CountOpens(tx)
}
// CountUpdates counts UPDATE-style covenants in the transaction outputs.
func CountUpdates(tx primitives.Transaction) int {
total := 0
for _, output := range tx.Outputs {
switch CovenantType(output.Covenant.Type) {
case TypeClaim, TypeOpen, TypeUpdate, TypeTransfer, TypeRevoke:
total++
}
}
return total
}
// GetCountUpdates is an alias for CountUpdates.
//
// count := covenant.GetCountUpdates(tx)
func GetCountUpdates(tx primitives.Transaction) int {
return CountUpdates(tx)
}
// CountRenewals counts REGISTER, RENEW, and FINALIZE covenants in the transaction outputs.
func CountRenewals(tx primitives.Transaction) int {
total := 0
for _, output := range tx.Outputs {
switch CovenantType(output.Covenant.Type) {
case TypeRegister, TypeRenew, TypeFinalize:
total++
}
}
return total
}
// GetCountRenewals is an alias for CountRenewals.
//
// count := covenant.GetCountRenewals(tx)
func GetCountRenewals(tx primitives.Transaction) int {
return CountRenewals(tx)
}