From 6dc4aa9956d355ed7182a285c94340ca9d6fadd8 Mon Sep 17 00:00:00 2001 From: 0xluk Date: Wed, 6 Mar 2024 17:52:58 +0200 Subject: [PATCH] fixed bug where nothing was save if the quorum had an empty tick data; added send_signed_tx rpc --- README.md | 139 +++++++++++++++-- docker-compose.yml | 43 +++++ main.go | 9 +- processor/processor.go | 5 + protobuff/archive.pb.go | 278 ++++++++++++++++++++++++--------- protobuff/archive.pb.gw.go | 85 ++++++++++ protobuff/archive.proto | 9 ++ protobuff/archive_grpc.pb.go | 37 +++++ rpc/rpc_server.go | 47 ++++-- store/store.go | 2 - validator/quorum/validation.go | 32 ++-- validator/tick/models.go | 3 + validator/validator.go | 6 +- 13 files changed, 580 insertions(+), 115 deletions(-) create mode 100644 docker-compose.yml diff --git a/README.md b/README.md index 167ac68..342cd78 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,133 @@ -## Docker usage: -When running the docker container, you need to specify the following environment variables: -- `QUBIC_ARCHIVER_QUBIC_NODE_IP` - the IP address of the Qubic node that archiver will connect to -- `QUBIC_ARCHIVER_QUBIC_FALLBACK_TICK` - the start tick for the archiver to start archiving from (needs to be from current epoch) +## High level description: +The archive system consists of two services: +- `qubic-archiver` - the archiver processor and HTTP server that provides rpc endpoints to query the archiver +- `qubic-node-fetcher` - a service that is starting from a reliable node, gather the peers by "walking" from peer to peer and then filters them out so they don't have more than 30 ticks behind. This service is also exposing an http server for the qubic-archiver to retrieve the reliable peers + +## IMPORTANT +Before starting the system, open the `docker-compose.yml` file and make sure that there is a reliable peer as a starting point for the node fetcher. It's defined in the `NODE_FETCHER_QUBIC_STARTING_PEER_IP` environment variable. + +## Run with docker-compose: +```bash +$ docker-compose up -d +``` + +## Available endpoints: + +### GetTickTransactions: +```bash +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTickTransactions -d '{"tickNumber": 12795663}' +{ + "transactions": [ + { + "sourceId": "PJUMDQZEAEDZNFAXATGGYGJULKGALYFCBYUAZRGAHGPXCDBDGEJOMKOFSKKD", + "destId": "AFZPUAIYVPNUYGJRQVLUKOPPVLHAZQTGLYAAUUNBXFTVTAMSBKQBLEIEPCVJ", + "amount": "0", + "tickNumber": 12795663, + "inputType": 0, + "inputSize": 32, + "inputHex": "716c692d637564614dfd03e48d610cd450b590e835155b6b9f55f91c516428b4", + "signatureHex": "1e597cb8f834797a2b58e8178f7f18219db4797e803277632299ebdc222a4e5194037c29d8dd87c2f8cebdf8dfb30f34b175e37565f8b01d059dc71cc1342200", + "txId": "qbrdxsmlfggneflkbskpqwjeqhgdssfuabhfapywobqcilroobgvruseuerk" + } + ] +} +``` +### GetTickData +```bash +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTickData -d '{"tickNumber": 12795663}' +{ + "tickData": { + "computorIndex": 335, + "epoch": 99, + "tickNumber": 12795663, + "timestamp": "1709731981000", + "varStruct": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + "timeLock": "Nd5Fn0wHnQmcar+qphSK5ucbEtg/gkY82ffWs4HBbkk=", + "transactionIds": [ + "qbrdxsmlfggneflkbskpqwjeqhgdssfuabhfapywobqcilroobgvruseuerk" + ], + "contractFees": [], + "signatureHex": "4aef8b84c2b594331eae649722ed747fa01a69b37e38538a0e3257c8f739950c7c7433d22d6fe77231972d51927fb29b3b4cc6dc9b202e609d42e5eddafe1c00" + } +} +``` + +### GetTransaction +```bash +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTransaction -d '{"txId": "qbrdxsmlfggneflkbskpqwjeqhgdssfuabhfapywobqcilroobgvruseuerk"}' +{ + "transaction": { + "sourceId": "PJUMDQZEAEDZNFAXATGGYGJULKGALYFCBYUAZRGAHGPXCDBDGEJOMKOFSKKD", + "destId": "AFZPUAIYVPNUYGJRQVLUKOPPVLHAZQTGLYAAUUNBXFTVTAMSBKQBLEIEPCVJ", + "amount": "0", + "tickNumber": 12795663, + "inputType": 0, + "inputSize": 32, + "inputHex": "716c692d637564614dfd03e48d610cd450b590e835155b6b9f55f91c516428b4", + "signatureHex": "1e597cb8f834797a2b58e8178f7f18219db4797e803277632299ebdc222a4e5194037c29d8dd87c2f8cebdf8dfb30f34b175e37565f8b01d059dc71cc1342200", + "txId": "qbrdxsmlfggneflkbskpqwjeqhgdssfuabhfapywobqcilroobgvruseuerk" + } +} +``` + +### GetQuorumTickData +```bash +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetQuorumTickData -d '{"tickNumber": 12795663}' + +``` + +### Get Computors ```bash -$ docker run -p 8000:8000 -p 8001:8001 -e QUBIC_ARCHIVER_QUBIC_NODE_IP="212.51.150.253" -e QUBIC_ARCHIVER_QUBIC_FALLBACK_TICK=12543674 -v /root/store:/app/store --name qubic-archiver -d ghcr.io/qubic/qubic-archiver:latest +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetComputors -d '{"epoch": 99}' +{ + "computors": { + "epoch": 99, + "identities": [ + "9263520905f41451c102f3e4c9a2434490cd766ceaac5f03a5300f7b5a5e60c7", + "b23fc58a4371aedac687ef76c2ebc666ac554f1aee07351a9aa503b6df05ad92", + "0d6fa2d10c02f7cc33fec302bd77535d91e9c905785c6b0e7f03ef7547279174", + "e245860121add2513340b0c47df7010410120a41368dcdb5246b581f2a63d99f", + "27402616c685f579e233e64056ad5553fd475541439e68ff6587da0f9ee05e8b", + "8931ddf58887c72eb693ab866212b620d7db79ba1ec1456826d67e313c7e50c5" + ], + "signatureHex": "77d93167d5cf9ba7aca8139fcbdb0624eaf6884d7a3bb79832dc5f59131f84da55ee9e29f81cd07fae746b4b7aa055b734c58ce21c3443aef5da521903d10d00" + } +} +``` +### GetIdentityInfo +```bash +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetIdentityInfo -d '{"identity": "PJUMDQZEAEDZNFAXATGGYGJULKGALYFCBYUAZRGAHGPXCDBDGEJOMKOFSKKD"}' +{ + "identityInfo": { + "id": "PJUMDQZEAEDZNFAXATGGYGJULKGALYFCBYUAZRGAHGPXCDBDGEJOMKOFSKKD", + "tickNumber": 12797233, + "balance": "1479289941", + "incomingAmount": "4835212306297", + "outgoingAmount": "4833733016356", + "nrIncomingTransfers": 826438, + "nrOutgoingTransfers": 47187, + "latestIncomingTransferTick": 12790393, + "latestOutgoingTransferTick": 12797113, + "siblingsHex": [ + "2a5af1c66af3ef4a294e09f27aed030d3faeffb9a1910012468b9c7f3e46bd9f", + "705f57f0c8f11be888bb1e4d935a7582ca65e8212207404bc135b22a6e9bf450", + "c11fb66d62103d9a2e47b39b205354517d7014e15b6985343daec01f396da1d5", + "c6b45f22943acd48520886ccd104a580d85b41f39e803c29a8d2eeb0b0e62865" + ] + } +} ``` -## Querying the archiver +### GetLastProcessedTick ```bash -$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTickTransactions -d '{"tickNumber": 12570631}' -$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTickData -d '{"tickNumber": 12570631}' -$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetTransaction -d '{"txId": "qbizhhehgiijddcgbzdxqtkqcwuedcvgnrorvovdkavytqsukxlucyjhjxeg"}' -``` \ No newline at end of file +$ curl -sX POST http://127.0.0.1:8000/qubic.archiver.archive.pb.ArchiveService/GetLastProcessedTick +{ + "lastProcessedTick": 12797164, + "lastProcessedTicksPerEpoch": { + "99": "12797164" + } +} +``` + + + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..fe72763 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,43 @@ +version: '3' + +services: + qubic-archiver: + image: ghcr.io/qubic/qubic-archiver:v0.1.12 + container_name: qubic-archiver + ports: + - "8000:8000" + - "8001:8001" + links: + - "qubic-node-fetcher" + depends_on: + - "qubic-node-fetcher" + environment: + QUBIC_ARCHIVER_SERVER_HTTP_HOST: "0.0.0.0:8000" + QUBIC_ARCHIVER_SERVER_GRPC_HOST: "0.0.0.0:8001" + QUBIC_ARCHIVER_POOL_NODE_FETCHER_URL: "http://qubic-node-fetcher:8080/peers" + volumes: + - ./store/archiver:/app/store + networks: + - qubic + restart: always + + qubic-node-fetcher: + image: ghcr.io/qubic/go-node-fetcher:v0.1.1 + container_name: qubic-node-fetcher + ports: + - "8080:8080" + environment: + NODE_FETCHER_QUBIC_STARTING_PEER_IP: "212.51.150.253" + volumes: + - ./store/node-fetcher:/app/store + networks: + - qubic + healthcheck: + test: [ "CMD", "curl", "-f", "http://127.0.0.1:8080/peers" ] + interval: 30s + timeout: 5s + retries: 5 + restart: always + +networks: + qubic: \ No newline at end of file diff --git a/main.go b/main.go index 4896921..6daa0e9 100644 --- a/main.go +++ b/main.go @@ -43,9 +43,10 @@ func run() error { IdleTimeout time.Duration `conf:"default:15s"` } Qubic struct { - NodePort string `conf:"default:21841"` - StorageFolder string `conf:"default:store"` - ProcessTickTimeout time.Duration `conf:"default:5s"` + NodePort string `conf:"default:21841"` + StorageFolder string `conf:"default:store"` + ProcessTickTimeout time.Duration `conf:"default:5s"` + NrPeersToBroadcastTx int `conf:"default:2"` } } @@ -98,7 +99,7 @@ func run() error { return errors.Wrap(err, "creating new connection pool") } - rpcServer := rpc.NewServer(cfg.Server.GrpcHost, cfg.Server.HttpHost, ps, chPool) + rpcServer := rpc.NewServer(cfg.Server.GrpcHost, cfg.Server.HttpHost, ps, chPool, cfg.Qubic.NrPeersToBroadcastTx) rpcServer.Start() shutdown := make(chan os.Signal, 1) diff --git a/processor/processor.go b/processor/processor.go index 1782d60..04c0fd6 100644 --- a/processor/processor.go +++ b/processor/processor.go @@ -108,6 +108,8 @@ func (p *Processor) processOneByOne() error { func (p *Processor) getNextProcessingTick(ctx context.Context, currentTickInfo types.TickInfo) (uint64, error) { lastTick, err := p.ps.GetLastProcessedTick(ctx) if err != nil { + //handles first run of the archiver where there is nothing in storage + // in this case we start from the initial tick of the current epoch if errors.Is(err, store.ErrNotFound) { return uint64(currentTickInfo.InitialTick), nil } @@ -115,9 +117,12 @@ func (p *Processor) getNextProcessingTick(ctx context.Context, currentTickInfo t return 0, errors.Wrap(err, "getting last processed tick") } + //handles the case where the initial tick of epoch returned by the node is greater than the last processed tick + // which means that we are in the next epoch and we should start from the initial tick of the current epoch if uint64(currentTickInfo.InitialTick) > lastTick { return uint64(currentTickInfo.InitialTick), nil } + // otherwise we are in the same epoch and we should start from the last processed tick + 1 return lastTick + 1, nil } diff --git a/protobuff/archive.pb.go b/protobuff/archive.pb.go index 1e14467..76e4ea6 100644 --- a/protobuff/archive.pb.go +++ b/protobuff/archive.pb.go @@ -1381,6 +1381,100 @@ func (x *GetLastProcessedTickResponse) GetLastProcessedTicksPerEpoch() map[uint3 return nil } +type SendRawTransactionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SignedTx string `protobuf:"bytes,1,opt,name=signed_tx,json=signedTx,proto3" json:"signed_tx,omitempty"` +} + +func (x *SendRawTransactionRequest) Reset() { + *x = SendRawTransactionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendRawTransactionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendRawTransactionRequest) ProtoMessage() {} + +func (x *SendRawTransactionRequest) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendRawTransactionRequest.ProtoReflect.Descriptor instead. +func (*SendRawTransactionRequest) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{22} +} + +func (x *SendRawTransactionRequest) GetSignedTx() string { + if x != nil { + return x.SignedTx + } + return "" +} + +type SendRawTransactionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *SendRawTransactionResponse) Reset() { + *x = SendRawTransactionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_archive_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendRawTransactionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendRawTransactionResponse) ProtoMessage() {} + +func (x *SendRawTransactionResponse) ProtoReflect() protoreflect.Message { + mi := &file_archive_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendRawTransactionResponse.ProtoReflect.Descriptor instead. +func (*SendRawTransactionResponse) Descriptor() ([]byte, []int) { + return file_archive_proto_rawDescGZIP(), []int{23} +} + +func (x *SendRawTransactionResponse) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + var File_archive_proto protoreflect.FileDescriptor var file_archive_proto_rawDesc = []byte{ @@ -1616,65 +1710,81 @@ var file_archive_proto_rawDesc = []byte{ 0x50, 0x65, 0x72, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xf1, 0x06, 0x0a, 0x0e, 0x41, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, 0x0a, 0x0b, - 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x2e, 0x71, 0x75, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x38, 0x0a, 0x19, 0x53, 0x65, 0x6e, + 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, + 0x5f, 0x74, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x54, 0x78, 0x22, 0x36, 0x0a, 0x1a, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0xf5, 0x07, 0x0a, 0x0e, + 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6c, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x2e, + 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, + 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x71, + 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, + 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, + 0x13, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, + 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, - 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x71, 0x75, 0x62, - 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x13, 0x47, - 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x12, 0x35, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, - 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x75, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, - 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, - 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, + 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x75, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x51, - 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x2e, - 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, - 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, - 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, - 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, - 0x65, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x43, - 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, - 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, - 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, - 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, - 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, 0x65, 0x74, - 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x31, 0x2e, 0x71, - 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, - 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x32, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, - 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, - 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x36, 0x2e, 0x71, - 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, - 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, + 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7e, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x33, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, + 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x51, + 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, - 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, - 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x29, 0x5a, - 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x71, 0x75, 0x62, 0x69, - 0x63, 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x66, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x47, 0x65, 0x74, 0x51, 0x75, 0x6f, 0x72, 0x75, 0x6d, 0x54, 0x69, 0x63, 0x6b, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6f, 0x0a, 0x0c, 0x47, 0x65, + 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x2e, 0x2e, 0x71, 0x75, 0x62, + 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x71, 0x75, 0x62, + 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x6f, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x31, + 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x49, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x32, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, + 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, + 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x36, + 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, + 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, + 0x70, 0x62, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x65, 0x64, 0x54, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x81, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, 0x2e, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, + 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x71, + 0x75, 0x62, 0x69, 0x63, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x72, 0x2e, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2e, 0x70, 0x62, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x52, 0x61, 0x77, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x71, 0x75, 0x62, 0x69, 0x63, 0x2f, 0x67, 0x6f, 0x2d, 0x61, 0x72, 0x63, 0x68, 0x69, + 0x76, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x66, 0x2f, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1689,7 +1799,7 @@ func file_archive_proto_rawDescGZIP() []byte { return file_archive_proto_rawDescData } -var file_archive_proto_msgTypes = make([]protoimpl.MessageInfo, 24) +var file_archive_proto_msgTypes = make([]protoimpl.MessageInfo, 26) var file_archive_proto_goTypes = []interface{}{ (*TickData)(nil), // 0: qubic.archiver.archive.pb.TickData (*GetTickDataRequest)(nil), // 1: qubic.archiver.archive.pb.GetTickDataRequest @@ -1713,8 +1823,10 @@ var file_archive_proto_goTypes = []interface{}{ (*GetIdentityInfoResponse)(nil), // 19: qubic.archiver.archive.pb.GetIdentityInfoResponse (*GetLastProcessedTickRequest)(nil), // 20: qubic.archiver.archive.pb.GetLastProcessedTickRequest (*GetLastProcessedTickResponse)(nil), // 21: qubic.archiver.archive.pb.GetLastProcessedTickResponse - nil, // 22: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry - nil, // 23: qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry + (*SendRawTransactionRequest)(nil), // 22: qubic.archiver.archive.pb.SendRawTransactionRequest + (*SendRawTransactionResponse)(nil), // 23: qubic.archiver.archive.pb.SendRawTransactionResponse + nil, // 24: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry + nil, // 25: qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry } var file_archive_proto_depIdxs = []int32{ 0, // 0: qubic.archiver.archive.pb.GetTickDataResponse.tick_data:type_name -> qubic.archiver.archive.pb.TickData @@ -1722,11 +1834,11 @@ var file_archive_proto_depIdxs = []int32{ 3, // 2: qubic.archiver.archive.pb.Transactions.transactions:type_name -> qubic.archiver.archive.pb.Transaction 3, // 3: qubic.archiver.archive.pb.GetTickTransactionsResponse.transactions:type_name -> qubic.archiver.archive.pb.Transaction 10, // 4: qubic.archiver.archive.pb.QuorumTickData.quorum_tick_structure:type_name -> qubic.archiver.archive.pb.QuorumTickStructure - 22, // 5: qubic.archiver.archive.pb.QuorumTickData.quorum_diff_per_computor:type_name -> qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry + 24, // 5: qubic.archiver.archive.pb.QuorumTickData.quorum_diff_per_computor:type_name -> qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry 11, // 6: qubic.archiver.archive.pb.GetQuorumTickDataResponse.quorum_tick_data:type_name -> qubic.archiver.archive.pb.QuorumTickData 14, // 7: qubic.archiver.archive.pb.GetComputorsResponse.computors:type_name -> qubic.archiver.archive.pb.Computors 17, // 8: qubic.archiver.archive.pb.GetIdentityInfoResponse.identity_info:type_name -> qubic.archiver.archive.pb.IdentityInfo - 23, // 9: qubic.archiver.archive.pb.GetLastProcessedTickResponse.last_processed_ticks_per_epoch:type_name -> qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry + 25, // 9: qubic.archiver.archive.pb.GetLastProcessedTickResponse.last_processed_ticks_per_epoch:type_name -> qubic.archiver.archive.pb.GetLastProcessedTickResponse.LastProcessedTicksPerEpochEntry 9, // 10: qubic.archiver.archive.pb.QuorumTickData.QuorumDiffPerComputorEntry.value:type_name -> qubic.archiver.archive.pb.QuorumDiff 1, // 11: qubic.archiver.archive.pb.ArchiveService.GetTickData:input_type -> qubic.archiver.archive.pb.GetTickDataRequest 7, // 12: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:input_type -> qubic.archiver.archive.pb.GetTickTransactionsRequest @@ -1735,15 +1847,17 @@ var file_archive_proto_depIdxs = []int32{ 15, // 15: qubic.archiver.archive.pb.ArchiveService.GetComputors:input_type -> qubic.archiver.archive.pb.GetComputorsRequest 18, // 16: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:input_type -> qubic.archiver.archive.pb.GetIdentityInfoRequest 20, // 17: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:input_type -> qubic.archiver.archive.pb.GetLastProcessedTickRequest - 2, // 18: qubic.archiver.archive.pb.ArchiveService.GetTickData:output_type -> qubic.archiver.archive.pb.GetTickDataResponse - 8, // 19: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:output_type -> qubic.archiver.archive.pb.GetTickTransactionsResponse - 5, // 20: qubic.archiver.archive.pb.ArchiveService.GetTransaction:output_type -> qubic.archiver.archive.pb.GetTransactionResponse - 13, // 21: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:output_type -> qubic.archiver.archive.pb.GetQuorumTickDataResponse - 16, // 22: qubic.archiver.archive.pb.ArchiveService.GetComputors:output_type -> qubic.archiver.archive.pb.GetComputorsResponse - 19, // 23: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:output_type -> qubic.archiver.archive.pb.GetIdentityInfoResponse - 21, // 24: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:output_type -> qubic.archiver.archive.pb.GetLastProcessedTickResponse - 18, // [18:25] is the sub-list for method output_type - 11, // [11:18] is the sub-list for method input_type + 22, // 18: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:input_type -> qubic.archiver.archive.pb.SendRawTransactionRequest + 2, // 19: qubic.archiver.archive.pb.ArchiveService.GetTickData:output_type -> qubic.archiver.archive.pb.GetTickDataResponse + 8, // 20: qubic.archiver.archive.pb.ArchiveService.GetTickTransactions:output_type -> qubic.archiver.archive.pb.GetTickTransactionsResponse + 5, // 21: qubic.archiver.archive.pb.ArchiveService.GetTransaction:output_type -> qubic.archiver.archive.pb.GetTransactionResponse + 13, // 22: qubic.archiver.archive.pb.ArchiveService.GetQuorumTickData:output_type -> qubic.archiver.archive.pb.GetQuorumTickDataResponse + 16, // 23: qubic.archiver.archive.pb.ArchiveService.GetComputors:output_type -> qubic.archiver.archive.pb.GetComputorsResponse + 19, // 24: qubic.archiver.archive.pb.ArchiveService.GetIdentityInfo:output_type -> qubic.archiver.archive.pb.GetIdentityInfoResponse + 21, // 25: qubic.archiver.archive.pb.ArchiveService.GetLastProcessedTick:output_type -> qubic.archiver.archive.pb.GetLastProcessedTickResponse + 23, // 26: qubic.archiver.archive.pb.ArchiveService.SendRawTransaction:output_type -> qubic.archiver.archive.pb.SendRawTransactionResponse + 19, // [19:27] is the sub-list for method output_type + 11, // [11:19] is the sub-list for method input_type 11, // [11:11] is the sub-list for extension type_name 11, // [11:11] is the sub-list for extension extendee 0, // [0:11] is the sub-list for field type_name @@ -2019,6 +2133,30 @@ func file_archive_proto_init() { return nil } } + file_archive_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendRawTransactionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_archive_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendRawTransactionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2026,7 +2164,7 @@ func file_archive_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_archive_proto_rawDesc, NumEnums: 0, - NumMessages: 24, + NumMessages: 26, NumExtensions: 0, NumServices: 1, }, diff --git a/protobuff/archive.pb.gw.go b/protobuff/archive.pb.gw.go index 2b912c6..91d147b 100644 --- a/protobuff/archive.pb.gw.go +++ b/protobuff/archive.pb.gw.go @@ -269,6 +269,40 @@ func local_request_ArchiveService_GetLastProcessedTick_0(ctx context.Context, ma } +func request_ArchiveService_SendRawTransaction_0(ctx context.Context, marshaler runtime.Marshaler, client ArchiveServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SendRawTransactionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.SendRawTransaction(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArchiveService_SendRawTransaction_0(ctx context.Context, marshaler runtime.Marshaler, server ArchiveServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SendRawTransactionRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.SendRawTransaction(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterArchiveServiceHandlerServer registers the http handlers for service ArchiveService to "mux". // UnaryRPC :call ArchiveServiceServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -450,6 +484,31 @@ func RegisterArchiveServiceHandlerServer(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_ArchiveService_SendRawTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArchiveService_SendRawTransaction_0(annotatedContext, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_SendRawTransaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -645,6 +704,28 @@ func RegisterArchiveServiceHandlerClient(ctx context.Context, mux *runtime.Serve }) + mux.Handle("POST", pattern_ArchiveService_SendRawTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + var err error + var annotatedContext context.Context + annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction", runtime.WithHTTPPathPattern("/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction")) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArchiveService_SendRawTransaction_0(annotatedContext, inboundMarshaler, client, req, pathParams) + annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md) + if err != nil { + runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArchiveService_SendRawTransaction_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -662,6 +743,8 @@ var ( pattern_ArchiveService_GetIdentityInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "GetIdentityInfo"}, "")) pattern_ArchiveService_GetLastProcessedTick_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "GetLastProcessedTick"}, "")) + + pattern_ArchiveService_SendRawTransaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"qubic.archiver.archive.pb.ArchiveService", "SendRawTransaction"}, "")) ) var ( @@ -678,4 +761,6 @@ var ( forward_ArchiveService_GetIdentityInfo_0 = runtime.ForwardResponseMessage forward_ArchiveService_GetLastProcessedTick_0 = runtime.ForwardResponseMessage + + forward_ArchiveService_SendRawTransaction_0 = runtime.ForwardResponseMessage ) diff --git a/protobuff/archive.proto b/protobuff/archive.proto index f01a155..98347b4 100644 --- a/protobuff/archive.proto +++ b/protobuff/archive.proto @@ -131,6 +131,14 @@ message GetLastProcessedTickResponse{ map last_processed_ticks_per_epoch = 2; } +message SendRawTransactionRequest { + string signed_tx = 1; +} + +message SendRawTransactionResponse { + string message = 1; +} + service ArchiveService { rpc GetTickData(GetTickDataRequest) returns (GetTickDataResponse); rpc GetTickTransactions(GetTickTransactionsRequest) returns (GetTickTransactionsResponse); @@ -139,4 +147,5 @@ service ArchiveService { rpc GetComputors(GetComputorsRequest) returns (GetComputorsResponse); rpc GetIdentityInfo(GetIdentityInfoRequest) returns (GetIdentityInfoResponse); rpc GetLastProcessedTick(GetLastProcessedTickRequest) returns (GetLastProcessedTickResponse); + rpc SendRawTransaction(SendRawTransactionRequest) returns (SendRawTransactionResponse); } \ No newline at end of file diff --git a/protobuff/archive_grpc.pb.go b/protobuff/archive_grpc.pb.go index 4f0ab13..bd65a79 100644 --- a/protobuff/archive_grpc.pb.go +++ b/protobuff/archive_grpc.pb.go @@ -26,6 +26,7 @@ const ( ArchiveService_GetComputors_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetComputors" ArchiveService_GetIdentityInfo_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetIdentityInfo" ArchiveService_GetLastProcessedTick_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/GetLastProcessedTick" + ArchiveService_SendRawTransaction_FullMethodName = "/qubic.archiver.archive.pb.ArchiveService/SendRawTransaction" ) // ArchiveServiceClient is the client API for ArchiveService service. @@ -39,6 +40,7 @@ type ArchiveServiceClient interface { GetComputors(ctx context.Context, in *GetComputorsRequest, opts ...grpc.CallOption) (*GetComputorsResponse, error) GetIdentityInfo(ctx context.Context, in *GetIdentityInfoRequest, opts ...grpc.CallOption) (*GetIdentityInfoResponse, error) GetLastProcessedTick(ctx context.Context, in *GetLastProcessedTickRequest, opts ...grpc.CallOption) (*GetLastProcessedTickResponse, error) + SendRawTransaction(ctx context.Context, in *SendRawTransactionRequest, opts ...grpc.CallOption) (*SendRawTransactionResponse, error) } type archiveServiceClient struct { @@ -112,6 +114,15 @@ func (c *archiveServiceClient) GetLastProcessedTick(ctx context.Context, in *Get return out, nil } +func (c *archiveServiceClient) SendRawTransaction(ctx context.Context, in *SendRawTransactionRequest, opts ...grpc.CallOption) (*SendRawTransactionResponse, error) { + out := new(SendRawTransactionResponse) + err := c.cc.Invoke(ctx, ArchiveService_SendRawTransaction_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // ArchiveServiceServer is the server API for ArchiveService service. // All implementations must embed UnimplementedArchiveServiceServer // for forward compatibility @@ -123,6 +134,7 @@ type ArchiveServiceServer interface { GetComputors(context.Context, *GetComputorsRequest) (*GetComputorsResponse, error) GetIdentityInfo(context.Context, *GetIdentityInfoRequest) (*GetIdentityInfoResponse, error) GetLastProcessedTick(context.Context, *GetLastProcessedTickRequest) (*GetLastProcessedTickResponse, error) + SendRawTransaction(context.Context, *SendRawTransactionRequest) (*SendRawTransactionResponse, error) mustEmbedUnimplementedArchiveServiceServer() } @@ -151,6 +163,9 @@ func (UnimplementedArchiveServiceServer) GetIdentityInfo(context.Context, *GetId func (UnimplementedArchiveServiceServer) GetLastProcessedTick(context.Context, *GetLastProcessedTickRequest) (*GetLastProcessedTickResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetLastProcessedTick not implemented") } +func (UnimplementedArchiveServiceServer) SendRawTransaction(context.Context, *SendRawTransactionRequest) (*SendRawTransactionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SendRawTransaction not implemented") +} func (UnimplementedArchiveServiceServer) mustEmbedUnimplementedArchiveServiceServer() {} // UnsafeArchiveServiceServer may be embedded to opt out of forward compatibility for this service. @@ -290,6 +305,24 @@ func _ArchiveService_GetLastProcessedTick_Handler(srv interface{}, ctx context.C return interceptor(ctx, in, info, handler) } +func _ArchiveService_SendRawTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SendRawTransactionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArchiveServiceServer).SendRawTransaction(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: ArchiveService_SendRawTransaction_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArchiveServiceServer).SendRawTransaction(ctx, req.(*SendRawTransactionRequest)) + } + return interceptor(ctx, in, info, handler) +} + // ArchiveService_ServiceDesc is the grpc.ServiceDesc for ArchiveService service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -325,6 +358,10 @@ var ArchiveService_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetLastProcessedTick", Handler: _ArchiveService_GetLastProcessedTick_Handler, }, + { + MethodName: "SendRawTransaction", + Handler: _ArchiveService_SendRawTransaction_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "archive.proto", diff --git a/rpc/rpc_server.go b/rpc/rpc_server.go index a417753..aa09bfb 100644 --- a/rpc/rpc_server.go +++ b/rpc/rpc_server.go @@ -3,6 +3,7 @@ package rpc import ( "context" "encoding/hex" + "fmt" "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/pkg/errors" "github.com/qubic/go-archiver/protobuff" @@ -23,18 +24,20 @@ import ( type Server struct { protobuff.UnimplementedArchiveServiceServer - listenAddrGRPC string - listenAddrHTTP string - store *store.PebbleStore - pool pool.Pool + listenAddrGRPC string + listenAddrHTTP string + store *store.PebbleStore + pool pool.Pool + nrPeersToBroadcastTx int } -func NewServer(listenAddrGRPC, listenAddrHTTP string, store *store.PebbleStore, p pool.Pool) *Server { +func NewServer(listenAddrGRPC, listenAddrHTTP string, store *store.PebbleStore, p pool.Pool, nrPeersToBroadcastTx int) *Server { return &Server{ - listenAddrGRPC: listenAddrGRPC, - listenAddrHTTP: listenAddrHTTP, - store: store, - pool: p, + listenAddrGRPC: listenAddrGRPC, + listenAddrHTTP: listenAddrHTTP, + store: store, + pool: p, + nrPeersToBroadcastTx: nrPeersToBroadcastTx, } } @@ -147,6 +150,32 @@ func (s *Server) GetLastProcessedTick(ctx context.Context, req *protobuff.GetLas return &protobuff.GetLastProcessedTickResponse{LastProcessedTick: uint32(tick), LastProcessedTicksPerEpoch: lastProcessedTicksPerEpoch}, nil } +func (s *Server) SendRawTransaction(ctx context.Context, req *protobuff.SendRawTransactionRequest) (*protobuff.SendRawTransactionResponse, error) { + nrSuccess := 0 + for i := 0; i < s.nrPeersToBroadcastTx; i++ { + func() { + qcv, err := s.pool.Get() + if err != nil { + return + } + defer s.pool.Put(qcv) + + client := qcv.(*qubic.Client) + err = client.SendRawTransaction(ctx, []byte(req.SignedTx)) + if err != nil { + return + } + nrSuccess++ + }() + } + + if nrSuccess == 0 { + return nil, status.Errorf(codes.Internal, "broadcasting tx failed for all peers") + } + + return &protobuff.SendRawTransactionResponse{Message: fmt.Sprintf("Transaction broadcasted to %d peers", nrSuccess)}, nil +} + func (s *Server) Start() error { srv := grpc.NewServer( grpc.MaxRecvMsgSize(600*1024*1024), diff --git a/store/store.go b/store/store.go index 3506b44..a76bdf5 100644 --- a/store/store.go +++ b/store/store.go @@ -9,7 +9,6 @@ import ( "go.uber.org/zap" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" - "log" "strconv" ) @@ -279,7 +278,6 @@ func (s *PebbleStore) GetLastProcessedTicksPerEpoch(ctx context.Context) (map[ui epochNumber := binary.BigEndian.Uint32(key[1:]) tickNumber := binary.LittleEndian.Uint64(value) ticksPerEpoch[epochNumber] = tickNumber - log.Printf("key: %s, value: %s\n", key, value) } return ticksPerEpoch, nil diff --git a/validator/quorum/validation.go b/validator/quorum/validation.go index e653596..e3081db 100644 --- a/validator/quorum/validation.go +++ b/validator/quorum/validation.go @@ -33,19 +33,19 @@ func compareVotes(ctx context.Context, quorumVotes types.QuorumVotes) error { for i := 1; i < len(quorumVotes); i++ { if quorumVotes[i].Epoch != firstTickData.Epoch || - quorumVotes[i].Tick != firstTickData.Tick || - quorumVotes[i].Millisecond != firstTickData.Millisecond || - quorumVotes[i].Second != firstTickData.Second || - quorumVotes[i].Minute != firstTickData.Minute || - quorumVotes[i].Hour != firstTickData.Hour || - quorumVotes[i].Day != firstTickData.Day || - quorumVotes[i].Month != firstTickData.Month || - quorumVotes[i].Year != firstTickData.Year || - quorumVotes[i].PreviousResourceTestingDigest != firstTickData.PreviousResourceTestingDigest || - quorumVotes[i].PreviousComputerDigest != firstTickData.PreviousComputerDigest || - quorumVotes[i].PreviousSpectrumDigest != firstTickData.PreviousSpectrumDigest || - quorumVotes[i].PreviousUniverseDigest != firstTickData.PreviousUniverseDigest || - quorumVotes[i].TxDigest != firstTickData.TxDigest { + quorumVotes[i].Tick != firstTickData.Tick || + quorumVotes[i].Millisecond != firstTickData.Millisecond || + quorumVotes[i].Second != firstTickData.Second || + quorumVotes[i].Minute != firstTickData.Minute || + quorumVotes[i].Hour != firstTickData.Hour || + quorumVotes[i].Day != firstTickData.Day || + quorumVotes[i].Month != firstTickData.Month || + quorumVotes[i].Year != firstTickData.Year || + quorumVotes[i].PreviousResourceTestingDigest != firstTickData.PreviousResourceTestingDigest || + quorumVotes[i].PreviousComputerDigest != firstTickData.PreviousComputerDigest || + quorumVotes[i].PreviousSpectrumDigest != firstTickData.PreviousSpectrumDigest || + quorumVotes[i].PreviousUniverseDigest != firstTickData.PreviousUniverseDigest || + quorumVotes[i].TxDigest != firstTickData.TxDigest { return errors.New("quorum votes are not the same between quorum computors") } } @@ -76,7 +76,7 @@ func quorumTickSigVerify(ctx context.Context, quorumVotes types.QuorumVotes, com failedIdentites = append(failedIdentites, string(badComputor)) continue } - successVotes +=1 + successVotes += 1 //log.Printf("Validated vote for computor index: %d. Vote number %d\n", quorumTickData.ComputorIndex, successVotes) } @@ -106,12 +106,10 @@ func getDigestFromQuorumTickData(data types.QuorumTickVote) ([32]byte, error) { func Store(ctx context.Context, store *store.PebbleStore, quorumVotes types.QuorumVotes) error { protoModel := qubicToProto(quorumVotes) - err := store.SetQuorumTickData(ctx, uint64(protoModel.QuorumTickStructure.Epoch), protoModel) + err := store.SetQuorumTickData(ctx, uint64(protoModel.QuorumTickStructure.TickNumber), protoModel) if err != nil { return errors.Wrap(err, "set quorum votes") } return nil } - - diff --git a/validator/tick/models.go b/validator/tick/models.go index fee002f..7e1ccc9 100644 --- a/validator/tick/models.go +++ b/validator/tick/models.go @@ -48,6 +48,9 @@ func digestsToIdentities(digests [types.NumberOfTransactionsPerTick][32]byte) ([ func contractFeesToProto(contractFees [1024]int64) []int64 { protoContractFees := make([]int64, len(contractFees)) for i, fee := range contractFees { + if fee == 0 { + continue + } protoContractFees[i] = fee } return protoContractFees diff --git a/validator/validator.go b/validator/validator.go index b508652..263e30f 100644 --- a/validator/validator.go +++ b/validator/validator.go @@ -63,9 +63,9 @@ func (v *Validator) ValidateTick(ctx context.Context, tickNumber uint64) error { // if the quorum votes have an empty tick data, it means that POTENTIALLY there is no tick data, it doesn't for // validation, but we may need to fetch it in the future ?! - if quorumVotes[0].TxDigest == [32]byte{} { - return nil - } + //if quorumVotes[0].TxDigest == [32]byte{} { + // return nil + //} log.Println("Quorum validated")