Files
zeekay 4e6885fbe8 chore: initial commit — tree had no git at all
github.com/luxfi/coronad existed only as loose files: no .git, no history, no
remote. Invisible to any sweep that looks for a .git directory, and an rm -rf
would have destroyed it unrecoverably.

Includes two dependency repairs.

1. It did not build: "unknown revision v1.16.98" — the v1.16.x line was DELETED
   from github.com/luxfi/geth. The requirement is baked into published modules
   (crypto/constants/warp pin the dead tag, some also `exclude` the
   alternative), so requiring crypto v1.20.2 / constants v1.6.2 / warp v1.24.1
   is what escapes it.

2. Dropped two replace directives pointing at absolute paths on one disk:

       replace github.com/luxfi/corona => /Users/z/work/lux/corona
       replace github.com/luxfi/warp   => /Users/z/work/lux/warp

   Those would have made this module resolvable ONLY on this machine — CI or
   any other checkout could never build it. They were also unnecessary: the
   published versions the `require` lines already name (corona v0.10.4) build
   and test clean without them.

Verified: go build ./... exits 0, go test ./... 1 ok / 0 fail.
The compiled coronad binary is ignored rather than committed.

NOTE: no remote — luxfi/coronad does not exist on GitHub. Still one copy.
2026-07-26 05:22:22 -07:00

66 lines
2.1 KiB
Go

// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package coronad
import (
"fmt"
"sync"
"github.com/luxfi/corona/threshold"
"github.com/luxfi/ids"
"github.com/luxfi/warp"
warppulsar "github.com/luxfi/warp/pulsar"
)
// EraResolver is an in-memory warp/pulsar.CoronaGroupKeyResolver: it maps a
// (chainID, keyEraID, generation) tuple to the era's Corona group key and the
// Corona suite id. A destination chain's REAL resolver pulls the group key from
// its on-chain source-chain Corona key registry; EraResolver is the same shape
// for tests and single-box deployment.
//
// Compile-time assertion that *EraResolver satisfies the warp boundary:
var _ warppulsar.CoronaGroupKeyResolver = (*EraResolver)(nil)
type eraKey struct {
chainID ids.ID
keyEraID uint64
generation uint64
}
type EraResolver struct {
mu sync.RWMutex
keys map[eraKey]*threshold.GroupKey
}
// NewEraResolver returns an empty resolver. Register eras with Add.
func NewEraResolver() *EraResolver {
return &EraResolver{keys: make(map[eraKey]*threshold.GroupKey)}
}
// Add registers an era's group key for its CURRENT (chainID, keyEraID,
// generation). Corona's Reshare/Refresh preserve the group key but advance the
// generation, so call Add again after each advance to answer for the new
// generation the emitted evidence carries.
func (r *EraResolver) Add(era *Era) {
if era == nil || era.GroupKey() == nil {
return
}
r.mu.Lock()
defer r.mu.Unlock()
r.keys[eraKey{era.ChainID(), era.KeyEraID(), era.Generation()}] = era.GroupKey()
}
// ResolveGroupKey implements warp/pulsar.CoronaGroupKeyResolver.
func (r *EraResolver) ResolveGroupKey(sourceChainID [32]byte, keyEraID, generation uint64) (*threshold.GroupKey, string, error) {
r.mu.RLock()
gk, ok := r.keys[eraKey{ids.ID(sourceChainID), keyEraID, generation}]
r.mu.RUnlock()
if !ok || gk == nil {
return nil, "", fmt.Errorf("coronad: no Corona group key for chain=%x keyEra=%d gen=%d",
sourceChainID[:4], keyEraID, generation)
}
return gk, string(warp.DefaultCoronaSuiteID), nil
}