forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
206 lines (178 loc) · 5.99 KB
/
main.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
// Package core contains database record definitions useable for
// reading rows from a Stellar Core db
package core
import (
"github.com/guregu/null"
"github.com/stellar/go/strkey"
"github.com/stellar/go/support/db"
"github.com/stellar/go/xdr"
)
// Account is a row of data from the `accounts` table
type Account struct {
Accountid string
Balance xdr.Int64
Seqnum string
Numsubentries int32
Inflationdest null.String
HomeDomain null.String
Thresholds xdr.Thresholds
Flags xdr.AccountFlags
}
// AccountData is a row of data from the `accountdata` table
type AccountData struct {
Accountid string
Key string `db:"dataname"`
Value string `db:"datavalue"`
}
// LedgerHeader is row of data from the `ledgerheaders` table
type LedgerHeader struct {
LedgerHash string `db:"ledgerhash"`
PrevHash string `db:"prevhash"`
BucketListHash string `db:"bucketlisthash"`
CloseTime int64 `db:"closetime"`
Sequence uint32 `db:"ledgerseq"`
Data xdr.LedgerHeader `db:"data"`
}
// Offer is row of data from the `offers` table from stellar-core
type Offer struct {
SellerID string `db:"sellerid"`
OfferID int64 `db:"offerid"`
SellingAssetType xdr.AssetType `db:"sellingassettype"`
SellingAssetCode null.String `db:"sellingassetcode"`
SellingIssuer null.String `db:"sellingissuer"`
BuyingAssetType xdr.AssetType `db:"buyingassettype"`
BuyingAssetCode null.String `db:"buyingassetcode"`
BuyingIssuer null.String `db:"buyingissuer"`
Amount xdr.Int64 `db:"amount"`
Pricen int32 `db:"pricen"`
Priced int32 `db:"priced"`
Price float64 `db:"price"`
Flags int32 `db:"flags"`
Lastmodified int32 `db:"lastmodified"`
}
// OrderBookSummaryPriceLevel is a collapsed view of multiple offers at the same price that
// contains the summed amount from all the member offers. Used by OrderBookSummary
type OrderBookSummaryPriceLevel struct {
Type string `db:"type"`
PriceLevel
}
// OrderBookSummary is a summary of a set of offers for a given base and
// counter currency
type OrderBookSummary []OrderBookSummaryPriceLevel
// Q is a helper struct on which to hang common queries against a stellar
// core database.
type Q struct {
*db.Session
}
// PriceLevel represents an aggregation of offers to trade at a certain
// price.
type PriceLevel struct {
Pricen int32 `db:"pricen"`
Priced int32 `db:"priced"`
Pricef float64 `db:"pricef"`
Amount int64 `db:"amount"`
}
// SequenceProvider implements `txsub.SequenceProvider`
type SequenceProvider struct {
Q *Q
}
// Signer is a row of data from the `signers` table from stellar-core
type Signer struct {
Accountid string
Publickey string
Weight int32
}
// Transaction is row of data from the `txhistory` table from stellar-core
type Transaction struct {
TransactionHash string `db:"txid"`
LedgerSequence int32 `db:"ledgerseq"`
Index int32 `db:"txindex"`
Envelope xdr.TransactionEnvelope `db:"txbody"`
Result xdr.TransactionResultPair `db:"txresult"`
ResultMeta xdr.TransactionMeta `db:"txmeta"`
}
// TransactionFee is row of data from the `txfeehistory` table from stellar-core
type TransactionFee struct {
TransactionHash string `db:"txid"`
LedgerSequence int32 `db:"ledgerseq"`
Index int32 `db:"txindex"`
Changes xdr.LedgerEntryChanges `db:"txchanges"`
}
// Trustline is a row of data from the `trustlines` table from stellar-core
type Trustline struct {
Accountid string
Assettype xdr.AssetType
Issuer string
Assetcode string
Tlimit xdr.Int64
Balance xdr.Int64
Flags int32
}
// AssetFromDB produces an xdr.Asset by combining the constituent type, code and
// issuer, as often retrieved from the DB in 3 separate columns.
func AssetFromDB(typ xdr.AssetType, code string, issuer string) (result xdr.Asset, err error) {
switch typ {
case xdr.AssetTypeAssetTypeNative:
result, err = xdr.NewAsset(xdr.AssetTypeAssetTypeNative, nil)
case xdr.AssetTypeAssetTypeCreditAlphanum4:
var (
an xdr.AssetAlphaNum4
decoded []byte
pkey xdr.Uint256
)
copy(an.AssetCode[:], []byte(code))
decoded, err = strkey.Decode(strkey.VersionByteAccountID, issuer)
if err != nil {
return
}
copy(pkey[:], decoded)
an.Issuer, err = xdr.NewAccountId(xdr.PublicKeyTypePublicKeyTypeEd25519, pkey)
if err != nil {
return
}
result, err = xdr.NewAsset(xdr.AssetTypeAssetTypeCreditAlphanum4, an)
case xdr.AssetTypeAssetTypeCreditAlphanum12:
var (
an xdr.AssetAlphaNum12
decoded []byte
pkey xdr.Uint256
)
copy(an.AssetCode[:], []byte(code))
decoded, err = strkey.Decode(strkey.VersionByteAccountID, issuer)
if err != nil {
return
}
copy(pkey[:], decoded)
an.Issuer, err = xdr.NewAccountId(xdr.PublicKeyTypePublicKeyTypeEd25519, pkey)
if err != nil {
return
}
result, err = xdr.NewAsset(xdr.AssetTypeAssetTypeCreditAlphanum12, an)
}
return
}
// ElderLedger represents the oldest "ingestable" ledger known to the
// stellar-core database this ingestion system is communicating with. Horizon,
// which wants to operate on a contiguous range of ledger data (i.e. free from
// gaps) uses the elder ledger to start importing in the case of an empty
// database. NOTE: This current query used is correct, but slow. Please keep
// this query out of latency sensitive or frequently trafficked code paths.
func (q *Q) ElderLedger(dest *int32) error {
err := q.GetRaw(dest, `
SELECT COALESCE(ledgerseq, 0)
FROM (
SELECT
ledgerseq,
LAG(ledgerseq, 1) OVER ( ORDER BY ledgerseq) as prev
FROM ledgerheaders
) seqs
WHERE COALESCE(prev, -1) < ledgerseq - 1
ORDER BY ledgerseq DESC
LIMIT 1;
`)
return err
}
// LatestLedger loads the latest known ledger
func (q *Q) LatestLedger(dest interface{}) error {
return q.GetRaw(dest, `SELECT COALESCE(MAX(ledgerseq), 0) FROM ledgerheaders`)
}