Skip to content

Commit 1a09224

Browse files
jvffafck
andauthored
Limit the size of oracle responses (#3597)
## Motivation Services can be called as oracles, and the responses they provide must be bounded because they are stored in blocks. ## Proposal Implement a configurable limit to the size of oracle responses, and enforce that limit in contract HTTP requests and service-as-oracle responses. To distinguish between contracts and services in compile time, an extension trait was used to allow minimal change to the `BaseRuntime` implementation. ## Test Plan Unit test cases were added to check if the limits were being respected. ## Release Plan - These changes follow the usual release cycle, because services-as-oracles is still feature gated by `unstable-oracles`. ## Links - Closes #3563 - [reviewer checklist](https://github.com/linera-io/linera-protocol/blob/main/CONTRIBUTING.md#reviewer-checklist) --------- Signed-off-by: Janito Vaqueiro Ferreira Filho <[email protected]> Co-authored-by: Andreas Fackler <[email protected]>
1 parent 13e3bf8 commit 1a09224

File tree

17 files changed

+423
-138
lines changed

17 files changed

+423
-138
lines changed

CLI.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ View or update the resource control policy
476476
* `--maximum-block-proposal-size <MAXIMUM_BLOCK_PROPOSAL_SIZE>` — Set the maximum size of a block proposal, in bytes
477477
* `--maximum-bytes-read-per-block <MAXIMUM_BYTES_READ_PER_BLOCK>` — Set the maximum read data per block
478478
* `--maximum-bytes-written-per-block <MAXIMUM_BYTES_WRITTEN_PER_BLOCK>` — Set the maximum write data per block
479+
* `--maximum-oracle-response-bytes <MAXIMUM_ORACLE_RESPONSE_BYTES>` — Set the maximum size of oracle responses
479480
* `--maximum-http-response-bytes <MAXIMUM_HTTP_RESPONSE_BYTES>` — Set the maximum size in bytes of a received HTTP response
480481
* `--http-request-timeout-ms <HTTP_REQUEST_TIMEOUT_MS>` — Set the maximum amount of time allowed to wait for an HTTP response
481482
* `--http-request-allow-list <HTTP_REQUEST_ALLOW_LIST>` — Set the list of hosts that contracts and services can send HTTP requests to
@@ -535,6 +536,7 @@ Create genesis configuration for a Linera deployment. Create initial user chains
535536
* `--maximum-block-proposal-size <MAXIMUM_BLOCK_PROPOSAL_SIZE>` — Set the maximum size of a block proposal, in bytes. (This will overwrite value from `--policy-config`)
536537
* `--maximum-bytes-read-per-block <MAXIMUM_BYTES_READ_PER_BLOCK>` — Set the maximum read data per block. (This will overwrite value from `--policy-config`)
537538
* `--maximum-bytes-written-per-block <MAXIMUM_BYTES_WRITTEN_PER_BLOCK>` — Set the maximum write data per block. (This will overwrite value from `--policy-config`)
539+
* `--maximum-oracle-response-bytes <MAXIMUM_ORACLE_RESPONSE_BYTES>` — Set the maximum size of oracle responses. (This will overwrite value from `--policy-config`)
538540
* `--maximum-http-response-bytes <MAXIMUM_HTTP_RESPONSE_BYTES>` — Set the maximum size in bytes of a received HTTP response
539541
* `--http-request-timeout-ms <HTTP_REQUEST_TIMEOUT_MS>` — Set the maximum amount of time allowed to wait for an HTTP response
540542
* `--http-request-allow-list <HTTP_REQUEST_ALLOW_LIST>` — Set the list of hosts that contracts and services can send HTTP requests to

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/Cargo.lock

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

linera-chain/Cargo.toml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,23 @@ repository.workspace = true
1212
version.workspace = true
1313

1414
[features]
15-
test = ["tokio/macros", "linera-base/test", "linera-execution/test"]
16-
metrics = ["prometheus", "linera-views/metrics", "linera-execution/metrics"]
17-
web = ["linera-base/web", "linera-views/web", "linera-execution/web"]
1815
benchmark = ["linera-base/test"]
16+
metrics = ["prometheus", "linera-views/metrics", "linera-execution/metrics"]
17+
test = [
18+
"dep:anyhow",
19+
"dep:axum",
20+
"tokio/macros",
21+
"linera-base/test",
22+
"linera-execution/test",
23+
]
1924
unstable-oracles = ["linera-execution/unstable-oracles"]
25+
web = ["linera-base/web", "linera-views/web", "linera-execution/web"]
2026

2127
[dependencies]
28+
anyhow = { workspace = true, optional = true }
2229
async-graphql.workspace = true
2330
async-trait.workspace = true
31+
axum = { workspace = true, optional = true }
2432
custom_debug_derive.workspace = true
2533
futures.workspace = true
2634
linera-base.workspace = true
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright (c) Zefchain Labs, Inc.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! A simple HTTP server to use for testing.
5+
6+
use std::{future::IntoFuture, net::Ipv4Addr};
7+
8+
use axum::Router;
9+
use futures::FutureExt as _;
10+
use tokio::{net::TcpListener, sync::oneshot};
11+
12+
/// A handle to a running HTTP server.
13+
///
14+
/// The server is gracefully shutdown when this handle is dropped.
15+
pub struct HttpServer {
16+
port: u16,
17+
_shutdown_sender: oneshot::Sender<()>,
18+
}
19+
20+
impl HttpServer {
21+
/// Spawns a task with an HTTP server serving the routes defined by the [`Router`].
22+
///
23+
/// Returns an [`HttpServer`] handle to keep the server running in the background.
24+
pub async fn start(router: Router) -> anyhow::Result<Self> {
25+
let (shutdown_sender, shutdown_receiver) = oneshot::channel();
26+
let shutdown_signal = shutdown_receiver.map(|_| ());
27+
28+
let listener = TcpListener::bind((Ipv4Addr::from([127, 0, 0, 1]), 0)).await?;
29+
let port = listener.local_addr()?.port();
30+
31+
tokio::spawn(
32+
axum::serve(listener, router)
33+
.with_graceful_shutdown(shutdown_signal)
34+
.into_future(),
35+
);
36+
37+
Ok(HttpServer {
38+
port,
39+
_shutdown_sender: shutdown_sender,
40+
})
41+
}
42+
43+
/// Returns the URL string this HTTP server is listening on.
44+
pub fn url(&self) -> String {
45+
format!("http://{}:{}", self.hostname(), self.port())
46+
}
47+
48+
/// Returns the hostname of this HTTP server.
49+
pub fn hostname(&self) -> String {
50+
"localhost".to_owned()
51+
}
52+
53+
/// Returns the port this HTTP server is listening on.
54+
pub fn port(&self) -> u16 {
55+
self.port
56+
}
57+
}

linera-chain/src/test.rs renamed to linera-chain/src/test/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
//! Test utilities
55
6+
mod http_server;
7+
68
use linera_base::{
79
crypto::{AccountPublicKey, AccountSecretKey},
810
data_types::{Amount, BlockHeight, Round, Timestamp},
@@ -15,6 +17,7 @@ use linera_execution::{
1517
Message, MessageKind, Operation, ResourceControlPolicy, SystemOperation,
1618
};
1719

20+
pub use self::http_server::HttpServer;
1821
use crate::{
1922
block::ConfirmedBlock,
2023
data_types::{

0 commit comments

Comments
 (0)