-
Notifications
You must be signed in to change notification settings - Fork 2
/
mainloop.go
306 lines (226 loc) · 8.64 KB
/
mainloop.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
297
298
299
300
301
302
303
304
305
306
package main
import (
"context"
"github.com/SomniaStellarum/StellarUtilities/slog"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"log"
"math/big"
"time"
)
const ROPSTEN_FACTORY_ADDRESS = "0x649cc62BB1cF4F73827387D2B663d89570016673"
var cli *ethclient.Client
var (
factoryAddress common.Address
toastytradeFactory *ToastytradeFactory
)
var (
CreatedTopic common.Hash
FundsAddedTopic common.Hash
PayerStatementTopic common.Hash
WorkerStatementTopic common.Hash
FundsRecoveredTopic common.Hash
CommittedTopic common.Hash
FundsBurnedTopic common.Hash
FundsReleasedTopic common.Hash
ClaimStartedTopic common.Hash
ClaimCanceledTopic common.Hash
ClaimTriggeredTopic common.Hash
ClosedTopic common.Hash
UnclosedTopic common.Hash
)
func mainLoop(fromBlock uint64) {
slog.DebugPrint("starting eth read loop")
ctx := context.Background()
lastBlockScanned := big.NewInt(int64(fromBlock) - 1)
var queryStartBlock, queryEndBlock big.Int
for {
slog.DebugPrint("loopin")
//Set the beginning of the queried range to the block just after the last block scanned
//queryStartBlock = lastBlockScanned + 1
queryStartBlock.Add(lastBlockScanned, big.NewInt(1))
//Get latest block
block, err := cli.HeaderByNumber(ctx, nil)
if err != nil {
log.Panic("error getting block number: ", err)
}
//Set the end of the range to the latest block
//(We could use 'latest', but this way we have finer control, to make sure we aren't re-scanning blocks)
queryEndBlock = *block.Number
if queryStartBlock.Cmp(&queryEndBlock) == 1 { // If queryStartBlock > queryEndBlock
//Indicates there has been no new block since last loop. Sleep a bit and continue.
slog.DebugPrint("No new blocks, sleepin")
time.Sleep(time.Minute)
continue
}
slog.DebugPrint("Scanning block range: ", queryStartBlock, queryEndBlock)
var factoryQuery ethereum.FilterQuery
factoryQuery.FromBlock = &queryStartBlock
factoryQuery.ToBlock = &queryEndBlock
//This range will be used for both filter calls that follow in this loop.
//Get all events ToastytradeCreated events from Factory contract, and extract address of new BPs
factoryQuery.Addresses = []common.Address{factoryAddress}
logs, err := cli.FilterLogs(ctx, factoryQuery)
if err != nil {
log.Panic("error filtering for factory events", err)
}
var newToastytradeAddresses []common.Address
for _, log := range logs {
event := new(ToastytradeFactoryToastytradeCreated)
toastytradeFactory.ToastytradeFactoryFilterer.contract.UnpackLog(event, "ToastytradeCreated", log)
newToastytradeAddresses = append(newToastytradeAddresses, event.ToastytradeAddress)
}
slog.DebugPrint("TTs from Factory: ", len(newToastytradeAddresses))
//Additionally fetch all already-cached BP addresses from DB
getAllToastytradeAddressesReqChan <- true
result := <-getAllToastytradeAddressesResChan
if result.err != nil {
log.Panic(result.err)
}
ttAddressesFromDB := result.addresses
slog.DebugPrint("TTs from DB: ", len(ttAddressesFromDB))
//Concacenate the DB's adddresses and those from the newly-created BPs.
toastytradeAddresses := append(ttAddressesFromDB, newToastytradeAddresses...)
//create toastytradeContract instances to use their filterer in the next loop
toastytradeContracts := make(map[common.Address]*BurnablePayment)
for _, addr := range toastytradeAddresses {
contract, err := NewBurnablePayment(addr, cli)
if err != nil {
log.Panic("error creating toastytrade @ ", addr.Hex())
}
toastytradeContracts[addr] = contract
}
//now deal with each new event from each toastytrade
var ttQuery ethereum.FilterQuery
ttQuery.Addresses = toastytradeAddresses
ttQuery.FromBlock = &queryStartBlock
ttQuery.ToBlock = &queryEndBlock
logs, err = cli.FilterLogs(ctx, ttQuery)
if err != nil {
log.Panic("error filtering for toastytrade events: ", err)
}
for _, thisLog := range logs {
addr := thisLog.Address
switch thisLog.Topics[0] {
case CreatedTopic:
slog.DebugPrint("Created event found")
//decode event
event := new(BurnablePaymentCreated)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "Created", thisLog)
ttEntry := new(toastytradeEntry)
ttEntry.Seller = event.Creator
state, _, _, _, balance, commitThreshold, _, _, _, autoreleaseInterval, _, err := toastytradeContracts[addr].BurnablePaymentCaller.GetFullState(nil)
if err != nil {
log.Panic("error calling bp.getFullState: ", err)
}
ttEntry.State = state
ttEntry.Balance = *balance
ttEntry.CommitThreshold = *commitThreshold
ttEntry.AutoreleaseInterval = *autoreleaseInterval
createdUpdate := new(createdUpdate)
createdUpdate.ttAddr = addr
createdUpdate.entry = ttEntry
createdUpdateChan <- createdUpdate
err = notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case FundsRecoveredTopic:
slog.DebugPrint("FundsRecovered topic found")
event := new(BurnablePaymentFundsRecovered)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "FundsRecovered", thisLog)
fundsRecoveredUpdate := new(noArgUpdate)
fundsRecoveredUpdate.ttAddr = addr
fundsRecoveredUpdateChan <- fundsRecoveredUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case CommittedTopic:
slog.DebugPrint("Committed event found")
event := new(BurnablePaymentCommitted)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "Committed", thisLog)
committedUpdate := new(committedUpdate)
committedUpdate.ttAddr = addr
committedUpdate.buyerAddr = event.Committer
committedUpdateChan <- committedUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case FundsBurnedTopic:
slog.DebugPrint("FundsBurned event found")
event := new(BurnablePaymentFundsBurned)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "FundsBurned", thisLog)
fundsBurnedUpdate := new(fundsBurnedUpdate)
fundsBurnedUpdate.ttAddr = addr
fundsBurnedUpdate.amount = *event.Amount
fundsBurnedUpdateChan <- fundsBurnedUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case FundsReleasedTopic:
slog.DebugPrint("FundsReleased event found")
event := new(BurnablePaymentFundsReleased)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "FundsReleased", thisLog)
fundsReleasedUpdate := new(fundsReleasedUpdate)
fundsReleasedUpdate.ttAddr = addr
fundsReleasedUpdate.amount = *event.Amount
fundsReleasedUpdateChan <- fundsReleasedUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case ClaimStartedTopic:
slog.DebugPrint("ClaimStarted event found")
event := new(BurnablePaymentClaimStarted)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "ClaimStarted", thisLog)
claimStartedUpdate := new(noArgUpdate)
claimStartedUpdate.ttAddr = addr
claimStartedUpdateChan <- claimStartedUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case ClaimCanceledTopic:
slog.DebugPrint("ClaimCanceled event found")
event := new(BurnablePaymentClaimCanceled)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "ClaimCanceled", thisLog)
claimCanceledUpdate := new(noArgUpdate)
claimCanceledUpdate.ttAddr = addr
claimCanceledUpdateChan <- claimCanceledUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case ClaimTriggeredTopic:
slog.DebugPrint("ClaimTriggered event found")
event := new(BurnablePaymentClaimTriggered)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "ClaimTriggered", thisLog)
claimTriggeredUpdate := new(noArgUpdate)
claimTriggeredUpdate.ttAddr = addr
claimTriggeredUpdateChan <- claimTriggeredUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
case ClosedTopic:
slog.DebugPrint("Closed event found")
event := new(BurnablePaymentClosed)
toastytradeContracts[addr].BurnablePaymentFilterer.contract.UnpackLog(event, "Closed", thisLog)
closedUpdate := new(noArgUpdate)
closedUpdate.ttAddr = addr
closedUpdateChan <- closedUpdate
err := notifyParties(addr, event)
if err != nil {
log.Panic(err)
}
}
}
lastBlockScanned.Set(&queryEndBlock)
slog.DebugPrint("sleepin")
time.Sleep(time.Minute)
}
}