utxo: strip Eth/Keccak aliases — EVMAddrs / EVMAddresses() / GetByEVM only

Forward-only per user "no aliases!!! just keep evm address and utxo address"
and CLAUDE.md "no backwards compatibility only forwards perfection".

Removed from secp256k1fx.Keychain:
- KeccakAddrs / EthAddrs fields (were Deprecated aliases sharing map)
- KeccakAddresses() / EthAddresses() methods (were Deprecated)
- GetByKeccak() / GetEth() methods (were Deprecated)
- private keccakAddrToKeyIndex (renamed evmAddrToKeyIndex)
- private luxAddrToKeyIndex (renamed utxoAddrToKeyIndex — was already
  UTXO data but the naming braided in the brand)

Canonical surface (the only API):
- Addrs       set.Set[ids.ShortID]            — UTXO-native ShortIDs
- EVMAddrs    set.Set[gethcommon.Address]     — EVM-runtime 20-byte addrs
- Addresses() set.Set[ids.ShortID]            — keychain.Keychain interface
- EVMAddresses() set.Set[gethcommon.Address]
- Get(ShortID) — UTXO-side lookup
- GetByEVM(gethcommon.Address) — EVM-side lookup
- Add(*PrivateKey) — populates both sides

Downstream callers across cli, kms, mpc, state must update to use
EVMAddrs / EVMAddresses() / GetByEVM only. Lockstep break-fix in
this wave.

