Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ jobs:
- name: Run tests (Bitcoin mode, REST+Electrum)
run: RUST_LOG=debug cargo test

test-bitcoin-28:
runs-on: ubuntu-22.04
steps:
- run: sudo apt-get update && sudo apt-get install libfuse2
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@1.75.0
- uses: Swatinem/rust-cache@v2
- name: Download bitcoind 28.0
run: |
curl -sSL https://bitcoincore.org/bin/bitcoin-core-28.0/bitcoin-28.0-x86_64-linux-gnu.tar.gz | tar -xz
chmod +x bitcoin-28.0/bin/bitcoind
- name: Run tests (Bitcoin 28.0, REST+Electrum)
run: RUST_LOG=debug cargo test --features bitcoind_28_0
env:
BITCOIND_EXE: ${{ github.workspace }}/bitcoin-28.0/bin/bitcoind

test-electrum-raw:
runs-on: ubuntu-22.04
steps:
Expand Down
44 changes: 37 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ version = "0.4.1"
authors = ["Roman Zeyde <me@romanzey.de>"]
description = "An efficient re-implementation of Electrum Server in Rust"
license = "MIT"
homepage = "https://github.com/romanz/electrs"
repository = "https://github.com/romanz/electrs"
homepage = "https://github.com/blockstream/electrs"
repository = "https://github.com/blockstream/electrs"
keywords = ["bitcoin", "electrum", "server", "index", "database"]
documentation = "https://docs.rs/electrs/"
readme = "README.md"
edition = "2018"
default-run = "electrs"
Expand All @@ -27,13 +26,14 @@ otlp-tracing = [
"opentelemetry-semantic-conventions",
"electrs_macros/otlp-tracing"
]
bitcoind_28_0 = []

