generated from mrz1836/go-template
/
broadcast_providers.go
142 lines (115 loc) · 3.67 KB
/
broadcast_providers.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
package chainstate
import (
"context"
"errors"
"fmt"
"strings"
"github.com/bitcoin-sv/go-broadcast-client/broadcast"
"github.com/tonicpow/go-minercraft/v2"
)
// generic broadcast provider
type txBroadcastProvider interface {
getName() string
broadcast(ctx context.Context, c *Client) error
}
// mAPI provider
type mapiBroadcastProvider struct {
miner *minercraft.Miner
txID, txHex string
}
func (provider *mapiBroadcastProvider) getName() string {
return provider.miner.Name
}
func (provider *mapiBroadcastProvider) broadcast(ctx context.Context, c *Client) error {
return broadcastMAPI(ctx, c, provider.miner, provider.txID, provider.txHex)
}
// broadcastMAPI will broadcast a transaction to a miner using mAPI
func broadcastMAPI(ctx context.Context, client *Client, miner *minercraft.Miner, id, hex string) error {
logger := client.options.logger
logger.Debug().
Str("txID", id).
Msgf("executing broadcast request in mapi using miner: %s", miner.Name)
resp, err := client.Minercraft().SubmitTransaction(ctx, miner, &minercraft.Transaction{
CallBackEncryption: "", // todo: allow customizing the payload
CallBackToken: "",
CallBackURL: "",
DsCheck: false,
MerkleFormat: "",
MerkleProof: false,
RawTx: hex,
})
if err != nil {
logger.Debug().
Str("txID", id).
Msgf("error executing request in mapi using miner: %s failed: %s", miner.Name, err.Error())
return err
}
// Something went wrong - got back an id that does not match
if resp == nil {
return emptyBroadcastResponseErr(id)
}
if !strings.EqualFold(resp.Results.TxID, id) {
return incorrectTxIDReturnedErr(resp.Results.TxID, id)
}
// mAPI success of broadcast
if resp.Results.ReturnResult == mAPISuccess {
return nil
}
// Check error message (for success error message)
if doesErrorContain(resp.Results.ResultDescription, broadcastSuccessErrors) {
return nil
}
// We got a potential real error message?
return errors.New(resp.Results.ResultDescription)
}
func incorrectTxIDReturnedErr(actualTxID, expectedTxID string) error {
return fmt.Errorf("returned tx id [%s] does not match given tx id [%s]", actualTxID, expectedTxID)
}
func emptyBroadcastResponseErr(txID string) error {
return fmt.Errorf("an empty response was returned after broadcasting of tx id [%s]", txID)
}
////
// BroadcastClient provider
type broadcastClientProvider struct {
txID, txHex string
format HexFormatFlag
}
func (provider *broadcastClientProvider) getName() string {
return ProviderBroadcastClient
}
func (provider *broadcastClientProvider) broadcast(ctx context.Context, c *Client) error {
logger := c.options.logger
logger.Debug().
Str("txID", provider.txID).
Msgf("executing broadcast request for %s", provider.getName())
tx := broadcast.Transaction{
Hex: provider.txHex,
}
formatOpt := broadcast.WithRawFormat()
if provider.format.Contains(Ef) {
formatOpt = broadcast.WithEfFormat()
logger.Debug().
Str("txID", provider.txID).
Msgf("broadcast with broadcast-client in Extended Format")
} else {
logger.Debug().
Str("txID", provider.txID).
Msgf("broadcast with broadcast-client in RawTx format")
}
result, err := c.BroadcastClient().SubmitTransaction(
ctx,
&tx,
formatOpt,
broadcast.WithCallback(c.options.config.callbackURL, c.options.config.callbackToken),
)
if err != nil {
logger.Debug().
Str("txID", provider.txID).
Msgf("error broadcast request for %s failed: %s", provider.getName(), err.Error())
return err
}
logger.Debug().
Str("txID", provider.txID).
Msgf("result broadcast request for %s blockhash: %s status: %s", provider.getName(), result.BlockHash, result.TxStatus.String())
return nil
}