Deps: crypto v1.19.15 → v1.19.16 (matches crypto's alias-strip).

Per CLAUDE.md x.x.x+1.
This commit is contained in:
Hanzo AI
2026-05-23 23:55:45 -07:00
parent 32d3c529c9
commit bb56be5530
3 changed files with 25 additions and 68 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ require (
github.com/luxfi/cache v1.2.1
github.com/luxfi/codec v1.1.4
github.com/luxfi/constants v1.4.7
github.com/luxfi/crypto v1.19.15
github.com/luxfi/crypto v1.19.16
github.com/luxfi/database v1.17.44
github.com/luxfi/formatting v1.0.1
github.com/luxfi/geth v1.16.98
+2 -2
View File
@@ -91,8 +91,8 @@ github.com/luxfi/constants v1.4.7 h1:e/Qs+DQP3pugle3Zncq6fZCxKgqqtbyD/z7Gm4ZjsYg
github.com/luxfi/constants v1.4.7/go.mod h1:hOszZ2NDQ8gMZKncfcZ67PXkb5OIbnwAzXC3oFbQwW0=
github.com/luxfi/container v0.0.4 h1:BXhF82WyfqVP5mjlNcr7tP0Fcnvl0Ap1rkiu+rq5XuM=
github.com/luxfi/container v0.0.4/go.mod h1:Z3SpmMF5d4t77MM0nHYXURpn+EMVaeu1fhbd/3BGaek=
github.com/luxfi/crypto v1.19.15 h1:Tf+iPRXv08Rlj9k7iNtYy0e1tJWIgRcY0pTR4rQax6w=
github.com/luxfi/crypto v1.19.15/go.mod h1:INjdZtke85k8hX/QAmTMAY8bbZ4gzGZQLqURg3xf6Gk=
github.com/luxfi/crypto v1.19.16 h1:YCAXtLS65TCi7/iw6zBglFW0YS80zJj9Y61fTxdP+wo=
github.com/luxfi/crypto v1.19.16/go.mod h1:INjdZtke85k8hX/QAmTMAY8bbZ4gzGZQLqURg3xf6Gk=
github.com/luxfi/database v1.17.44 h1:hfiTls7sqbweW+o4iaZqB8P997paC+vpgWmhN6v5MJ0=
github.com/luxfi/database v1.17.44/go.mod h1:6Ey5y3I0WNLHbxIlIdFqUuKfBg+b0fAgTA8FgRgQ8zg=
github.com/luxfi/formatting v1.0.1 h1:ZnE1rAdEUds9yAegdVdGDOBGN6hLMPOv6E03Fp8IEYo=
+22 -65
View File
@@ -58,47 +58,34 @@ func (s *luxSigner) AddressBytes() []byte {
// Keychain is a collection of keys that can be used to spend outputs.
//
// The keychain holds TWO orthogonal address spaces for each key:
// Each key has two address forms (the two data models in a multi-chain
// keychain):
//
// - Addrs: UTXO-native X-Chain / P-Chain addresses (SHA256+RIPEMD160 →
// ids.ShortID). This is the address space of UTXO chains.
// ids.ShortID). Consumed by UTXO-model chains.
//
// - EVMAddrs: 20-byte account addresses used by EVM-runtime chains
// - EVMAddrs: 20-byte account addresses consumed by EVM-runtime chains
// (Lux C-Chain, Partner EVM, Hanzo EVM, Polygon, BSC, etc.). The
// internal derivation uses Keccak256, but the name reflects the
// data model that consumes the value (EVM account address), not
// the hash primitive that derives it. UTXO vs EVM is the relevant
// contrast in a multi-chain keychain — Keccak is just a hash.
//
// KeccakAddrs and EthAddrs are deprecated aliases of EVMAddrs that
// share the SAME underlying map so adds via any field are visible
// from all three. set.Set is a map type (reference semantics).
// internal derivation uses Keccak256, but the name reflects what
// the value IS (EVM-runtime account address), not how it's hashed.
type Keychain struct {
luxAddrToKeyIndex map[ids.ShortID]int
evmAddrToKeyIndex map[gethcommon.Address]int
utxoAddrToKeyIndex map[ids.ShortID]int
evmAddrToKeyIndex map[gethcommon.Address]int
// These can be used to iterate over. However, they should not be modified
// externally. KeccakAddrs and EthAddrs share the same underlying
// map as EVMAddrs — see type docstring.
Addrs set.Set[ids.ShortID]
EVMAddrs set.Set[gethcommon.Address]
KeccakAddrs set.Set[gethcommon.Address] // Deprecated: same map as EVMAddrs
EthAddrs set.Set[gethcommon.Address] // Deprecated: same map as EVMAddrs
Keys []*secp256k1.PrivateKey
// These can be used to iterate over. However, they should not be
// modified externally.
Addrs set.Set[ids.ShortID]
EVMAddrs set.Set[gethcommon.Address]
Keys []*secp256k1.PrivateKey
}
// NewKeychain returns a new keychain containing [keys]
func NewKeychain(keys ...*secp256k1.PrivateKey) *Keychain {
evmAddrs := make(set.Set[gethcommon.Address])
kc := &Keychain{
luxAddrToKeyIndex: make(map[ids.ShortID]int),
evmAddrToKeyIndex: make(map[gethcommon.Address]int),
Addrs: make(set.Set[ids.ShortID]),
// EVMAddrs / KeccakAddrs / EthAddrs share the SAME underlying
// map so Adds via any field are visible from all three.
EVMAddrs: evmAddrs,
KeccakAddrs: evmAddrs,
EthAddrs: evmAddrs,
utxoAddrToKeyIndex: make(map[ids.ShortID]int),
evmAddrToKeyIndex: make(map[gethcommon.Address]int),
Addrs: make(set.Set[ids.ShortID]),
EVMAddrs: make(set.Set[gethcommon.Address]),
}
for _, key := range keys {
kc.Add(key)
@@ -112,17 +99,15 @@ func (kc *Keychain) Add(key *secp256k1.PrivateKey) {
// Convert public key to Lux address using hash160
pkBytes := pk.Bytes()
addressBytes := secp256k1.PubkeyBytesToAddress(pkBytes)
luxAddr, _ := ids.ToShortID(addressBytes)
utxoAddr, _ := ids.ToShortID(addressBytes)
if _, ok := kc.luxAddrToKeyIndex[luxAddr]; !ok {
kc.luxAddrToKeyIndex[luxAddr] = len(kc.Keys)
if _, ok := kc.utxoAddrToKeyIndex[utxoAddr]; !ok {
kc.utxoAddrToKeyIndex[utxoAddr] = len(kc.Keys)
cryptoAddr := secp256k1.PubkeyToAddress(*pk.ToECDSA())
evmAddr := gethcommon.Address(cryptoAddr)
kc.evmAddrToKeyIndex[evmAddr] = len(kc.Keys)
kc.Keys = append(kc.Keys, key)
kc.Addrs.Add(luxAddr)
// One write — EVMAddrs / KeccakAddrs / EthAddrs all see it
// since they share the underlying map.
kc.Addrs.Add(utxoAddr)
kc.EVMAddrs.Add(evmAddr)
}
}
@@ -147,20 +132,6 @@ func (kc Keychain) GetByEVM(addr gethcommon.Address) (keychain.Signer, bool) {
return nil, false
}
// GetByKeccak is the deprecated alias for GetByEVM.
//
// Deprecated: use GetByEVM.
func (kc Keychain) GetByKeccak(addr gethcommon.Address) (keychain.Signer, bool) {
return kc.GetByEVM(addr)
}
// GetEth is the deprecated alias for GetByEVM.
//
// Deprecated: use GetByEVM.
func (kc Keychain) GetEth(addr gethcommon.Address) (keychain.Signer, bool) {
return kc.GetByEVM(addr)
}
// AddressSet returns a set of addresses this keychain manages
func (kc Keychain) AddressSet() set.Set[ids.ShortID] {
return kc.Addrs
@@ -197,20 +168,6 @@ func (kc Keychain) EVMAddresses() set.Set[gethcommon.Address] {
return kc.EVMAddrs
}
// KeccakAddresses is the deprecated alias for EVMAddresses.
//
// Deprecated: use EVMAddresses.
func (kc Keychain) KeccakAddresses() set.Set[gethcommon.Address] {
return kc.EVMAddresses()
}
// EthAddresses is the deprecated alias for EVMAddresses.
//
// Deprecated: use EVMAddresses.
func (kc Keychain) EthAddresses() set.Set[gethcommon.Address] {
return kc.EVMAddresses()
}
// New returns a newly generated private key
func (kc *Keychain) New() (*secp256k1.PrivateKey, error) {
sk, err := secp256k1.NewPrivateKey()
@@ -289,7 +246,7 @@ func (kc *Keychain) String() string {
// to avoid internals type assertions
func (kc Keychain) get(id ids.ShortID) (*secp256k1.PrivateKey, bool) {
if i, ok := kc.luxAddrToKeyIndex[id]; ok {
if i, ok := kc.utxoAddrToKeyIndex[id]; ok {
return kc.Keys[i], true
}
return nil, false