From ce9f960188c3843c0e684c5c0a308937aa75e1be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=B6ckli?= Date: Thu, 14 Dec 2023 09:44:25 +0100 Subject: [PATCH] Check if any unmined transactions have been mined which are not older than 20min --- metamorph/processor.go | 11 ++++++----- metamorph/processor_test.go | 31 +++++++++++++------------------ testdata/data.go | 3 +++ 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/metamorph/processor.go b/metamorph/processor.go index 507093446..ca10d7b99 100644 --- a/metamorph/processor.go +++ b/metamorph/processor.go @@ -26,7 +26,7 @@ import ( ) const ( - // number of times we will retry announcing transaction if we haven't seen it on the network + // MaxRetries number of times we will retry announcing transaction if we haven't seen it on the network MaxRetries = 15 // length of interval for checking transactions if they are seen on the network // if not we resend them again for a few times @@ -37,6 +37,7 @@ const ( failedToUpdateStatus = "Failed to update status" dataRetentionPeriodDefault = 14 * 24 * time.Hour // 14 days + checkIfMinedTimeRange = time.Minute * 20 ) type Processor struct { @@ -120,7 +121,7 @@ func NewProcessor(s store.MetamorphStore, pm p2p.PeerManagerI, // Start a goroutine to resend transactions that have not been seen on the network go p.processExpiredTransactions() - go p.processExpiredSeenTransactions() + go p.processCheckIfMined() gocore.AddAppPayloadFn("mtm", func() interface{} { return p.GetStats(false) @@ -173,10 +174,10 @@ func (p *Processor) unlockItems() error { return p.store.SetUnlocked(context.Background(), hashes) } -func (p *Processor) processExpiredSeenTransactions() { - // filterFunc returns true if the transaction has not been seen on the network +func (p *Processor) processCheckIfMined() { + // filter for transactions which have been at least announced but not mined and which haven't started to be processed longer than a specified amount of time ago filterFunc := func(processorResp *processor_response.ProcessorResponse) bool { - return processorResp.GetStatus() == metamorph_api.Status_SEEN_ON_NETWORK && p.now().Sub(processorResp.Start) > p.processExpiredSeenTxsInterval + return (processorResp.GetStatus() != metamorph_api.Status_MINED && processorResp.GetStatus() != metamorph_api.Status_CONFIRMED) && p.now().Sub(processorResp.Start) < checkIfMinedTimeRange } // Check transactions that have been seen on the network, but haven't been marked as mined diff --git a/metamorph/processor_test.go b/metamorph/processor_test.go index df4818772..b1a8fd328 100644 --- a/metamorph/processor_test.go +++ b/metamorph/processor_test.go @@ -705,7 +705,7 @@ func BenchmarkProcessTransaction(b *testing.B) { time.Sleep(1 * time.Second) } -func TestProcessExpiredSeenTransactions(t *testing.T) { +func TestProcessCheckIfMined(t *testing.T) { txsBlocks := []*blocktx_api.TransactionBlock{ { BlockHash: testdata.Block1Hash[:], @@ -730,22 +730,19 @@ func TestProcessExpiredSeenTransactions(t *testing.T) { getTransactionBlocksErr error updateMinedErr error - expectedNrOfUpdates int - expectedNrOfBlockTxRequests int + expectedNrOfUpdates int }{ { - name: "expired seen txs", + name: "expired txs", blocks: txsBlocks, - expectedNrOfUpdates: 3, - expectedNrOfBlockTxRequests: 1, + expectedNrOfUpdates: 3, }, { name: "failed to get transaction blocks", getTransactionBlocksErr: errors.New("failed to get transaction blocks"), - expectedNrOfUpdates: 0, - expectedNrOfBlockTxRequests: 1, + expectedNrOfUpdates: 0, }, { name: "failed to parse block hash", @@ -753,16 +750,14 @@ func TestProcessExpiredSeenTransactions(t *testing.T) { BlockHash: []byte("not a valid block hash"), }}, - expectedNrOfUpdates: 0, - expectedNrOfBlockTxRequests: 1, + expectedNrOfUpdates: 0, }, { name: "failed to update mined", blocks: txsBlocks, updateMinedErr: errors.New("failed to update mined"), - expectedNrOfUpdates: 3, - expectedNrOfBlockTxRequests: 1, + expectedNrOfUpdates: 3, }, { name: "failed to get tx from response map", @@ -770,12 +765,11 @@ func TestProcessExpiredSeenTransactions(t *testing.T) { { BlockHash: testdata.Block1Hash[:], BlockHeight: 1234, - TransactionHash: testdata.TX4Hash[:], + TransactionHash: testdata.TX5Hash[:], }, }, - expectedNrOfUpdates: 0, - expectedNrOfBlockTxRequests: 1, + expectedNrOfUpdates: 0, }, } @@ -813,14 +807,15 @@ func TestProcessExpiredSeenTransactions(t *testing.T) { require.Equal(t, 0, processor.ProcessorResponseMap.Len()) - processor.ProcessorResponseMap.Set(testdata.TX1Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX1Hash, metamorph_api.Status_SEEN_ON_NETWORK)) + processor.ProcessorResponseMap.Set(testdata.TX1Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX1Hash, metamorph_api.Status_STORED)) processor.ProcessorResponseMap.Set(testdata.TX2Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX2Hash, metamorph_api.Status_SEEN_ON_NETWORK)) - processor.ProcessorResponseMap.Set(testdata.TX3Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX3Hash, metamorph_api.Status_SEEN_ON_NETWORK)) + processor.ProcessorResponseMap.Set(testdata.TX3Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX3Hash, metamorph_api.Status_REJECTED)) + processor.ProcessorResponseMap.Set(testdata.TX4Hash, processor_response.NewProcessorResponseWithStatus(testdata.TX4Hash, metamorph_api.Status_MINED)) time.Sleep(25 * time.Millisecond) require.Equal(t, tc.expectedNrOfUpdates, len(metamorphStore.UpdateMinedCalls())) - require.Equal(t, tc.expectedNrOfBlockTxRequests, len(btxMock.GetTransactionBlocksCalls())) + require.Equal(t, 1, len(btxMock.GetTransactionBlocksCalls())) }) } } diff --git a/testdata/data.go b/testdata/data.go index ee32dc9dc..49f04490d 100644 --- a/testdata/data.go +++ b/testdata/data.go @@ -27,6 +27,9 @@ var ( TX4 = "88eab41a8d0b7b4bc395f8f988ea3d6e63c8bc339526fd2f00cb7ce6fd7df0f7" TX4Hash, _ = chainhash.NewHashFromStr(TX4) + TX5 = "df931ab7d4ff0bbf96ff186f221c466f09c052c5331733641040defabf9dcd93" + TX5Hash, _ = chainhash.NewHashFromStr(TX5) + Time = time.Date(2009, 1, 03, 18, 15, 05, 0, time.UTC) DefaultPolicy = `{"excessiveblocksize":2000000000,"blockmaxsize":512000000,"maxtxsizepolicy":10000000,"maxorphantxsize":1000000000,"datacarriersize":4294967295,"maxscriptsizepolicy":500000,"maxopsperscriptpolicy":4294967295,"maxscriptnumlengthpolicy":10000,"maxpubkeyspermultisigpolicy":4294967295,"maxtxsigopscountspolicy":4294967295,"maxstackmemoryusagepolicy":100000000,"maxstackmemoryusageconsensus":200000000,"limitancestorcount":10000,"limitcpfpgroupmemberscount":25,"maxmempool":2000000000,"maxmempoolsizedisk":0,"mempoolmaxpercentcpfp":10,"acceptnonstdoutputs":true,"datacarrier":true,"minminingtxfee":5e-7,"maxstdtxvalidationduration":3,"maxnonstdtxvalidationduration":1000,"maxtxchainvalidationbudget":50,"validationclockcpu":true,"minconsolidationfactor":20,"maxconsolidationinputscriptsize":150,"minconfconsolidationinput":6,"minconsolidationinputmaturity":6,"acceptnonstdconsolidationinput":false}` )