Skip to content

Commit

Permalink
Increase default maximum index size for non-regtest chains (ordinals#448
Browse files Browse the repository at this point in the history
)

The ordinal index, stored in <ORD_DATA_DIR>/index.redb, is a redb
database, which grows dynamically. However, the maximum size that the
database can grow to must be declared up-front, to avoid expensive
region allocation operations on insert. We've been using 10 MiB as the
default index size, which is too small for anything but testing.

This commit changes the default maximum index size to 1 TiB on mainnet,
testnet, and signet, and leaves it at 10 MiB on regtest. 1 TiB is more
than needed, as even the mainnet database is only ~50 GiB, but
allocating a database is fast enough, so it doesn't hurt to over
provision and not have to think about it. For testing though, which is
done with `--chain=regtest`, we want database allocation is fast, and 10
MiB is more than enough.
  • Loading branch information
casey committed Sep 2, 2022
1 parent d3ed942 commit 3e50a3f
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 7 deletions.
1 change: 0 additions & 1 deletion deploy/ord.service
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Environment=RUST_LOG=info
ExecStart=/usr/local/bin/ord \
--bitcoin-data-dir /var/lib/bitcoind \
--data-dir /var/lib/ord \
--max-index-size 1TiB \
--chain ${CHAIN} \
server \
--acme-contact mailto:[email protected] \
Expand Down
17 changes: 15 additions & 2 deletions src/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,22 @@ const TI: usize = GI << 10;
const PI: usize = TI << 10;
const EI: usize = PI << 10;

#[derive(Debug, Eq, PartialEq)]
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub(crate) struct Bytes(pub(crate) usize);

impl Bytes {
pub(crate) const MIB: Bytes = Bytes(MI);
pub(crate) const TIB: Bytes = Bytes(TI);
}

impl Mul<usize> for Bytes {
type Output = Bytes;

fn mul(self, rhs: usize) -> Self::Output {
Bytes(self.0 * rhs)
}
}

impl FromStr for Bytes {
type Err = Error;

Expand All @@ -35,7 +48,7 @@ impl FromStr for Bytes {
_ => return Err(anyhow!("invalid suffix")),
};

Ok(Bytes((value * multiple as f64) as usize))
Ok(Bytes((value * multiple as f64).ceil() as usize))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ impl Index {
Err(redb::Error::Io(error)) if error.kind() == io::ErrorKind::NotFound => unsafe {
Database::builder()
.set_write_strategy(WriteStrategy::Throughput)
.create(&database_path, options.max_index_size.0)?
.create(&database_path, options.max_index_size().0)?
},
Err(error) => return Err(error.into()),
};
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use {
fmt::{self, Display, Formatter},
fs, io,
net::ToSocketAddrs,
ops::{Add, AddAssign, Deref, Sub},
ops::{Add, AddAssign, Deref, Mul, Sub},
path::{Path, PathBuf},
process,
str::FromStr,
Expand Down
68 changes: 66 additions & 2 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ use {super::*, clap::ValueEnum};

#[derive(Debug, Parser)]
pub(crate) struct Options {
#[clap(long, default_value = "10MiB")]
pub(crate) max_index_size: Bytes,
#[clap(
long,
help = "Limit the ordinal index to <MAX_INDEX_SIZE> bytes. [mainnet, testnet, and signet default: 1 TiB, regtest default: 10 MiB]"
)]
pub(crate) max_index_size: Option<Bytes>,
#[clap(long)]
cookie_file: Option<PathBuf>,
#[clap(long)]
Expand Down Expand Up @@ -45,6 +48,13 @@ impl Chain {
}

impl Options {
pub(crate) fn max_index_size(&self) -> Bytes {
self.max_index_size.unwrap_or(match self.chain.network() {
Network::Regtest => Bytes::MIB * 10,
Network::Bitcoin | Network::Signet | Network::Testnet => Bytes::TIB,
})
}

pub(crate) fn rpc_url(&self) -> String {
self
.rpc_url
Expand Down Expand Up @@ -106,6 +116,60 @@ impl Options {
mod tests {
use {super::*, std::path::Path};

#[test]
fn max_index_size_defaults() {
assert_eq!(
Arguments::try_parse_from(&["ord", "index"])
.unwrap()
.options
.max_index_size(),
Bytes::TIB
);

assert_eq!(
Arguments::try_parse_from(&["ord", "--chain=mainnet", "index"])
.unwrap()
.options
.max_index_size(),
Bytes::TIB
);

assert_eq!(
Arguments::try_parse_from(&["ord", "--chain=signet", "index"])
.unwrap()
.options
.max_index_size(),
Bytes::TIB
);

assert_eq!(
Arguments::try_parse_from(&["ord", "--chain=testnet", "index"])
.unwrap()
.options
.max_index_size(),
Bytes::TIB
);

assert_eq!(
Arguments::try_parse_from(&["ord", "--chain=regtest", "index"])
.unwrap()
.options
.max_index_size(),
Bytes::MIB * 10
);
}

#[test]
fn max_index_size_override() {
assert_eq!(
Arguments::try_parse_from(&["ord", "--max-index-size=1", "index"])
.unwrap()
.options
.max_index_size(),
Bytes(1),
);
}

#[test]
fn rpc_url_overrides_network() {
assert_eq!(
Expand Down

0 comments on commit 3e50a3f

Please sign in to comment.