Skip to content

Commit

Permalink
[SIG_PROVIDER] Add eth-bytecode-db source. Add batched event retrieva…
Browse files Browse the repository at this point in the history
…ls (#707)

* Add event descriptions search

* Insertion of the event signatures into database implementation

* Add tests

* Bump blockscout-service-launcher to v0.9.0. Add BatchGetEventAbis method template

* Update existing events parser to support eth-bytecode-db

* Add batch_get_event_abi implementation

* Update BatchGetEventAbis proto to bypass initial 'responses' object. Make requests in batch_get_event_abis concurrent

* Update tests

* Add BatchSearchEventDescriptions endpoint definition. Add test cases for batch-search

* Add BatchSearchEventDescriptions implementation

* Make use of batch search

* Remove supports_batched method
  • Loading branch information
rimrakhimov authored Dec 20, 2023
1 parent ff9c358 commit db27e40
Show file tree
Hide file tree
Showing 19 changed files with 1,387 additions and 296 deletions.
656 changes: 618 additions & 38 deletions sig-provider/Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion sig-provider/sig-provider-proto/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ fn compile(
.protoc_arg("--openapiv2_opt")
.protoc_arg("grpc_api_configuration=proto/api_config_http.yaml,output_format=yaml,allow_merge=true,merge_file_name=sig-provider")
.bytes(["."])
.type_attribute(".", "#[actix_prost_macros::serde]");
.type_attribute(".", "#[actix_prost_macros::serde]")
.message_attribute(".", "#[derive(Eq, Hash)]");
config.compile_protos(protos, includes)?;
Ok(())
}
Expand Down
5 changes: 5 additions & 0 deletions sig-provider/sig-provider-proto/proto/api_config_http.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,10 @@ http:
get: /api/v1/abi/event
response_body: "abi"

- selector: blockscout.sig_provider.v1.AbiService.BatchGetEventAbis
post: /api/v1/abi/events:batch-get
body: "*"
response_body: "responses"

- selector: blockscout.sig_provider.v1.Health.Check
get: /health
10 changes: 10 additions & 0 deletions sig-provider/sig-provider-proto/proto/sig-provider.proto
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ service SignatureService {
service AbiService {
rpc GetFunctionAbi(GetFunctionAbiRequest) returns (GetFunctionAbiResponse) {}
rpc GetEventAbi(GetEventAbiRequest) returns (GetEventAbiResponse) {}

rpc BatchGetEventAbis(BatchGetEventAbisRequest) returns (BatchGetEventAbisResponse) {}
}

message CreateSignaturesRequest { string abi = 1; }
Expand Down Expand Up @@ -44,3 +46,11 @@ message GetEventAbiRequest {
}

message GetEventAbiResponse { repeated Abi abi = 1; }

message BatchGetEventAbisRequest {
repeated GetEventAbiRequest requests = 1;
}

message BatchGetEventAbisResponse {
repeated GetEventAbiResponse responses = 1;
}
71 changes: 63 additions & 8 deletions sig-provider/sig-provider-proto/swagger/sig-provider.swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ paths:
schema:
type: array
items:
type: object
$ref: '#/definitions/v1Abi'
default:
description: An unexpected error response.
Expand All @@ -37,6 +38,29 @@ paths:
type: string
tags:
- AbiService
/api/v1/abi/events:batch-get:
post:
operationId: AbiService_BatchGetEventAbis
responses:
"200":
description: ""
schema:
type: array
items:
type: object
$ref: '#/definitions/v1GetEventAbiResponse'
default:
description: An unexpected error response.
schema:
$ref: '#/definitions/rpcStatus'
parameters:
- name: body
in: body
required: true
schema:
$ref: '#/definitions/v1BatchGetEventAbisRequest'
tags:
- AbiService
/api/v1/abi/function:
get:
operationId: AbiService_GetFunctionAbi
Expand All @@ -46,6 +70,7 @@ paths:
schema:
type: array
items:
type: object
$ref: '#/definitions/v1Abi'
default:
description: An unexpected error response.
Expand Down Expand Up @@ -109,6 +134,7 @@ definitions:
- NOT_SERVING
- SERVICE_UNKNOWN
default: UNKNOWN
description: ' - SERVICE_UNKNOWN: Used only by the Watch method.'
protobufAny:
type: object
properties:
Expand All @@ -121,58 +147,87 @@ definitions:
code:
type: integer
format: int32
message:
type: string
details:
type: array
items:
type: object
$ref: '#/definitions/protobufAny'
message:
type: string
v1Abi:
type: object
properties:
name:
type: string
inputs:
type: array
items:
type: object
$ref: '#/definitions/v1Argument'
name:
type: string
v1Argument:
type: object
properties:
name:
type: string
type:
type: string
components:
type: array
items:
type: object
$ref: '#/definitions/v1Argument'
indexed:
type: boolean
title: this is present only in events
name:
type: string
type:
type: string
value:
type: string
title: decoded value
v1BatchGetEventAbisRequest:
type: object
properties:
requests:
type: array
items:
type: object
$ref: '#/definitions/v1GetEventAbiRequest'
v1BatchGetEventAbisResponse:
type: object
properties:
responses:
type: array
items:
type: object
$ref: '#/definitions/v1GetEventAbiResponse'
v1CreateSignaturesRequest:
type: object
properties:
abi:
type: string
v1CreateSignaturesResponse:
type: object
v1GetEventAbiRequest:
type: object
properties:
data:
type: string
topics:
type: string
title: comma separated hex values, ex. `0x0000..1234,0x0000...5678`
v1GetEventAbiResponse:
type: object
properties:
abi:
type: array
items:
type: object
$ref: '#/definitions/v1Abi'
v1GetFunctionAbiResponse:
type: object
properties:
abi:
type: array
items:
type: object
$ref: '#/definitions/v1Abi'
v1HealthCheckResponse:
type: object
Expand Down
5 changes: 3 additions & 2 deletions sig-provider/sig-provider-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ futures = "0.3"
anyhow = "1.0"
url = { version = "2", features = ["serde"] }
hex = "0.4"
ethabi = "17"
blockscout-service-launcher = "0.1"
ethabi = "18.0.0"
blockscout-service-launcher = "0.9.0"

[dev-dependencies]
blockscout-service-launcher = { version = "*", features = ["test-server"] }
http = "0.2"
httpmock = "0.6"
pretty_assertions = "1.3"
Expand Down
11 changes: 10 additions & 1 deletion sig-provider/sig-provider-server/config/base.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
[server.http]
enabled = true
addr = "0.0.0.0:8050"
max_body_size = 2097152

[server.grpc]
enabled = true
enabled = false
addr = "0.0.0.0:8051"

[sources]
fourbyte = "https://www.4byte.directory/"
sigeth = "https://sig.eth.samczsun.com/"

[sources.eth_bytecode_db]
enabled = true
url = "https://eth-bytecode-db.services.blockscout.com/"

[metrics]
enabled = false
addr = "0.0.0.0:6060"
Expand All @@ -18,3 +23,7 @@ route = "/metrics"
[jaeger]
enabled = false
agent_endpoint = "127.0.0.1:6831"

[tracing]
enabled = true
format = "default"
3 changes: 2 additions & 1 deletion sig-provider/sig-provider-server/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use blockscout_service_launcher::launcher::ConfigSettings;
use sig_provider_server::{sig_provider, Settings};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
let settings = Settings::new().expect("failed to read config");
let settings = Settings::build().expect("failed to read config");
sig_provider(settings).await
}
83 changes: 44 additions & 39 deletions sig-provider/sig-provider-server/src/run.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::{health::HealthService, settings::SourcesSettings, Service, Settings};
use actix_web::web::ServiceConfig;
use blockscout_service_launcher::LaunchSettings;
use sig_provider::{fourbyte, sigeth, SourceAggregator};
use blockscout_service_launcher::{launcher, launcher::LaunchSettings, tracing};
use sig_provider::{
eth_bytecode_db, fourbyte, sigeth, CompleteSignatureSource, SignatureSource, SourceAggregator,
};
use sig_provider_proto::blockscout::sig_provider::v1::{
abi_service_actix::route_abi_service,
abi_service_server::{AbiService, AbiServiceServer},
Expand All @@ -12,67 +13,71 @@ use sig_provider_proto::blockscout::sig_provider::v1::{
};
use std::sync::Arc;

pub fn http_configure<S: SignatureService, A: AbiService>(
config: &mut ServiceConfig,
signature: Arc<S>,
abi: Arc<A>,
) {
route_signature_service(config, signature);
route_abi_service(config, abi);
}
const SERVICE_NAME: &str = "sig_provider";

#[derive(Clone)]
struct HttpRouter<S: SignatureService, A: AbiService> {
struct Router<S: SignatureService, A: AbiService> {
signature: Arc<S>,
abi: Arc<A>,
health: Arc<HealthService>,
}

impl<S: SignatureService, A: AbiService> blockscout_service_launcher::HttpRouter
for HttpRouter<S, A>
{
impl<S: SignatureService, A: AbiService> Router<S, A> {
pub fn grpc_router(&self) -> tonic::transport::server::Router {
tonic::transport::Server::builder()
.add_service(HealthServer::from_arc(self.health.clone()))
.add_service(SignatureServiceServer::from_arc(self.signature.clone()))
.add_service(AbiServiceServer::from_arc(self.abi.clone()))
}
}

impl<S: SignatureService, A: AbiService> launcher::HttpRouter for Router<S, A> {
fn register_routes(&self, service_config: &mut actix_web::web::ServiceConfig) {
service_config
.configure(|config| route_health(config, self.health.clone()))
.configure(|config| http_configure(config, self.signature.clone(), self.abi.clone()));
.configure(|config| route_signature_service(config, self.signature.clone()))
.configure(|config| route_abi_service(config, self.abi.clone()));
}
}

fn grpc_router<S: SignatureService, A: AbiService>(
signature: Arc<S>,
abi: Arc<A>,
health: Arc<HealthService>,
) -> tonic::transport::server::Router {
tonic::transport::Server::builder()
.add_service(HealthServer::from_arc(health))
.add_service(SignatureServiceServer::from_arc(signature))
.add_service(AbiServiceServer::from_arc(abi))
}

pub fn new_service(sources: SourcesSettings) -> Arc<Service> {
let aggregator = Arc::new(SourceAggregator::new(vec![
Arc::new(sigeth::Source::new(sources.sigeth)),
Arc::new(fourbyte::Source::new(sources.fourbyte)),
]));
pub fn new_service(settings: SourcesSettings) -> Arc<Service> {
let sources: Vec<Arc<dyn SignatureSource + Send + Sync + 'static>> = vec![
Arc::new(sigeth::Source::new(settings.sigeth)),
Arc::new(fourbyte::Source::new(settings.fourbyte)),
];
let complete_sources = {
let mut sources: Vec<Arc<dyn CompleteSignatureSource + Send + Sync + 'static>> = vec![];
if settings.eth_bytecode_db.enabled {
sources.push(Arc::new(eth_bytecode_db::Source::new(
settings.eth_bytecode_db.url,
)))
};
sources
};
let aggregator = Arc::new(SourceAggregator::new(sources, complete_sources));
Arc::new(Service::new(aggregator))
}

pub async fn sig_provider(settings: Settings) -> Result<(), anyhow::Error> {
let service = new_service(settings.sources);
tracing::init_logs(SERVICE_NAME, &settings.tracing, &settings.jaeger)?;

let health = Arc::new(HealthService::default());
let service = new_service(settings.sources);

let grpc_router = grpc_router(service.clone(), service.clone(), health.clone());
let http_router = HttpRouter {
signature: service.clone(),
let router = Router {
abi: service.clone(),
signature: service.clone(),
health,
};

let grpc_router = router.grpc_router();
let http_router = router;

let launch_settings = LaunchSettings {
service_name: "sig_provider".to_owned(),
service_name: SERVICE_NAME.to_string(),
server: settings.server,
metrics: settings.metrics,
jaeger: settings.jaeger,
};

blockscout_service_launcher::launch(&launch_settings, http_router, grpc_router).await
launcher::launch(&launch_settings, http_router, grpc_router).await
}
Loading

0 comments on commit db27e40

Please sign in to comment.