This repository has been archived by the owner on Apr 2, 2024. It is now read-only.
generated from mrz1836/go-template
-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
record_tx.go
110 lines (89 loc) · 2.44 KB
/
record_tx.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
107
108
109
110
package bux
import (
"context"
"fmt"
"time"
)
type recordTxStrategy interface {
TxID() string
LockKey() string
Validate() error
Execute(ctx context.Context, c ClientInterface, opts []ModelOps) (*Transaction, error)
}
type recordIncomingTxStrategy interface {
recordTxStrategy
ForceBroadcast(force bool)
FailOnBroadcastError(forceFail bool)
}
func recordTransaction(ctx context.Context, c ClientInterface, strategy recordTxStrategy, opts ...ModelOps) (*Transaction, error) {
unlock := waitForRecordTxWriteLock(ctx, c, strategy.LockKey())
defer unlock()
return strategy.Execute(ctx, c, opts)
}
func getRecordTxStrategy(ctx context.Context, c ClientInterface, xPubKey, txHex, draftID string) (recordTxStrategy, error) {
var rts recordTxStrategy
if draftID != "" {
rts = getOutgoingTxRecordStrategy(xPubKey, txHex, draftID)
} else {
var err error
rts, err = getIncomingTxRecordStrategy(ctx, c, txHex)
if err != nil {
return nil, err
}
}
if err := rts.Validate(); err != nil {
return nil, err
}
return rts, nil
}
func getOutgoingTxRecordStrategy(xPubKey, txHex, draftID string) recordTxStrategy {
return &outgoingTx{
Hex: txHex,
RelatedDraftID: draftID,
XPubKey: xPubKey,
}
}
func getIncomingTxRecordStrategy(ctx context.Context, c ClientInterface, txHex string) (recordIncomingTxStrategy, error) {
tx, err := getTransactionByHex(ctx, txHex, c.DefaultModelOptions()...)
if err != nil {
return nil, err
}
var rts recordIncomingTxStrategy
if tx != nil {
rts = &internalIncomingTx{
Tx: tx,
broadcastNow: false,
}
} else {
rts = &externalIncomingTx{
Hex: txHex,
broadcastNow: false,
}
}
return rts, nil
}
func waitForRecordTxWriteLock(ctx context.Context, c ClientInterface, key string) func() {
var (
unlock func()
err error
)
// Create the lock and set the release for after the function completes
// Waits for the moment when the transaction is unlocked and creates a new lock
// Relevant for bux to bux transactions, as we have 1 tx but need to record 2 txs - outgoing and incoming
lockKey := fmt.Sprintf(lockKeyRecordTx, key)
c.Logger().Debug().Msgf("try add write lock %s", lockKey)
for {
unlock, err = newWriteLock(
ctx, lockKey, c.Cachestore(),
)
if err == nil {
c.Logger().Debug().Msgf("added write lock %s", lockKey)
break
}
time.Sleep(time.Second * 1)
}
return func() {
c.Logger().Debug().Msgf("unlock %s", lockKey)
unlock()
}
}