Files
zeekayandHanzo Dev b1cc108c9f gofmt
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 01:51:51 -07:00

137 lines
3.7 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package primary
import (
"context"
"maps"
"slices"
"sync"
"github.com/luxfi/database"
"github.com/luxfi/ids"
"github.com/luxfi/node/wallet/network/primary/common"
lux "github.com/luxfi/utxo"
)
var (
_ UTXOs = (*utxos)(nil)
_ common.ChainUTXOs = (*chainUTXOs)(nil)
)
type UTXOs interface {
AddUTXO(ctx context.Context, sourceChainID, destinationChainID ids.ID, utxo *lux.UTXO) error
RemoveUTXO(ctx context.Context, sourceChainID, destinationChainID, utxoID ids.ID) error
UTXOs(ctx context.Context, sourceChainID, destinationChainID ids.ID) ([]*lux.UTXO, error)
GetUTXO(ctx context.Context, sourceChainID, destinationChainID, utxoID ids.ID) (*lux.UTXO, error)
}
func NewUTXOs() UTXOs {
return &utxos{
sourceToDestToUTXOIDToUTXO: make(map[ids.ID]map[ids.ID]map[ids.ID]*lux.UTXO),
}
}
func NewChainUTXOs(chainID ids.ID, utxos UTXOs) common.ChainUTXOs {
return &chainUTXOs{
utxos: utxos,
chainID: chainID,
}
}
type utxos struct {
lock sync.RWMutex
// sourceChainID -> destinationChainID -> utxoID -> utxo
sourceToDestToUTXOIDToUTXO map[ids.ID]map[ids.ID]map[ids.ID]*lux.UTXO
}
func (u *utxos) AddUTXO(_ context.Context, sourceChainID, destinationChainID ids.ID, utxo *lux.UTXO) error {
u.lock.Lock()
defer u.lock.Unlock()
destToUTXOIDToUTXO, ok := u.sourceToDestToUTXOIDToUTXO[sourceChainID]
if !ok {
destToUTXOIDToUTXO = make(map[ids.ID]map[ids.ID]*lux.UTXO)
u.sourceToDestToUTXOIDToUTXO[sourceChainID] = destToUTXOIDToUTXO
}
utxoIDToUTXO, ok := destToUTXOIDToUTXO[destinationChainID]
if !ok {
utxoIDToUTXO = make(map[ids.ID]*lux.UTXO)
destToUTXOIDToUTXO[destinationChainID] = utxoIDToUTXO
}
utxoIDToUTXO[utxo.InputID()] = utxo
return nil
}
func (u *utxos) RemoveUTXO(_ context.Context, sourceChainID, destinationChainID, utxoID ids.ID) error {
u.lock.Lock()
defer u.lock.Unlock()
destToUTXOIDToUTXO := u.sourceToDestToUTXOIDToUTXO[sourceChainID]
utxoIDToUTXO := destToUTXOIDToUTXO[destinationChainID]
_, ok := utxoIDToUTXO[utxoID]
if !ok {
return nil
}
delete(utxoIDToUTXO, utxoID)
if len(utxoIDToUTXO) != 0 {
return nil
}
delete(destToUTXOIDToUTXO, destinationChainID)
if len(destToUTXOIDToUTXO) != 0 {
return nil
}
delete(u.sourceToDestToUTXOIDToUTXO, sourceChainID)
return nil
}
func (u *utxos) UTXOs(_ context.Context, sourceChainID, destinationChainID ids.ID) ([]*lux.UTXO, error) {
u.lock.RLock()
defer u.lock.RUnlock()
destToUTXOIDToUTXO := u.sourceToDestToUTXOIDToUTXO[sourceChainID]
utxoIDToUTXO := destToUTXOIDToUTXO[destinationChainID]
return slices.Collect(maps.Values(utxoIDToUTXO)), nil
}
func (u *utxos) GetUTXO(_ context.Context, sourceChainID, destinationChainID, utxoID ids.ID) (*lux.UTXO, error) {
u.lock.RLock()
defer u.lock.RUnlock()
destToUTXOIDToUTXO := u.sourceToDestToUTXOIDToUTXO[sourceChainID]
utxoIDToUTXO := destToUTXOIDToUTXO[destinationChainID]
utxo, ok := utxoIDToUTXO[utxoID]
if !ok {
return nil, database.ErrNotFound
}
return utxo, nil
}
type chainUTXOs struct {
utxos UTXOs
chainID ids.ID
}
func (c *chainUTXOs) AddUTXO(ctx context.Context, destinationChainID ids.ID, utxo *lux.UTXO) error {
return c.utxos.AddUTXO(ctx, c.chainID, destinationChainID, utxo)
}
func (c *chainUTXOs) RemoveUTXO(ctx context.Context, sourceChainID, utxoID ids.ID) error {
return c.utxos.RemoveUTXO(ctx, sourceChainID, c.chainID, utxoID)
}
func (c *chainUTXOs) UTXOs(ctx context.Context, sourceChainID ids.ID) ([]*lux.UTXO, error) {
return c.utxos.UTXOs(ctx, sourceChainID, c.chainID)
}
func (c *chainUTXOs) GetUTXO(ctx context.Context, sourceChainID, utxoID ids.ID) (*lux.UTXO, error) {
return c.utxos.GetUTXO(ctx, sourceChainID, c.chainID, utxoID)
}