-
Notifications
You must be signed in to change notification settings - Fork 20
Make accounter schedule transactions explicitly #17
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
This should: a) simplify backend logic. There are now AddrRequest<->AddrResponses and TxRequest<->TxResponses pipelines. Backends don't have to track transactions that are seen in order to avoid sending duplicate entries to the accounter. b) make sure accounter stops when all the transactions are received from the backend. The accounter keeps track of derived and processed addresses. It can now see how many transactions each address has and then schedule those transactions accordingly with the backend. Then it knows, how many (non-duplicate) transactions it has to receive before completing the fetchTransactions step and moving to processing all the transaction information.
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,10 +34,12 @@ type Accounter struct { | |
deriver *deriver.AddressDeriver | ||
lookahead uint32 | ||
|
||
countMu sync.Mutex // protects lastAddresses, derivedCount and checkedCount | ||
lastAddresses [2]uint32 | ||
derivedCount uint32 | ||
checkedCount uint32 | ||
countMu sync.Mutex // protects lastAddresses, derivedAddrCount and processedAddrCount | ||
lastAddresses [2]uint32 | ||
derivedAddrCount uint32 | ||
processedAddrCount uint32 | ||
seenTxCount uint32 | ||
processedTxCount uint32 | ||
|
||
addrResponses <-chan *backend.AddrResponse | ||
txResponses <-chan *backend.TxResponse | ||
|
@@ -112,10 +114,12 @@ func (a *Accounter) processTransactions() { | |
for hash, tx := range a.transactions { | ||
// remove transactions which are too recent | ||
if tx.height > int64(a.blockHeight) { | ||
reporter.GetInstance().Logf("transaction %s has height %d > BLOCK HEIGHT (%d)", hash, tx.height, a.blockHeight) | ||
delete(a.transactions, hash) | ||
} | ||
// remove transactions which haven't been mined | ||
if tx.height <= 0 { | ||
reporter.GetInstance().Logf("transaction %s has not been mined, yet (height=%d)", hash, tx.height) | ||
delete(a.transactions, hash) | ||
} | ||
} | ||
|
@@ -223,7 +227,7 @@ func (a *Accounter) sendWork() { | |
// increment the number of addresses which have been derived | ||
addr := a.deriver.Derive(change, indexes[change]) | ||
a.countMu.Lock() | ||
a.derivedCount++ | ||
a.derivedAddrCount++ | ||
a.countMu.Unlock() | ||
a.backend.AddrRequest(addr) | ||
indexes[change]++ | ||
|
@@ -248,15 +252,24 @@ func (a *Accounter) recvWork() { | |
reporter.GetInstance().IncAddressesFetched() | ||
|
||
a.countMu.Lock() | ||
a.checkedCount++ | ||
a.processedAddrCount++ | ||
a.countMu.Unlock() | ||
|
||
a.addresses[resp.Address.Script()] = address{ | ||
path: resp.Address, | ||
txHashes: resp.TxHashes, | ||
} | ||
|
||
reporter.GetInstance().Log(fmt.Sprintf("address %s has %d transactions", resp.Address, len(resp.TxHashes))) | ||
a.countMu.Lock() | ||
for _, txHash := range resp.TxHashes { | ||
if _, exists := a.transactions[txHash]; !exists { | ||
a.backend.TxRequest(txHash) | ||
a.seenTxCount++ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you want to increment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes. sloppy coding 😅 |
||
} | ||
} | ||
a.countMu.Unlock() | ||
|
||
reporter.GetInstance().Logf("address %s has %d transactions", resp.Address, len(resp.TxHashes)) | ||
|
||
if resp.HasTransactions() { | ||
a.countMu.Lock() | ||
|
@@ -272,6 +285,10 @@ func (a *Accounter) recvWork() { | |
|
||
reporter.GetInstance().IncTxFetched() | ||
|
||
a.countMu.Lock() | ||
a.processedTxCount++ | ||
a.countMu.Unlock() | ||
|
||
tx := transaction{ | ||
height: resp.Height, | ||
hex: resp.Hex, | ||
|
@@ -303,6 +320,10 @@ func (a *Accounter) complete() bool { | |
defer a.countMu.Unlock() | ||
|
||
// We are done when the right number of addresses were scheduled, fetched and processed | ||
// *and* all the transactions that were seen have been scheduled, fetched and processed. | ||
indexes := a.lastAddresses[0] + a.lastAddresses[1] | ||
return a.derivedCount == indexes && a.checkedCount == indexes | ||
addrsDone := a.derivedAddrCount == indexes && a.processedAddrCount == indexes | ||
txsDone := a.seenTxCount == a.processedTxCount | ||
|
||
return addrsDone && txsDone | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,7 @@ import ( | |
type Backend interface { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we'll have to eventually update the comment above this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you mostly addressed the comment for the Backend interface in other PRs, right? |
||
AddrRequest(addr *deriver.Address) | ||
AddrResponses() <-chan *AddrResponse | ||
TxRequest(txHash string) | ||
TxResponses() <-chan *TxResponse | ||
|
||
ChainHeight() uint32 | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could use a single sync.Wg for all the backend channels here. Increment it before we write to any channel, decrement it when we read data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would this give us anything useful? We keep generating more addresses, so at some point WaitGroup can be done, but there might be more data in-flight. Maybe there's an elegant solution I cannot yet see 🤔