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
/
action_transaction.go
176 lines (146 loc) · 5.18 KB
/
action_transaction.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package bux
import (
"context"
"github.com/BuxOrg/bux/utils"
)
// RecordTransaction will parse the transaction and Save it into the Datastore
//
// Internal (known) transactions: there is a corresponding `draft_transaction` via `draft_id`
// External (known) transactions: there are output(s) related to the destination `reference_id`, tx is valid (mempool/on-chain)
// External (unknown) transactions: no reference id but some output(s) match known outputs, tx is valid (mempool/on-chain)
// Unknown transactions: no matching outputs, tx will be disregarded
//
// xPubKey is the raw public xPub
// txHex is the raw transaction hex
// draftID is the unique draft id from a previously started New() transaction (draft_transaction.ID)
// opts are model options and can include "metadata"
func (c *Client) RecordTransaction(ctx context.Context, xPubKey, txHex, draftID string,
opts ...ModelOps) (*Transaction, error) {
// Check for existing NewRelic transaction
ctx = c.GetOrStartTxn(ctx, "record_transaction")
// Create the model & set the default options (gives options from client->model)
newOpts := c.DefaultModelOptions(append(opts, WithXPub(xPubKey), New())...)
transaction := newTransactionWithDraftID(
txHex, draftID, newOpts...,
)
// Ensure that we have a transaction id (created from the txHex)
id := transaction.GetID()
if len(id) == 0 {
return nil, ErrMissingTxHex
}
// Create the lock and set the release for after the function completes
unlock, err := newWriteLock(
ctx, "action-record-transaction-"+id, c.Cachestore(),
)
defer unlock()
if err != nil {
return nil, err
}
// OPTION: check incoming transactions (if enabled, will add to queue for checking on-chain)
if !c.IsITCEnabled() {
transaction.DebugLog("incoming transaction check is disabled")
} else {
// Incoming (external/unknown) transaction (no draft id was given)
if len(transaction.DraftID) == 0 {
// Process & save the model
incomingTx := newIncomingTransaction(
transaction.ID, txHex, newOpts...,
)
if err = incomingTx.Save(ctx); err != nil {
return nil, err
}
// Added to queue
return newTransactionFromIncomingTransaction(incomingTx), nil
}
// Internal tx (must match draft tx)
if transaction.draftTransaction, err = getDraftTransactionID(
ctx, transaction.xPubID, transaction.DraftID,
transaction.GetOptions(false)...,
); err != nil {
return nil, err
} else if transaction.draftTransaction == nil {
return nil, ErrDraftNotFound
}
}
// Process & save the transaction model
if err = transaction.Save(ctx); err != nil {
return nil, err
}
// Return the response
return transaction, nil
}
// NewTransaction will create a new draft transaction and return it
//
// ctx is the context
// rawXpubKey is the raw xPub key
// config is the TransactionConfig
// metadata is added to the model
// opts are additional model options to be applied
func (c *Client) NewTransaction(ctx context.Context, rawXpubKey string, config *TransactionConfig,
metadata map[string]interface{}, opts ...ModelOps) (*DraftTransaction, error) {
// Check for existing NewRelic draftTransaction
ctx = c.GetOrStartTxn(ctx, "new_transaction")
// Create the lock and set the release for after the function completes
unlock, err := newWaitWriteLock(
ctx, "action-xpub-"+utils.Hash(rawXpubKey), c.Cachestore(),
)
defer unlock()
if err != nil {
return nil, err
}
// Set the metadata if found
if len(metadata) > 0 {
opts = append(opts, WithMetadatas(metadata))
}
// todo: this needs adjusting via Chainstate or mAPI
if config.FeeUnit == nil {
config.FeeUnit = c.GetFeeUnit(ctx, "miner")
}
// Create the model & set the default options (gives options from client->model)
draftTransaction := newDraftTransaction(
rawXpubKey, config,
c.DefaultModelOptions(append(opts, New())...)...,
)
// Save the model
if err = draftTransaction.Save(ctx); err != nil {
return nil, err
}
// Return the created model
return draftTransaction, nil
}
// GetTransaction will get a transaction from the Datastore
//
// ctx is the context
// testTxID is the transaction ID
func (c *Client) GetTransaction(ctx context.Context, rawXpubKey, txID string) (*Transaction, error) {
// Check for existing NewRelic transaction
ctx = c.GetOrStartTxn(ctx, "get_transaction")
// Get the transaction by ID
transaction, err := getTransactionByID(
ctx, rawXpubKey, txID, c.DefaultModelOptions(WithXPub(rawXpubKey))...,
)
if err != nil {
return nil, err
}
return transaction, nil
}
// GetTransactions will get all transactions for a given xpub from the Datastore
//
// ctx is the context
// rawXpubKey is the raw xPub key
// metadata is added to the request for searching
func (c *Client) GetTransactions(ctx context.Context, rawXpubKey string, metadata *Metadata,
conditions *map[string]interface{}) ([]*Transaction, error) {
// Check for existing NewRelic transaction
ctx = c.GetOrStartTxn(ctx, "get_transaction")
// Get the transaction by ID
// todo: add params for: page size and page (right now it is unlimited)
transactions, err := getTransactionsByXpubID(
ctx, rawXpubKey, metadata, conditions, 0, 0,
c.DefaultModelOptions(WithXPub(rawXpubKey))...,
)
if err != nil {
return nil, err
}
return transactions, nil
}