-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.go
296 lines (266 loc) · 10.1 KB
/
types.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
package bchain
import (
"context"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"math/big"
)
// ChainType is type of the blockchain
type ChainType int
const (
// ChainBitcoinType is blockchain derived from bitcoin
ChainBitcoinType = ChainType(iota)
// ChainEthereumType is blockchain derived from ethereum
ChainEthereumType
)
// errors with specific meaning returned by blockchain rpc
var (
// ErrBlockNotFound is returned when block is not found
// either unknown hash or too high height
// can be returned from GetBlockHash, GetBlockHeader, GetBlock
ErrBlockNotFound = errors.New("Block not found")
// ErrAddressMissing is returned if address is not specified
// for example To address in ethereum can be missing in case of contract transaction
ErrAddressMissing = errors.New("Address missing")
// ErrTxidMissing is returned if txid is not specified
// for example coinbase transactions in Bitcoin
ErrTxidMissing = errors.New("Txid missing")
// ErrTxNotFound is returned if transaction was not found
ErrTxNotFound = errors.New("Tx not found")
)
// Outpoint is txid together with output (or input) index
type Outpoint struct {
Txid string
Vout int32
}
// ScriptSig contains data about input script
type ScriptSig struct {
// Asm string `json:"asm"`
Hex string `json:"hex"`
}
// Vin contains data about tx output
type Vin struct {
Coinbase string `json:"coinbase"`
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig ScriptSig `json:"scriptSig"`
Sequence uint32 `json:"sequence"`
Addresses []string `json:"addresses"`
}
// ScriptPubKey contains data about output script
type ScriptPubKey struct {
// Asm string `json:"asm"`
Hex string `json:"hex,omitempty"`
// Type string `json:"type"`
Addresses []string `json:"addresses"`
}
// Vout contains data about tx output
type Vout struct {
ValueSat big.Int
JsonValue json.Number `json:"value"`
N uint32 `json:"n"`
ScriptPubKey ScriptPubKey `json:"scriptPubKey"`
}
// Tx is blockchain transaction
// unnecessary fields are commented out to avoid overhead
type Tx struct {
Hex string `json:"hex"`
Txid string `json:"txid"`
Version int32 `json:"version"`
LockTime uint32 `json:"locktime"`
Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"`
// BlockHash string `json:"blockhash,omitempty"`
Confirmations uint32 `json:"confirmations,omitempty"`
Time int64 `json:"time,omitempty"`
Blocktime int64 `json:"blocktime,omitempty"`
CoinSpecificData interface{} `json:"-"`
}
// Block is block header and list of transactions
type Block struct {
BlockHeader
Txs []Tx `json:"tx"`
}
// BlockHeader contains limited data (as needed for indexing) from backend block header
type BlockHeader struct {
Hash string `json:"hash"`
Prev string `json:"previousblockhash"`
Next string `json:"nextblockhash"`
Height uint32 `json:"height"`
Confirmations int `json:"confirmations"`
Size int `json:"size"`
Time int64 `json:"time,omitempty"`
}
// BlockInfo contains extended block header data and a list of block txids
type BlockInfo struct {
BlockHeader
Version json.Number `json:"version"`
MerkleRoot string `json:"merkleroot"`
Nonce json.Number `json:"nonce"`
Bits string `json:"bits"`
Difficulty json.Number `json:"difficulty"`
Txids []string `json:"tx,omitempty"`
}
// MempoolEntry is used to get data about mempool entry
type MempoolEntry struct {
Size uint32 `json:"size"`
FeeSat big.Int
Fee json.Number `json:"fee"`
ModifiedFeeSat big.Int
ModifiedFee json.Number `json:"modifiedfee"`
Time uint64 `json:"time"`
Height uint32 `json:"height"`
DescendantCount uint32 `json:"descendantcount"`
DescendantSize uint32 `json:"descendantsize"`
DescendantFees uint32 `json:"descendantfees"`
AncestorCount uint32 `json:"ancestorcount"`
AncestorSize uint32 `json:"ancestorsize"`
AncestorFees uint32 `json:"ancestorfees"`
Depends []string `json:"depends"`
}
// ChainInfo is used to get information about blockchain
type ChainInfo struct {
Chain string `json:"chain"`
Blocks int `json:"blocks"`
Headers int `json:"headers"`
Bestblockhash string `json:"bestblockhash"`
Difficulty string `json:"difficulty"`
SizeOnDisk int64 `json:"size_on_disk"`
Version string `json:"version"`
Subversion string `json:"subversion"`
ProtocolVersion string `json:"protocolversion"`
Timeoffset float64 `json:"timeoffset"`
Warnings string `json:"warnings"`
}
// RPCError defines rpc error returned by backend
type RPCError struct {
Code int `json:"code"`
Message string `json:"message"`
}
func (e *RPCError) Error() string {
return fmt.Sprintf("%d: %s", e.Code, e.Message)
}
// AddressDescriptor is an opaque type obtained by parser.GetAddrDesc* methods
type AddressDescriptor []byte
func (ad AddressDescriptor) String() string {
return "ad:" + hex.EncodeToString(ad)
}
// EthereumType specific
// Erc20Contract contains info about ERC20 contract
type Erc20Contract struct {
Contract string `json:"contract"`
Name string `json:"name"`
Symbol string `json:"symbol"`
Decimals int `json:"decimals"`
}
// Erc20Transfer contains a single ERC20 token transfer
type Erc20Transfer struct {
Contract string
From string
To string
Tokens big.Int
}
// MempoolTxidEntry contains mempool txid with first seen time
type MempoolTxidEntry struct {
Txid string
Time uint32
}
// MempoolTxidEntries is array of MempoolTxidEntry
type MempoolTxidEntries []MempoolTxidEntry
// OnNewBlockFunc is used to send notification about a new block
type OnNewBlockFunc func(hash string, height uint32)
// OnNewTxAddrFunc is used to send notification about a new transaction/address
type OnNewTxAddrFunc func(tx *Tx, desc AddressDescriptor)
// AddrDescForOutpointFunc defines function that returns address descriptorfor given outpoint or nil if outpoint not found
type AddrDescForOutpointFunc func(outpoint Outpoint) AddressDescriptor
// BlockChain defines common interface to block chain daemon
type BlockChain interface {
// life-cycle methods
// initialize the block chain connector
Initialize() error
// create mempool but do not initialize it
CreateMempool(BlockChain) (Mempool, error)
// initialize mempool, create ZeroMQ (or other) subscription
InitializeMempool(AddrDescForOutpointFunc, OnNewTxAddrFunc) error
// shutdown mempool, ZeroMQ and block chain connections
Shutdown(ctx context.Context) error
// chain info
IsTestnet() bool
GetNetworkName() string
GetSubversion() string
GetCoinName() string
GetChainInfo() (*ChainInfo, error)
// requests
GetBestBlockHash() (string, error)
GetBestBlockHeight() (uint32, error)
GetBlockHash(height uint32) (string, error)
GetBlockHeader(hash string) (*BlockHeader, error)
GetBlock(hash string, height uint32) (*Block, error)
GetBlockInfo(hash string) (*BlockInfo, error)
GetMempoolTransactions() ([]string, error)
GetTransaction(txid string) (*Tx, error)
GetTransactionForMempool(txid string) (*Tx, error)
GetTransactionSpecific(tx *Tx) (json.RawMessage, error)
EstimateSmartFee(blocks int, conservative bool) (big.Int, error)
EstimateFee(blocks int) (big.Int, error)
SendRawTransaction(tx string) (string, error)
GetMempoolEntry(txid string) (*MempoolEntry, error)
// parser
GetChainParser() BlockChainParser
// EthereumType specific
EthereumTypeGetBalance(addrDesc AddressDescriptor) (*big.Int, error)
EthereumTypeGetNonce(addrDesc AddressDescriptor) (uint64, error)
EthereumTypeEstimateGas(params map[string]interface{}) (uint64, error)
EthereumTypeGetErc20ContractInfo(contractDesc AddressDescriptor) (*Erc20Contract, error)
EthereumTypeGetErc20ContractBalance(addrDesc, contractDesc AddressDescriptor) (*big.Int, error)
}
// BlockChainParser defines common interface to parsing and conversions of block chain data
type BlockChainParser interface {
// type of the blockchain
GetChainType() ChainType
// KeepBlockAddresses returns number of blocks which are to be kept in blockTxs column
// to be used for rollbacks
KeepBlockAddresses() int
// AmountDecimals returns number of decimal places in coin amounts
AmountDecimals() int
// AmountToDecimalString converts amount in big.Int to string with decimal point in the correct place
AmountToDecimalString(a *big.Int) string
// AmountToBigInt converts amount in json.Number (string) to big.Int
// it uses string operations to avoid problems with rounding
AmountToBigInt(n json.Number) (big.Int, error)
// address descriptor conversions
GetAddrDescFromVout(output *Vout) (AddressDescriptor, error)
GetAddrDescFromAddress(address string) (AddressDescriptor, error)
GetAddressesFromAddrDesc(addrDesc AddressDescriptor) ([]string, bool, error)
GetScriptFromAddrDesc(addrDesc AddressDescriptor) ([]byte, error)
IsAddrDescIndexable(addrDesc AddressDescriptor) bool
// transactions
PackedTxidLen() int
PackTxid(txid string) ([]byte, error)
UnpackTxid(buf []byte) (string, error)
ParseTx(b []byte) (*Tx, error)
ParseTxFromJson(json.RawMessage) (*Tx, error)
PackTx(tx *Tx, height uint32, blockTime int64) ([]byte, error)
UnpackTx(buf []byte) (*Tx, uint32, error)
GetAddrDescForUnknownInput(tx *Tx, input int) AddressDescriptor
// blocks
PackBlockHash(hash string) ([]byte, error)
UnpackBlockHash(buf []byte) (string, error)
ParseBlock(b []byte) (*Block, error)
// xpub
DerivationBasePath(xpub string) (string, error)
DeriveAddressDescriptors(xpub string, change uint32, indexes []uint32) ([]AddressDescriptor, error)
DeriveAddressDescriptorsFromTo(xpub string, change uint32, fromIndex uint32, toIndex uint32) ([]AddressDescriptor, error)
// EthereumType specific
EthereumTypeGetErc20FromTx(tx *Tx) ([]Erc20Transfer, error)
}
// Mempool defines common interface to mempool
type Mempool interface {
Resync() (int, error)
GetTransactions(address string) ([]Outpoint, error)
GetAddrDescTransactions(addrDesc AddressDescriptor) ([]Outpoint, error)
GetAllEntries() MempoolTxidEntries
GetTransactionTime(txid string) uint32
}