-
Notifications
You must be signed in to change notification settings - Fork 499
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
services/horizon/txsub: Batch status check queries for pending transactions in txsub #3563
Changes from 10 commits
cf3b722
c3f9569
e8701ab
3376a06
023c64e
fac5977
ca5e147
bda6044
714d3bd
45dfc2a
6d0e082
5e5beb3
de6ed1b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,13 +8,16 @@ import ( | |
"time" | ||
|
||
"github.com/prometheus/client_golang/prometheus" | ||
"github.com/stellar/go/services/horizon/internal/db2/history" | ||
"github.com/stellar/go/services/horizon/internal/txsub/sequence" | ||
"github.com/stellar/go/support/log" | ||
"github.com/stellar/go/xdr" | ||
) | ||
|
||
type HorizonDB interface { | ||
GetLatestHistoryLedger(ctx context.Context) (uint32, error) | ||
TransactionByHash(ctx context.Context, dest interface{}, hash string) error | ||
TransactionsByHashesSinceLedger(ctx context.Context, dest interface{}, hashes []string, sinceLedgerSeq uint32) error | ||
GetSequenceNumbers(ctx context.Context, addresses []string) (map[string]uint64, error) | ||
BeginTx(*sql.TxOptions) error | ||
Rollback() error | ||
|
@@ -304,23 +307,58 @@ func (sys *System) Tick(ctx context.Context) { | |
} | ||
} | ||
|
||
for _, hash := range sys.Pending.Pending(ctx) { | ||
tx, err := txResultByHash(ctx, db, hash) | ||
pending := sys.Pending.Pending(ctx) | ||
|
||
if err == nil { | ||
logger.WithField("hash", hash).Debug("finishing open submission") | ||
sys.Pending.Finish(ctx, hash, Result{Transaction: tx}) | ||
continue | ||
if len(pending) > 0 { | ||
latestLedger, err := db.GetLatestHistoryLedger(ctx) | ||
if err != nil { | ||
logger.WithError(err).Error("error getting latest history ledger") | ||
return | ||
} | ||
|
||
if _, ok := err.(*FailedTransactionError); ok { | ||
logger.WithField("hash", hash).Debug("finishing open submission") | ||
sys.Pending.Finish(ctx, hash, Result{Transaction: tx, Err: err}) | ||
continue | ||
var sinceLedgerSeq int32 = int32(latestLedger) | ||
bartekn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sinceLedgerSeq -= 100 | ||
bartekn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if sinceLedgerSeq < 0 { | ||
sinceLedgerSeq = 0 | ||
} | ||
|
||
if err != ErrNoResults { | ||
logger.WithStack(err).Error(err) | ||
var txs []history.Transaction | ||
err = db.TransactionsByHashesSinceLedger(ctx, &txs, pending, uint32(sinceLedgerSeq)) | ||
if err != nil && !db.NoRows(err) { | ||
logger.WithError(err).Error("error getting transactions by hashes") | ||
return | ||
} | ||
|
||
txMap := make(map[string]history.Transaction, len(txs)) | ||
for _, tx := range txs { | ||
txMap[tx.TransactionHash] = tx | ||
if tx.InnerTransactionHash.Valid { | ||
txMap[tx.InnerTransactionHash.String] = tx | ||
} | ||
} | ||
|
||
for _, hash := range pending { | ||
tx, found := txMap[hash] | ||
if !found { | ||
continue | ||
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. How come we can happily continue here? 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. Couldn't it be that the transaction is in the DB but isn't found by 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. If |
||
} | ||
_, err := txResultFromHistory(tx) | ||
|
||
if err == nil { | ||
logger.WithField("hash", hash).Debug("finishing open submission") | ||
sys.Pending.Finish(ctx, hash, Result{Transaction: tx}) | ||
continue | ||
} | ||
|
||
if _, ok := err.(*FailedTransactionError); ok { | ||
logger.WithField("hash", hash).Debug("finishing open submission") | ||
sys.Pending.Finish(ctx, hash, Result{Transaction: tx, Err: err}) | ||
continue | ||
} | ||
|
||
if err != nil { | ||
logger.WithStack(err).Error(err) | ||
} | ||
} | ||
} | ||
|
||
|
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.
why is it necessary to add the
ht.ledger_sequence >= sinceLedgerSeq
condition? I thought the transaction hash is globally unique?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.
Unfortunately the query without the
ledger_sequence
limit is extremely slow. I realized it after to.mer tested it and added a fix in e8701ab. Technically the 100 ledgers is too much becauseTransactionsByHashesSinceLedger
is used only when checking the status of transactions inTick
so this could be 12 (one minute of ledgers).