mirror of
https://github.com/luxfi/sdk.git
synced 2026-10-30 15:19:23 +00:00
144 lines
4.0 KiB
Go
144 lines
4.0 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package common
|
|
|
|
import (
|
|
"context"
|
|
"maps"
|
|
"slices"
|
|
"sync"
|
|
|
|
"github.com/luxfi/database"
|
|
"github.com/luxfi/ids"
|
|
lux "github.com/luxfi/utxo"
|
|
)
|
|
|
|
var (
|
|
_ UTXOs = (*utxos)(nil)
|
|
_ 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)
|
|
}
|
|
|
|
type ChainUTXOs interface {
|
|
AddUTXO(ctx context.Context, destinationChainID ids.ID, utxo *lux.UTXO) error
|
|
RemoveUTXO(ctx context.Context, sourceChainID, utxoID ids.ID) error
|
|
|
|
UTXOs(ctx context.Context, sourceChainID ids.ID) ([]*lux.UTXO, error)
|
|
GetUTXO(ctx context.Context, sourceChainID, 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) 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)
|
|
}
|