From 2ecd29b78b1293a7753435db7dff485701406d01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=B6ckli?= Date: Fri, 31 May 2024 15:07:44 +0200 Subject: [PATCH 1/2] Del block processing function returns affected rows --- internal/blocktx/peer_handler.go | 8 +- internal/blocktx/server.go | 19 +- internal/blocktx/store/blocktx_store_mock.go | 12 +- internal/blocktx/store/interface.go | 4 +- .../blocktx/store/postgresql/clear_data.go | 4 +- .../blocktx/store/postgresql/postgres_test.go | 4 +- .../store/postgresql/set_block_processing.go | 9 +- .../k8s_watcher/mock/blocktx_client_mock.go | 6 +- internal/k8s_watcher/watcher.go | 12 +- internal/k8s_watcher/watcher_test.go | 4 +- pkg/blocktx/blocktx_api/blocktx_api.pb.go | 165 +++++++++--------- pkg/blocktx/blocktx_api/blocktx_api.proto | 12 +- .../blocktx_api/blocktx_api_grpc.pb.go | 40 ++--- pkg/blocktx/client.go | 10 +- pkg/blocktx/client_test.go | 19 +- pkg/blocktx/mocks/blocktx_api_mock.go | 24 +-- 16 files changed, 176 insertions(+), 176 deletions(-) diff --git a/internal/blocktx/peer_handler.go b/internal/blocktx/peer_handler.go index 17643464c..6d0f1d3f5 100644 --- a/internal/blocktx/peer_handler.go +++ b/internal/blocktx/peer_handler.go @@ -483,7 +483,7 @@ func (ph *PeerHandler) HandleBlock(wireMsg wire.Message, _ p2p.PeerI) error { blockId, err := ph.insertBlock(ctx, &blockHash, &merkleRoot, &previousBlockHash, msg.Height) if err != nil { - errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) + _, errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) if errDel != nil { ph.logger.Error("failed to delete block processing - after inserting block failed", slog.String("hash", blockHash.String()), slog.String("err", errDel.Error())) } @@ -493,7 +493,7 @@ func (ph *PeerHandler) HandleBlock(wireMsg wire.Message, _ p2p.PeerI) error { calculatedMerkleTree := buildMerkleTreeStoreChainHash(ctx, msg.TransactionHashes) if !merkleRoot.IsEqual(calculatedMerkleTree[len(calculatedMerkleTree)-1]) { - errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) + _, errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) if errDel != nil { ph.logger.Error("failed to delete block processing - after merkle root mismatch", slog.String("hash", blockHash.String()), slog.String("err", errDel.Error())) } @@ -501,7 +501,7 @@ func (ph *PeerHandler) HandleBlock(wireMsg wire.Message, _ p2p.PeerI) error { } if err = ph.markTransactionsAsMined(ctx, blockId, calculatedMerkleTree, msg.Height, &blockHash); err != nil { - errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) + _, errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) if errDel != nil { ph.logger.Error("failed to delete block processing - after marking transactions as mined failed", slog.String("hash", blockHash.String()), slog.String("err", errDel.Error())) } @@ -518,7 +518,7 @@ func (ph *PeerHandler) HandleBlock(wireMsg wire.Message, _ p2p.PeerI) error { } if err = ph.markBlockAsProcessed(ctx, block); err != nil { - errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) + _, errDel := ph.store.DelBlockProcessing(ctx, &blockHash, ph.hostname) if errDel != nil { ph.logger.Error("failed to delete block processing - after marking block as processed failed", slog.String("hash", blockHash.String()), slog.String("err", errDel.Error())) } diff --git a/internal/blocktx/server.go b/internal/blocktx/server.go index 6bc631a63..40276fa09 100644 --- a/internal/blocktx/server.go +++ b/internal/blocktx/server.go @@ -81,32 +81,35 @@ func (s *Server) Health(_ context.Context, _ *emptypb.Empty) (*blocktx_api.Healt }, nil } -func (s *Server) ClearTransactions(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.ClearDataResponse, error) { +func (s *Server) ClearTransactions(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.RowsAffectedResponse, error) { return s.store.ClearBlocktxTable(ctx, clearData.GetRetentionDays(), "transactions") } -func (s *Server) ClearBlocks(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.ClearDataResponse, error) { +func (s *Server) ClearBlocks(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.RowsAffectedResponse, error) { return s.store.ClearBlocktxTable(ctx, clearData.GetRetentionDays(), "blocks") } -func (s *Server) ClearBlockTransactionsMap(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.ClearDataResponse, error) { +func (s *Server) ClearBlockTransactionsMap(ctx context.Context, clearData *blocktx_api.ClearData) (*blocktx_api.RowsAffectedResponse, error) { return s.store.ClearBlocktxTable(ctx, clearData.GetRetentionDays(), "block_transactions_map") } -func (s *Server) DelUnfinishedBlockProcessing(ctx context.Context, req *blocktx_api.DelUnfinishedBlockProcessingRequest) (*emptypb.Empty, error) { +func (s *Server) DelUnfinishedBlockProcessing(ctx context.Context, req *blocktx_api.DelUnfinishedBlockProcessingRequest) (*blocktx_api.RowsAffectedResponse, error) { bhs, err := s.store.GetBlockHashesProcessingInProgress(ctx, req.GetProcessedBy()) if err != nil { - return &emptypb.Empty{}, err + return &blocktx_api.RowsAffectedResponse{}, err } + var rowsTotal int64 for _, bh := range bhs { - err = s.store.DelBlockProcessing(ctx, bh, req.GetProcessedBy()) + rows, err := s.store.DelBlockProcessing(ctx, bh, req.GetProcessedBy()) if err != nil { - return &emptypb.Empty{}, err + return &blocktx_api.RowsAffectedResponse{}, err } + + rowsTotal += rows } - return &emptypb.Empty{}, nil + return &blocktx_api.RowsAffectedResponse{Rows: rowsTotal}, nil } func (s *Server) VerifyMerkleRoots(ctx context.Context, req *blocktx_api.MerkleRootsVerificationRequest) (*blocktx_api.MerkleRootVerificationResponse, error) { diff --git a/internal/blocktx/store/blocktx_store_mock.go b/internal/blocktx/store/blocktx_store_mock.go index 0a57aa673..ce3ea8a20 100644 --- a/internal/blocktx/store/blocktx_store_mock.go +++ b/internal/blocktx/store/blocktx_store_mock.go @@ -20,13 +20,13 @@ var _ BlocktxStore = &BlocktxStoreMock{} // // // make and configure a mocked BlocktxStore // mockedBlocktxStore := &BlocktxStoreMock{ -// ClearBlocktxTableFunc: func(ctx context.Context, retentionDays int32, table string) (*blocktx_api.ClearDataResponse, error) { +// ClearBlocktxTableFunc: func(ctx context.Context, retentionDays int32, table string) (*blocktx_api.RowsAffectedResponse, error) { // panic("mock out the ClearBlocktxTable method") // }, // CloseFunc: func() error { // panic("mock out the Close method") // }, -// DelBlockProcessingFunc: func(ctx context.Context, hash *chainhash.Hash, processedBy string) error { +// DelBlockProcessingFunc: func(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) { // panic("mock out the DelBlockProcessing method") // }, // GetBlockGapsFunc: func(ctx context.Context, heightRange int) ([]*BlockGap, error) { @@ -67,13 +67,13 @@ var _ BlocktxStore = &BlocktxStoreMock{} // } type BlocktxStoreMock struct { // ClearBlocktxTableFunc mocks the ClearBlocktxTable method. - ClearBlocktxTableFunc func(ctx context.Context, retentionDays int32, table string) (*blocktx_api.ClearDataResponse, error) + ClearBlocktxTableFunc func(ctx context.Context, retentionDays int32, table string) (*blocktx_api.RowsAffectedResponse, error) // CloseFunc mocks the Close method. CloseFunc func() error // DelBlockProcessingFunc mocks the DelBlockProcessing method. - DelBlockProcessingFunc func(ctx context.Context, hash *chainhash.Hash, processedBy string) error + DelBlockProcessingFunc func(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) // GetBlockGapsFunc mocks the GetBlockGaps method. GetBlockGapsFunc func(ctx context.Context, heightRange int) ([]*BlockGap, error) @@ -225,7 +225,7 @@ type BlocktxStoreMock struct { } // ClearBlocktxTable calls ClearBlocktxTableFunc. -func (mock *BlocktxStoreMock) ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.ClearDataResponse, error) { +func (mock *BlocktxStoreMock) ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.RowsAffectedResponse, error) { if mock.ClearBlocktxTableFunc == nil { panic("BlocktxStoreMock.ClearBlocktxTableFunc: method is nil but BlocktxStore.ClearBlocktxTable was just called") } @@ -292,7 +292,7 @@ func (mock *BlocktxStoreMock) CloseCalls() []struct { } // DelBlockProcessing calls DelBlockProcessingFunc. -func (mock *BlocktxStoreMock) DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) error { +func (mock *BlocktxStoreMock) DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) { if mock.DelBlockProcessingFunc == nil { panic("BlocktxStoreMock.DelBlockProcessingFunc: method is nil but BlocktxStore.DelBlockProcessing was just called") } diff --git a/internal/blocktx/store/interface.go b/internal/blocktx/store/interface.go index 7d4cdee39..1ba564db2 100644 --- a/internal/blocktx/store/interface.go +++ b/internal/blocktx/store/interface.go @@ -20,12 +20,12 @@ type BlocktxStore interface { UpsertBlockTransactions(ctx context.Context, blockId uint64, transactions []*blocktx_api.TransactionAndSource, merklePaths []string) (registeredTxs []UpsertBlockTransactionsResult, err error) MarkBlockAsDone(ctx context.Context, hash *chainhash.Hash, size uint64, txCount uint64) error GetBlockGaps(ctx context.Context, heightRange int) ([]*BlockGap, error) - ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.ClearDataResponse, error) + ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.RowsAffectedResponse, error) GetMinedTransactions(ctx context.Context, hashes []*chainhash.Hash) ([]GetMinedTransactionResult, error) SetBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) (string, error) GetBlockHashesProcessingInProgress(ctx context.Context, processedBy string) ([]*chainhash.Hash, error) - DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) error + DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) VerifyMerkleRoots(ctx context.Context, merkleRoots []*blocktx_api.MerkleRootVerificationRequest, maxAllowedBlockHeightMismatch int) (*blocktx_api.MerkleRootVerificationResponse, error) Ping(ctx context.Context) error diff --git a/internal/blocktx/store/postgresql/clear_data.go b/internal/blocktx/store/postgresql/clear_data.go index 94fd865a5..38f9b606a 100644 --- a/internal/blocktx/store/postgresql/clear_data.go +++ b/internal/blocktx/store/postgresql/clear_data.go @@ -13,7 +13,7 @@ const ( numericalDateHourLayout = "2006010215" ) -func (p *PostgreSQL) ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.ClearDataResponse, error) { +func (p *PostgreSQL) ClearBlocktxTable(ctx context.Context, retentionDays int32, table string) (*blocktx_api.RowsAffectedResponse, error) { now := p.now() deleteBeforeDate := now.Add(-24 * time.Hour * time.Duration(retentionDays)) @@ -28,5 +28,5 @@ func (p *PostgreSQL) ClearBlocktxTable(ctx context.Context, retentionDays int32, return nil, fmt.Errorf("unable to delete rows: %v", err) } rows, _ := res.RowsAffected() - return &blocktx_api.ClearDataResponse{Rows: rows}, nil + return &blocktx_api.RowsAffectedResponse{Rows: rows}, nil } diff --git a/internal/blocktx/store/postgresql/postgres_test.go b/internal/blocktx/store/postgresql/postgres_test.go index 008c9dcb5..24f406974 100644 --- a/internal/blocktx/store/postgresql/postgres_test.go +++ b/internal/blocktx/store/postgresql/postgres_test.go @@ -367,10 +367,10 @@ func TestPostgresDB(t *testing.T) { require.Len(t, blockHashes, 1) require.True(t, bhInProgress.IsEqual(blockHashes[0])) - err = postgresDB.DelBlockProcessing(ctx, bhInProgress, "pod-1") + _, err = postgresDB.DelBlockProcessing(ctx, bhInProgress, "pod-1") require.ErrorIs(t, err, store.ErrBlockNotFound) - err = postgresDB.DelBlockProcessing(ctx, bhInProgress, "pod-2") + _, err = postgresDB.DelBlockProcessing(ctx, bhInProgress, "pod-2") require.NoError(t, err) blockHashes, err = postgresDB.GetBlockHashesProcessingInProgress(ctx, "pod-2") diff --git a/internal/blocktx/store/postgresql/set_block_processing.go b/internal/blocktx/store/postgresql/set_block_processing.go index 143c4e42b..21362cc6d 100644 --- a/internal/blocktx/store/postgresql/set_block_processing.go +++ b/internal/blocktx/store/postgresql/set_block_processing.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "github.com/bitcoin-sv/arc/internal/blocktx/store" "github.com/lib/pq" "github.com/libsv/go-p2p/chaincfg/chainhash" @@ -38,7 +37,7 @@ func (p *PostgreSQL) SetBlockProcessing(ctx context.Context, hash *chainhash.Has return processedBy, nil } -func (p *PostgreSQL) DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) error { +func (p *PostgreSQL) DelBlockProcessing(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) { if tracer != nil { var span trace.Span ctx, span = tracer.Start(ctx, "InsertBlock") @@ -51,14 +50,14 @@ func (p *PostgreSQL) DelBlockProcessing(ctx context.Context, hash *chainhash.Has res, err := p.db.ExecContext(ctx, q, hash[:], processedBy) if err != nil { - return err + return 0, err } rowsAffected, _ := res.RowsAffected() if rowsAffected != 1 { - return store.ErrBlockNotFound + return 0, store.ErrBlockNotFound } - return nil + return rowsAffected, nil } func (p *PostgreSQL) GetBlockHashesProcessingInProgress(ctx context.Context, processedBy string) ([]*chainhash.Hash, error) { diff --git a/internal/k8s_watcher/mock/blocktx_client_mock.go b/internal/k8s_watcher/mock/blocktx_client_mock.go index 5c76d8646..c7326a437 100644 --- a/internal/k8s_watcher/mock/blocktx_client_mock.go +++ b/internal/k8s_watcher/mock/blocktx_client_mock.go @@ -28,7 +28,7 @@ var _ blocktx.BlocktxClient = &BlocktxClientMock{} // ClearTransactionsFunc: func(ctx context.Context, retentionDays int32) (int64, error) { // panic("mock out the ClearTransactions method") // }, -// DelUnfinishedBlockProcessingFunc: func(ctx context.Context, processedBy string) error { +// DelUnfinishedBlockProcessingFunc: func(ctx context.Context, processedBy string) (int64, error) { // panic("mock out the DelUnfinishedBlockProcessing method") // }, // HealthFunc: func(ctx context.Context) error { @@ -54,7 +54,7 @@ type BlocktxClientMock struct { ClearTransactionsFunc func(ctx context.Context, retentionDays int32) (int64, error) // DelUnfinishedBlockProcessingFunc mocks the DelUnfinishedBlockProcessing method. - DelUnfinishedBlockProcessingFunc func(ctx context.Context, processedBy string) error + DelUnfinishedBlockProcessingFunc func(ctx context.Context, processedBy string) (int64, error) // HealthFunc mocks the Health method. HealthFunc func(ctx context.Context) error @@ -222,7 +222,7 @@ func (mock *BlocktxClientMock) ClearTransactionsCalls() []struct { } // DelUnfinishedBlockProcessing calls DelUnfinishedBlockProcessingFunc. -func (mock *BlocktxClientMock) DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) error { +func (mock *BlocktxClientMock) DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) (int64, error) { if mock.DelUnfinishedBlockProcessingFunc == nil { panic("BlocktxClientMock.DelUnfinishedBlockProcessingFunc: method is nil but BlocktxClient.DelUnfinishedBlockProcessing was just called") } diff --git a/internal/k8s_watcher/watcher.go b/internal/k8s_watcher/watcher.go index 7cd807197..a09fdae06 100644 --- a/internal/k8s_watcher/watcher.go +++ b/internal/k8s_watcher/watcher.go @@ -154,12 +154,12 @@ func (c *Watcher) watchBlocktx() { break retryLoop } - err = c.blocktxClient.DelUnfinishedBlockProcessing(ctx, podName) + rows, err := c.blocktxClient.DelUnfinishedBlockProcessing(ctx, podName) if err != nil { c.logger.Error("Failed to delete unfinished block processing", slog.String("pod-name", podName), slog.String("err", err.Error())) continue } - c.logger.Info("Deleted unfinished block processing", slog.String("pod-name", podName)) + c.logger.Info("Deleted unfinished block processing", slog.Int64("rows-affected", rows), slog.String("pod-name", podName)) break } } @@ -210,16 +210,16 @@ func (c *Watcher) watchMetamorph() { i++ if i > maxRetries { - c.logger.Error(fmt.Sprintf("failed to unlock metamorph records after %d retries", maxRetries), slog.String("pod-name", podName)) + c.logger.Error(fmt.Sprintf("Failed to unlock metamorph records after %d retries", maxRetries), slog.String("pod-name", podName)) break retryLoop } - resp, err := c.metamorphClient.SetUnlockedByName(ctx, podName) + rows, err := c.metamorphClient.SetUnlockedByName(ctx, podName) if err != nil { - c.logger.Error("failed to unlock metamorph records", slog.String("pod-name", podName), slog.String("err", err.Error())) + c.logger.Error("Failed to unlock metamorph records", slog.String("pod-name", podName), slog.String("err", err.Error())) continue } - c.logger.Info("records unlocked", slog.Int64("rows-affected", resp), slog.String("pod-name", podName)) + c.logger.Info("Records unlocked", slog.Int64("rows-affected", rows), slog.String("pod-name", podName)) break } } diff --git a/internal/k8s_watcher/watcher_test.go b/internal/k8s_watcher/watcher_test.go index 90fc841f1..14ba659f4 100644 --- a/internal/k8s_watcher/watcher_test.go +++ b/internal/k8s_watcher/watcher_test.go @@ -161,9 +161,7 @@ func TestStartBlocktxWatcher(t *testing.T) { t.Run(tc.name, func(t *testing.T) { metamorphMock := &mock.TransactionMaintainerMock{} blocktxMock := &mock.BlocktxClientMock{ - DelUnfinishedBlockProcessingFunc: func(ctx context.Context, processedBy string) error { - return nil - }, + DelUnfinishedBlockProcessingFunc: func(ctx context.Context, processedBy string) (int64, error) { return 0, nil }, } iteration := 0 diff --git a/pkg/blocktx/blocktx_api/blocktx_api.pb.go b/pkg/blocktx/blocktx_api/blocktx_api.pb.go index d990637fa..3b49e2978 100644 --- a/pkg/blocktx/blocktx_api/blocktx_api.pb.go +++ b/pkg/blocktx/blocktx_api/blocktx_api.pb.go @@ -444,8 +444,8 @@ func (x *ClearData) GetRetentionDays() int32 { return 0 } -// swagger:model ClearDataResponse -type ClearDataResponse struct { +// swagger:model RowsAffectedResponse +type RowsAffectedResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -453,8 +453,8 @@ type ClearDataResponse struct { Rows int64 `protobuf:"varint,1,opt,name=rows,proto3" json:"rows,omitempty"` } -func (x *ClearDataResponse) Reset() { - *x = ClearDataResponse{} +func (x *RowsAffectedResponse) Reset() { + *x = RowsAffectedResponse{} if protoimpl.UnsafeEnabled { mi := &file_pkg_blocktx_blocktx_api_blocktx_api_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -462,13 +462,13 @@ func (x *ClearDataResponse) Reset() { } } -func (x *ClearDataResponse) String() string { +func (x *RowsAffectedResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ClearDataResponse) ProtoMessage() {} +func (*RowsAffectedResponse) ProtoMessage() {} -func (x *ClearDataResponse) ProtoReflect() protoreflect.Message { +func (x *RowsAffectedResponse) ProtoReflect() protoreflect.Message { mi := &file_pkg_blocktx_blocktx_api_blocktx_api_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -480,12 +480,12 @@ func (x *ClearDataResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ClearDataResponse.ProtoReflect.Descriptor instead. -func (*ClearDataResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use RowsAffectedResponse.ProtoReflect.Descriptor instead. +func (*RowsAffectedResponse) Descriptor() ([]byte, []int) { return file_pkg_blocktx_blocktx_api_blocktx_api_proto_rawDescGZIP(), []int{7} } -func (x *ClearDataResponse) GetRows() int64 { +func (x *RowsAffectedResponse) GetRows() int64 { if x != nil { return x.Rows } @@ -800,73 +800,74 @@ var file_pkg_blocktx_blocktx_api_blocktx_api_proto_rawDesc = []byte{ 0x22, 0x31, 0x0a, 0x09, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x79, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x44, - 0x61, 0x79, 0x73, 0x22, 0x27, 0x0a, 0x11, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x22, 0x42, 0x0a, 0x14, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, 0x64, 0x53, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x22, 0x48, 0x0a, 0x23, 0x44, 0x65, 0x6c, 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, - 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x79, 0x22, 0x63, 0x0a, 0x1d, 0x4d, 0x65, - 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, - 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, - 0x6f, 0x0a, 0x1e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x4d, 0x0a, 0x0c, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, - 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0b, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, - 0x22, 0x5a, 0x0a, 0x1e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x56, 0x65, - 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x04, 0x52, 0x16, 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, - 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x32, 0x99, 0x04, 0x0a, - 0x0a, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x78, 0x41, 0x50, 0x49, 0x12, 0x3f, 0x0a, 0x06, 0x48, - 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1b, 0x2e, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4d, 0x0a, 0x11, - 0x43, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, - 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x1e, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x0b, 0x43, - 0x6c, 0x65, 0x61, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, + 0x61, 0x79, 0x73, 0x22, 0x2a, 0x0a, 0x14, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x72, + 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x22, + 0x42, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x6e, + 0x64, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x22, 0x48, 0x0a, 0x23, 0x44, 0x65, 0x6c, 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, + 0x73, 0x68, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x42, 0x79, 0x22, 0x63, 0x0a, + 0x1d, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, + 0x0a, 0x0b, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, + 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x22, 0x6f, 0x0a, 0x1e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, + 0x73, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x0c, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, + 0x6f, 0x6f, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b, 0x6d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, + 0x6f, 0x74, 0x73, 0x22, 0x5a, 0x0a, 0x1e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, + 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x18, 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x04, 0x52, 0x16, 0x75, 0x6e, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x32, + 0xad, 0x04, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x78, 0x41, 0x50, 0x49, 0x12, 0x3f, + 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1b, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x48, + 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x50, 0x0a, 0x11, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x21, 0x2e, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x4a, 0x0a, 0x0b, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x73, + 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, + 0x19, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x61, 0x70, 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, - 0x74, 0x61, 0x1a, 0x1e, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, - 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x19, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x4d, 0x61, - 0x70, 0x12, 0x16, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, - 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x1e, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x44, 0x61, 0x74, - 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x1c, 0x44, - 0x65, 0x6c, 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, - 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x2e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x55, 0x6e, 0x66, - 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x6f, 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x79, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x12, 0x2b, 0x2e, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, - 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, - 0x6f, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x74, 0x61, 0x1a, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, + 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x75, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x55, 0x6e, + 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x12, 0x30, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, + 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x55, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x77, 0x73, 0x41, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6f, + 0x0a, 0x11, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, + 0x6f, 0x74, 0x73, 0x12, 0x2b, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, + 0x69, 0x2e, 0x4d, 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x73, 0x56, 0x65, 0x72, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, 0x2e, 0x4d, + 0x65, 0x72, 0x6b, 0x6c, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, + 0x0f, 0x5a, 0x0d, 0x2e, 0x3b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x74, 0x78, 0x5f, 0x61, 0x70, 0x69, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -890,7 +891,7 @@ var file_pkg_blocktx_blocktx_api_blocktx_api_proto_goTypes = []interface{}{ (*TransactionBlocks)(nil), // 4: blocktx_api.TransactionBlocks (*Transaction)(nil), // 5: blocktx_api.Transaction (*ClearData)(nil), // 6: blocktx_api.ClearData - (*ClearDataResponse)(nil), // 7: blocktx_api.ClearDataResponse + (*RowsAffectedResponse)(nil), // 7: blocktx_api.RowsAffectedResponse (*TransactionAndSource)(nil), // 8: blocktx_api.TransactionAndSource (*DelUnfinishedBlockProcessingRequest)(nil), // 9: blocktx_api.DelUnfinishedBlockProcessingRequest (*MerkleRootVerificationRequest)(nil), // 10: blocktx_api.MerkleRootVerificationRequest @@ -911,10 +912,10 @@ var file_pkg_blocktx_blocktx_api_blocktx_api_proto_depIdxs = []int32{ 9, // 8: blocktx_api.BlockTxAPI.DelUnfinishedBlockProcessing:input_type -> blocktx_api.DelUnfinishedBlockProcessingRequest 11, // 9: blocktx_api.BlockTxAPI.VerifyMerkleRoots:input_type -> blocktx_api.MerkleRootsVerificationRequest 0, // 10: blocktx_api.BlockTxAPI.Health:output_type -> blocktx_api.HealthResponse - 7, // 11: blocktx_api.BlockTxAPI.ClearTransactions:output_type -> blocktx_api.ClearDataResponse - 7, // 12: blocktx_api.BlockTxAPI.ClearBlocks:output_type -> blocktx_api.ClearDataResponse - 7, // 13: blocktx_api.BlockTxAPI.ClearBlockTransactionsMap:output_type -> blocktx_api.ClearDataResponse - 14, // 14: blocktx_api.BlockTxAPI.DelUnfinishedBlockProcessing:output_type -> google.protobuf.Empty + 7, // 11: blocktx_api.BlockTxAPI.ClearTransactions:output_type -> blocktx_api.RowsAffectedResponse + 7, // 12: blocktx_api.BlockTxAPI.ClearBlocks:output_type -> blocktx_api.RowsAffectedResponse + 7, // 13: blocktx_api.BlockTxAPI.ClearBlockTransactionsMap:output_type -> blocktx_api.RowsAffectedResponse + 7, // 14: blocktx_api.BlockTxAPI.DelUnfinishedBlockProcessing:output_type -> blocktx_api.RowsAffectedResponse 12, // 15: blocktx_api.BlockTxAPI.VerifyMerkleRoots:output_type -> blocktx_api.MerkleRootVerificationResponse 10, // [10:16] is the sub-list for method output_type 4, // [4:10] is the sub-list for method input_type @@ -1014,7 +1015,7 @@ func file_pkg_blocktx_blocktx_api_blocktx_api_proto_init() { } } file_pkg_blocktx_blocktx_api_blocktx_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ClearDataResponse); i { + switch v := v.(*RowsAffectedResponse); i { case 0: return &v.state case 1: diff --git a/pkg/blocktx/blocktx_api/blocktx_api.proto b/pkg/blocktx/blocktx_api/blocktx_api.proto index 2c0486190..a02194a6f 100644 --- a/pkg/blocktx/blocktx_api/blocktx_api.proto +++ b/pkg/blocktx/blocktx_api/blocktx_api.proto @@ -12,16 +12,16 @@ service BlockTxAPI { rpc Health (google.protobuf.Empty) returns (HealthResponse) {} // ClearTransactions clears transaction data - rpc ClearTransactions(ClearData) returns (ClearDataResponse) {} + rpc ClearTransactions(ClearData) returns (RowsAffectedResponse) {} // ClearBlocks clears block data - rpc ClearBlocks(ClearData) returns (ClearDataResponse) {} + rpc ClearBlocks(ClearData) returns (RowsAffectedResponse) {} // ClearBlockTransactionsMap clears block-transaction-map data - rpc ClearBlockTransactionsMap(ClearData) returns (ClearDataResponse) {} + rpc ClearBlockTransactionsMap(ClearData) returns (RowsAffectedResponse) {} // DelUnfinishedBlockProcessing deletes unfinished block processing - rpc DelUnfinishedBlockProcessing(DelUnfinishedBlockProcessingRequest) returns (google.protobuf.Empty) {} + rpc DelUnfinishedBlockProcessing(DelUnfinishedBlockProcessingRequest) returns (RowsAffectedResponse) {} // VerifyMerkleRoots verifies the merkle roots existance in blocktx db and returns unverified block heights rpc VerifyMerkleRoots(MerkleRootsVerificationRequest) returns (MerkleRootVerificationResponse) {} @@ -71,8 +71,8 @@ message ClearData { int32 retentionDays = 1; } -// swagger:model ClearDataResponse -message ClearDataResponse { +// swagger:model RowsAffectedResponse +message RowsAffectedResponse { int64 rows = 1; } diff --git a/pkg/blocktx/blocktx_api/blocktx_api_grpc.pb.go b/pkg/blocktx/blocktx_api/blocktx_api_grpc.pb.go index 8fd379b94..743852b0a 100644 --- a/pkg/blocktx/blocktx_api/blocktx_api_grpc.pb.go +++ b/pkg/blocktx/blocktx_api/blocktx_api_grpc.pb.go @@ -35,13 +35,13 @@ type BlockTxAPIClient interface { // Health returns the health of the API. Health(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*HealthResponse, error) // ClearTransactions clears transaction data - ClearTransactions(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) + ClearTransactions(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) // ClearBlocks clears block data - ClearBlocks(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) + ClearBlocks(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) // ClearBlockTransactionsMap clears block-transaction-map data - ClearBlockTransactionsMap(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) + ClearBlockTransactionsMap(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) // DelUnfinishedBlockProcessing deletes unfinished block processing - DelUnfinishedBlockProcessing(ctx context.Context, in *DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DelUnfinishedBlockProcessing(ctx context.Context, in *DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*RowsAffectedResponse, error) // VerifyMerkleRoots verifies the merkle roots existance in blocktx db and returns unverified block heights VerifyMerkleRoots(ctx context.Context, in *MerkleRootsVerificationRequest, opts ...grpc.CallOption) (*MerkleRootVerificationResponse, error) } @@ -63,8 +63,8 @@ func (c *blockTxAPIClient) Health(ctx context.Context, in *emptypb.Empty, opts . return out, nil } -func (c *blockTxAPIClient) ClearTransactions(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) { - out := new(ClearDataResponse) +func (c *blockTxAPIClient) ClearTransactions(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) { + out := new(RowsAffectedResponse) err := c.cc.Invoke(ctx, BlockTxAPI_ClearTransactions_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -72,8 +72,8 @@ func (c *blockTxAPIClient) ClearTransactions(ctx context.Context, in *ClearData, return out, nil } -func (c *blockTxAPIClient) ClearBlocks(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) { - out := new(ClearDataResponse) +func (c *blockTxAPIClient) ClearBlocks(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) { + out := new(RowsAffectedResponse) err := c.cc.Invoke(ctx, BlockTxAPI_ClearBlocks_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -81,8 +81,8 @@ func (c *blockTxAPIClient) ClearBlocks(ctx context.Context, in *ClearData, opts return out, nil } -func (c *blockTxAPIClient) ClearBlockTransactionsMap(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*ClearDataResponse, error) { - out := new(ClearDataResponse) +func (c *blockTxAPIClient) ClearBlockTransactionsMap(ctx context.Context, in *ClearData, opts ...grpc.CallOption) (*RowsAffectedResponse, error) { + out := new(RowsAffectedResponse) err := c.cc.Invoke(ctx, BlockTxAPI_ClearBlockTransactionsMap_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -90,8 +90,8 @@ func (c *blockTxAPIClient) ClearBlockTransactionsMap(ctx context.Context, in *Cl return out, nil } -func (c *blockTxAPIClient) DelUnfinishedBlockProcessing(ctx context.Context, in *DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *blockTxAPIClient) DelUnfinishedBlockProcessing(ctx context.Context, in *DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*RowsAffectedResponse, error) { + out := new(RowsAffectedResponse) err := c.cc.Invoke(ctx, BlockTxAPI_DelUnfinishedBlockProcessing_FullMethodName, in, out, opts...) if err != nil { return nil, err @@ -115,13 +115,13 @@ type BlockTxAPIServer interface { // Health returns the health of the API. Health(context.Context, *emptypb.Empty) (*HealthResponse, error) // ClearTransactions clears transaction data - ClearTransactions(context.Context, *ClearData) (*ClearDataResponse, error) + ClearTransactions(context.Context, *ClearData) (*RowsAffectedResponse, error) // ClearBlocks clears block data - ClearBlocks(context.Context, *ClearData) (*ClearDataResponse, error) + ClearBlocks(context.Context, *ClearData) (*RowsAffectedResponse, error) // ClearBlockTransactionsMap clears block-transaction-map data - ClearBlockTransactionsMap(context.Context, *ClearData) (*ClearDataResponse, error) + ClearBlockTransactionsMap(context.Context, *ClearData) (*RowsAffectedResponse, error) // DelUnfinishedBlockProcessing deletes unfinished block processing - DelUnfinishedBlockProcessing(context.Context, *DelUnfinishedBlockProcessingRequest) (*emptypb.Empty, error) + DelUnfinishedBlockProcessing(context.Context, *DelUnfinishedBlockProcessingRequest) (*RowsAffectedResponse, error) // VerifyMerkleRoots verifies the merkle roots existance in blocktx db and returns unverified block heights VerifyMerkleRoots(context.Context, *MerkleRootsVerificationRequest) (*MerkleRootVerificationResponse, error) mustEmbedUnimplementedBlockTxAPIServer() @@ -134,16 +134,16 @@ type UnimplementedBlockTxAPIServer struct { func (UnimplementedBlockTxAPIServer) Health(context.Context, *emptypb.Empty) (*HealthResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Health not implemented") } -func (UnimplementedBlockTxAPIServer) ClearTransactions(context.Context, *ClearData) (*ClearDataResponse, error) { +func (UnimplementedBlockTxAPIServer) ClearTransactions(context.Context, *ClearData) (*RowsAffectedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ClearTransactions not implemented") } -func (UnimplementedBlockTxAPIServer) ClearBlocks(context.Context, *ClearData) (*ClearDataResponse, error) { +func (UnimplementedBlockTxAPIServer) ClearBlocks(context.Context, *ClearData) (*RowsAffectedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ClearBlocks not implemented") } -func (UnimplementedBlockTxAPIServer) ClearBlockTransactionsMap(context.Context, *ClearData) (*ClearDataResponse, error) { +func (UnimplementedBlockTxAPIServer) ClearBlockTransactionsMap(context.Context, *ClearData) (*RowsAffectedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method ClearBlockTransactionsMap not implemented") } -func (UnimplementedBlockTxAPIServer) DelUnfinishedBlockProcessing(context.Context, *DelUnfinishedBlockProcessingRequest) (*emptypb.Empty, error) { +func (UnimplementedBlockTxAPIServer) DelUnfinishedBlockProcessing(context.Context, *DelUnfinishedBlockProcessingRequest) (*RowsAffectedResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DelUnfinishedBlockProcessing not implemented") } func (UnimplementedBlockTxAPIServer) VerifyMerkleRoots(context.Context, *MerkleRootsVerificationRequest) (*MerkleRootVerificationResponse, error) { diff --git a/pkg/blocktx/client.go b/pkg/blocktx/client.go index 8dfd8d5ac..63e3fdb4d 100644 --- a/pkg/blocktx/client.go +++ b/pkg/blocktx/client.go @@ -14,7 +14,7 @@ type BlocktxClient interface { ClearTransactions(ctx context.Context, retentionDays int32) (int64, error) ClearBlocks(ctx context.Context, retentionDays int32) (int64, error) ClearBlockTransactionsMap(ctx context.Context, retentionDays int32) (int64, error) - DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) error + DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) (int64, error) VerifyMerkleRoots(ctx context.Context, merkleRootVerificationRequest []MerkleRootVerificationRequest) ([]uint64, error) } @@ -50,12 +50,12 @@ func (btc *Client) Health(ctx context.Context) error { return nil } -func (btc *Client) DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) error { - _, err := btc.client.DelUnfinishedBlockProcessing(ctx, &blocktx_api.DelUnfinishedBlockProcessingRequest{ProcessedBy: processedBy}) +func (btc *Client) DelUnfinishedBlockProcessing(ctx context.Context, processedBy string) (int64, error) { + resp, err := btc.client.DelUnfinishedBlockProcessing(ctx, &blocktx_api.DelUnfinishedBlockProcessingRequest{ProcessedBy: processedBy}) if err != nil { - return err + return 0, err } - return nil + return resp.Rows, nil } func (btc *Client) ClearTransactions(ctx context.Context, retentionDays int32) (int64, error) { diff --git a/pkg/blocktx/client_test.go b/pkg/blocktx/client_test.go index f21d2e5ea..fa78fc66d 100644 --- a/pkg/blocktx/client_test.go +++ b/pkg/blocktx/client_test.go @@ -10,7 +10,6 @@ import ( "github.com/bitcoin-sv/arc/pkg/blocktx/mocks" "github.com/stretchr/testify/require" "google.golang.org/grpc" - "google.golang.org/protobuf/types/known/emptypb" ) //go:generate moq -pkg mocks -out ./mocks/blocktx_api_mock.go ./blocktx_api BlockTxAPIClient @@ -36,13 +35,13 @@ func TestClient_DelUnfinishedBlockProcessing(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { apiClient := &mocks.BlockTxAPIClientMock{ - DelUnfinishedBlockProcessingFunc: func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - return &emptypb.Empty{}, tc.delErr + DelUnfinishedBlockProcessingFunc: func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { + return &blocktx_api.RowsAffectedResponse{}, tc.delErr }, } client := blocktx.NewClient(apiClient) - err := client.DelUnfinishedBlockProcessing(context.Background(), "test-1") + _, err := client.DelUnfinishedBlockProcessing(context.Background(), "test-1") if tc.expectedErrorStr == "" { require.NoError(t, err) } else { @@ -74,8 +73,8 @@ func TestClient_ClearBlocks(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { apiClient := &mocks.BlockTxAPIClientMock{ - ClearBlocksFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { - return &blocktx_api.ClearDataResponse{Rows: 5}, tc.clearErr + ClearBlocksFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { + return &blocktx_api.RowsAffectedResponse{Rows: 5}, tc.clearErr }, } client := blocktx.NewClient(apiClient) @@ -114,8 +113,8 @@ func TestClient_ClearTransactions(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { apiClient := &mocks.BlockTxAPIClientMock{ - ClearTransactionsFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { - return &blocktx_api.ClearDataResponse{Rows: 5}, tc.clearErr + ClearTransactionsFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { + return &blocktx_api.RowsAffectedResponse{Rows: 5}, tc.clearErr }, } client := blocktx.NewClient(apiClient) @@ -154,8 +153,8 @@ func TestClient_ClearBlockTransactionsMap(t *testing.T) { for _, tc := range tt { t.Run(tc.name, func(t *testing.T) { apiClient := &mocks.BlockTxAPIClientMock{ - ClearBlockTransactionsMapFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { - return &blocktx_api.ClearDataResponse{Rows: 5}, tc.clearErr + ClearBlockTransactionsMapFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { + return &blocktx_api.RowsAffectedResponse{Rows: 5}, tc.clearErr }, } client := blocktx.NewClient(apiClient) diff --git a/pkg/blocktx/mocks/blocktx_api_mock.go b/pkg/blocktx/mocks/blocktx_api_mock.go index 778085259..2d20bc1d1 100644 --- a/pkg/blocktx/mocks/blocktx_api_mock.go +++ b/pkg/blocktx/mocks/blocktx_api_mock.go @@ -21,16 +21,16 @@ var _ blocktx_api.BlockTxAPIClient = &BlockTxAPIClientMock{} // // // make and configure a mocked blocktx_api.BlockTxAPIClient // mockedBlockTxAPIClient := &BlockTxAPIClientMock{ -// ClearBlockTransactionsMapFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +// ClearBlockTransactionsMapFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { // panic("mock out the ClearBlockTransactionsMap method") // }, -// ClearBlocksFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +// ClearBlocksFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { // panic("mock out the ClearBlocks method") // }, -// ClearTransactionsFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +// ClearTransactionsFunc: func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { // panic("mock out the ClearTransactions method") // }, -// DelUnfinishedBlockProcessingFunc: func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { +// DelUnfinishedBlockProcessingFunc: func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { // panic("mock out the DelUnfinishedBlockProcessing method") // }, // HealthFunc: func(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*blocktx_api.HealthResponse, error) { @@ -47,16 +47,16 @@ var _ blocktx_api.BlockTxAPIClient = &BlockTxAPIClientMock{} // } type BlockTxAPIClientMock struct { // ClearBlockTransactionsMapFunc mocks the ClearBlockTransactionsMap method. - ClearBlockTransactionsMapFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) + ClearBlockTransactionsMapFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) // ClearBlocksFunc mocks the ClearBlocks method. - ClearBlocksFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) + ClearBlocksFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) // ClearTransactionsFunc mocks the ClearTransactions method. - ClearTransactionsFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) + ClearTransactionsFunc func(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) // DelUnfinishedBlockProcessingFunc mocks the DelUnfinishedBlockProcessing method. - DelUnfinishedBlockProcessingFunc func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) + DelUnfinishedBlockProcessingFunc func(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) // HealthFunc mocks the Health method. HealthFunc func(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*blocktx_api.HealthResponse, error) @@ -130,7 +130,7 @@ type BlockTxAPIClientMock struct { } // ClearBlockTransactionsMap calls ClearBlockTransactionsMapFunc. -func (mock *BlockTxAPIClientMock) ClearBlockTransactionsMap(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +func (mock *BlockTxAPIClientMock) ClearBlockTransactionsMap(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { if mock.ClearBlockTransactionsMapFunc == nil { panic("BlockTxAPIClientMock.ClearBlockTransactionsMapFunc: method is nil but BlockTxAPIClient.ClearBlockTransactionsMap was just called") } @@ -170,7 +170,7 @@ func (mock *BlockTxAPIClientMock) ClearBlockTransactionsMapCalls() []struct { } // ClearBlocks calls ClearBlocksFunc. -func (mock *BlockTxAPIClientMock) ClearBlocks(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +func (mock *BlockTxAPIClientMock) ClearBlocks(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { if mock.ClearBlocksFunc == nil { panic("BlockTxAPIClientMock.ClearBlocksFunc: method is nil but BlockTxAPIClient.ClearBlocks was just called") } @@ -210,7 +210,7 @@ func (mock *BlockTxAPIClientMock) ClearBlocksCalls() []struct { } // ClearTransactions calls ClearTransactionsFunc. -func (mock *BlockTxAPIClientMock) ClearTransactions(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.ClearDataResponse, error) { +func (mock *BlockTxAPIClientMock) ClearTransactions(ctx context.Context, in *blocktx_api.ClearData, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { if mock.ClearTransactionsFunc == nil { panic("BlockTxAPIClientMock.ClearTransactionsFunc: method is nil but BlockTxAPIClient.ClearTransactions was just called") } @@ -250,7 +250,7 @@ func (mock *BlockTxAPIClientMock) ClearTransactionsCalls() []struct { } // DelUnfinishedBlockProcessing calls DelUnfinishedBlockProcessingFunc. -func (mock *BlockTxAPIClientMock) DelUnfinishedBlockProcessing(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { +func (mock *BlockTxAPIClientMock) DelUnfinishedBlockProcessing(ctx context.Context, in *blocktx_api.DelUnfinishedBlockProcessingRequest, opts ...grpc.CallOption) (*blocktx_api.RowsAffectedResponse, error) { if mock.DelUnfinishedBlockProcessingFunc == nil { panic("BlockTxAPIClientMock.DelUnfinishedBlockProcessingFunc: method is nil but BlockTxAPIClient.DelUnfinishedBlockProcessing was just called") } From 73c3192cc16a628097adc6807f86985eed2492e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=B6ckli?= Date: Fri, 7 Jun 2024 18:02:08 +0200 Subject: [PATCH 2/2] Add unit test --- internal/blocktx/server_test.go | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/internal/blocktx/server_test.go b/internal/blocktx/server_test.go index 59e0c606f..125c7d254 100644 --- a/internal/blocktx/server_test.go +++ b/internal/blocktx/server_test.go @@ -1,12 +1,17 @@ package blocktx import ( + "context" + "errors" "log/slog" "os" "testing" "time" "github.com/bitcoin-sv/arc/internal/blocktx/store" + "github.com/bitcoin-sv/arc/internal/testdata" + "github.com/bitcoin-sv/arc/pkg/blocktx/blocktx_api" + "github.com/libsv/go-p2p/chaincfg/chainhash" "github.com/stretchr/testify/require" ) @@ -36,3 +41,64 @@ func TestStartGRPCServer(t *testing.T) { }) } } + +func TestDelUnfinishedBlock(t *testing.T) { + tt := []struct { + name string + getBlockHashesProcessingInProgressErr error + delBlockProcessingErr error + + expectedRows int64 + expectedErrorStr string + }{ + { + name: "success", + + expectedRows: 6, + }, + { + name: "error - getBlockHashesProcessingInProgress", + getBlockHashesProcessingInProgressErr: errors.New("failed to get block hashes processing in progress"), + + expectedErrorStr: "failed to get block hashes processing in progress", + expectedRows: 0, + }, + { + name: "error - delBlockProcessingErr", + delBlockProcessingErr: errors.New("failed to delete block processing error"), + + expectedErrorStr: "failed to delete block processing error", + expectedRows: 0, + }, + } + + for _, tc := range tt { + t.Run(tc.name, func(t *testing.T) { + logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) + storeMock := &store.BlocktxStoreMock{ + GetBlockHashesProcessingInProgressFunc: func(ctx context.Context, processedBy string) ([]*chainhash.Hash, error) { + return []*chainhash.Hash{testdata.TX1Hash, testdata.TX2Hash}, tc.getBlockHashesProcessingInProgressErr + }, + + DelBlockProcessingFunc: func(ctx context.Context, hash *chainhash.Hash, processedBy string) (int64, error) { + return 3, tc.delBlockProcessingErr + }, + } + + server := NewServer(storeMock, logger, nil, 0) + + resp, err := server.DelUnfinishedBlockProcessing(context.Background(), &blocktx_api.DelUnfinishedBlockProcessingRequest{ + ProcessedBy: "host", + }) + + if tc.expectedErrorStr == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, tc.expectedErrorStr) + return + } + + require.Equal(t, tc.expectedRows, resp.Rows) + }) + } +}