[dependencies]
arraydeque = "0.5.1"
arrayref = "0.3.6"
base64 = "0.22"
bincode = "1.3.1"
bitcoin = { version = "0.32", features = ["serde"] }
bitcoin = { version = "0.32.4", features = ["serde"] }
clap = "2.33.3"
crossbeam-channel = "0.5.0"
dirs = "5.0.1"
Expand Down Expand Up @@ -70,6 +70,7 @@ opentelemetry-otlp = { version = "0.13.0", default-features = false, features =
tracing-subscriber = { version = "0.3.17", default-features = false, features = ["env-filter", "fmt"], optional = true }
opentelemetry-semantic-conventions = { version = "0.12.0", optional = true }
tracing = { version = "0.1.40", default-features = false, features = ["attributes"], optional = true }
rand = "0.9.1"

# optional dependencies for electrum-discovery
electrum-client = { version = "0.8", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion doc/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ and [latest Electrum wallet](https://electrum.org/#download) (3.2+).
Also, install the following packages (on Debian):
```bash
$ sudo apt update
$ sudo apt install clang cmake # for building 'rust-rocksdb'
$ sudo apt install clang cmake build-essential # for building 'rust-rocksdb'
```

## Build
Expand Down
3 changes: 1 addition & 2 deletions electrs_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use proc_macro::TokenStream;


#[proc_macro_attribute]
#[cfg(feature = "otlp-tracing")]
pub fn trace(attr: TokenStream, item: TokenStream) -> TokenStream {
Expand Down Expand Up @@ -32,4 +31,4 @@ pub fn trace(attr: TokenStream, item: TokenStream) -> TokenStream {
#[cfg(not(feature = "otlp-tracing"))]
pub fn trace(_attr: TokenStream, item: TokenStream) -> TokenStream {
item
}
}
32 changes: 12 additions & 20 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 56 additions & 6 deletions src/bin/electrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ extern crate electrs;

use crossbeam_channel::{self as channel};
use error_chain::ChainedError;
use std::process;
use std::{env, process, thread};
use std::sync::{Arc, RwLock};
use std::time::Duration;

use bitcoin::hex::DisplayHex;
use rand::{rng, RngCore};
use electrs::{
config::Config,
daemon::Daemon,
Expand All @@ -28,6 +29,9 @@ use electrs::otlp_trace;
use electrs::elements::AssetRegistry;
use electrs::metrics::MetricOpts;

/// Default salt rotation interval in seconds (24 hours)
const DEFAULT_SALT_ROTATION_INTERVAL_SECS: u64 = 24 * 3600;

fn fetch_from(config: &Config, store: &Store) -> FetchFrom {
let mut jsonrpc_import = config.jsonrpc_import;
if !jsonrpc_import {
Expand All @@ -44,7 +48,7 @@ fn fetch_from(config: &Config, store: &Store) -> FetchFrom {
}
}

fn run_server(config: Arc<Config>) -> Result<()> {
fn run_server(config: Arc<Config>, salt_rwlock: Arc<RwLock<String>>) -> Result<()> {
let (block_hash_notify, block_hash_receive) = channel::bounded(1);
let signal = Waiter::start(block_hash_receive);
let metrics = Metrics::new(config.monitoring_addr);
Expand All @@ -64,7 +68,7 @@ fn run_server(config: Arc<Config>) -> Result<()> {
signal.clone(),
&metrics,
)?);
let store = Arc::new(Store::open(&config.db_path.join("newindex"), &config));
let store = Arc::new(Store::open(&config.db_path.join("newindex"), &config, &metrics));
let mut indexer = Indexer::open(
Arc::clone(&store),
fetch_from(&config, &store),
Expand Down Expand Up @@ -116,7 +120,12 @@ fn run_server(config: Arc<Config>) -> Result<()> {

// TODO: configuration for which servers to start
let rest_server = rest::start(Arc::clone(&config), Arc::clone(&query));
let electrum_server = ElectrumRPC::start(Arc::clone(&config), Arc::clone(&query), &metrics);
let electrum_server = ElectrumRPC::start(
Arc::clone(&config),
Arc::clone(&query),
&metrics,
Arc::clone(&salt_rwlock),
);

let main_loop_count = metrics.gauge(MetricOpts::new(
"electrs_main_loop_count",
Expand Down Expand Up @@ -151,9 +160,50 @@ fn run_server(config: Arc<Config>) -> Result<()> {
Ok(())
}

fn generate_salt() -> String {
let mut random_bytes = [0u8; 32];
rng().fill_bytes(&mut random_bytes);
random_bytes.to_lower_hex_string()
}

fn rotate_salt(salt: &mut String) {
*salt = generate_salt();
}

fn get_salt_rotation_interval() -> Duration {
let var_name = "SALT_ROTATION_INTERVAL_SECS";
let secs = env::var(var_name)
.ok()
.and_then(|val| val.parse::<u64>().ok())
.unwrap_or(DEFAULT_SALT_ROTATION_INTERVAL_SECS);

Duration::from_secs(secs)
}

fn spawn_salt_rotation_thread() -> Arc<RwLock<String>> {
let salt = generate_salt();
let salt_rwlock = Arc::new(RwLock::new(salt));
let writer_arc = Arc::clone(&salt_rwlock);
let interval = get_salt_rotation_interval();

thread::spawn(move || {
loop {
thread::sleep(interval); // 24 hours
{
let mut guard = writer_arc.write().unwrap();
rotate_salt(&mut *guard);
info!("Salt rotated");
}
}
});
salt_rwlock
}

fn main_() {
let salt_rwlock = spawn_salt_rotation_thread();

let config = Arc::new(Config::from_args());
if let Err(e) = run_server(config) {
if let Err(e) = run_server(config, Arc::clone(&salt_rwlock)) {
error!("server failed: {}", e.display_chain());
process::exit(1);
}
Expand Down
7 changes: 3 additions & 4 deletions src/bin/popular-scripts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ extern crate electrs;

use bitcoin::hex::DisplayHex;
use electrs::{
config::Config,
new_index::{Store, TxHistoryKey},
util::bincode,
config::Config, metrics::Metrics, new_index::{Store, TxHistoryKey}, util::bincode
};

fn main() {
let config = Config::from_args();
let store = Store::open(&config.db_path.join("newindex"), &config);
let metrics = Metrics::new(config.monitoring_addr);
let store = Store::open(&config.db_path.join("newindex"), &config, &metrics);

let mut iter = store.history_db().raw_iterator();
iter.seek(b"H");
Expand Down
Loading
Loading