-
Notifications
You must be signed in to change notification settings - Fork 660
/
backend.go
106 lines (86 loc) · 2.37 KB
/
backend.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package p
import (
"sync"
stdcontext "context"
"github.com/ava-labs/avalanchego/database"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/set"
"github.com/ava-labs/avalanchego/vms/components/avax"
"github.com/ava-labs/avalanchego/vms/platformvm/txs"
)
var _ Backend = (*backend)(nil)
type ChainUTXOs interface {
AddUTXO(ctx stdcontext.Context, destinationChainID ids.ID, utxo *avax.UTXO) error
RemoveUTXO(ctx stdcontext.Context, sourceChainID, utxoID ids.ID) error
UTXOs(ctx stdcontext.Context, sourceChainID ids.ID) ([]*avax.UTXO, error)
GetUTXO(ctx stdcontext.Context, sourceChainID, utxoID ids.ID) (*avax.UTXO, error)
}
// Backend defines the full interface required to support a P-chain wallet.
type Backend interface {
ChainUTXOs
BuilderBackend
SignerBackend
AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error
}
type backend struct {
Context
ChainUTXOs
txsLock sync.RWMutex
// txID -> tx
txs map[ids.ID]*txs.Tx
}
func NewBackend(ctx Context, utxos ChainUTXOs, txs map[ids.ID]*txs.Tx) Backend {
return &backend{
Context: ctx,
ChainUTXOs: utxos,
txs: txs,
}
}
func (b *backend) AcceptTx(ctx stdcontext.Context, tx *txs.Tx) error {
txID := tx.ID()
err := tx.Unsigned.Visit(&backendVisitor{
b: b,
ctx: ctx,
txID: txID,
})
if err != nil {
return err
}
producedUTXOSlice := tx.UTXOs()
err = b.addUTXOs(ctx, constants.PlatformChainID, producedUTXOSlice)
if err != nil {
return err
}
b.txsLock.Lock()
defer b.txsLock.Unlock()
b.txs[txID] = tx
return nil
}
func (b *backend) addUTXOs(ctx stdcontext.Context, destinationChainID ids.ID, utxos []*avax.UTXO) error {
for _, utxo := range utxos {
if err := b.AddUTXO(ctx, destinationChainID, utxo); err != nil {
return err
}
}
return nil
}
func (b *backend) removeUTXOs(ctx stdcontext.Context, sourceChain ids.ID, utxoIDs set.Set[ids.ID]) error {
for utxoID := range utxoIDs {
if err := b.RemoveUTXO(ctx, sourceChain, utxoID); err != nil {
return err
}
}
return nil
}
func (b *backend) GetTx(_ stdcontext.Context, txID ids.ID) (*txs.Tx, error) {
b.txsLock.RLock()
defer b.txsLock.RUnlock()
tx, exists := b.txs[txID]
if !exists {
return nil, database.ErrNotFound
}
return tx, nil
}