diff --git a/.gitignore b/.gitignore index 75e839a..b210a01 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ target /test-lmdb/ core-blocks data-bench +data-bench2 +tmp Cargo.lock launch.json @@ -16,3 +18,4 @@ data/ bitcrust.iml store/tst-* + diff --git a/Cargo.toml b/Cargo.toml index 59b2bbb..cf27669 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,10 +16,8 @@ itertools = "0.5.1" memmap = "0.4" libc = "0.2.30" rand = "0.3" -ring = "0.12" - -serde = "1" -serde_derive = "1" +ring = "0.16" +serde = { version = "1.0", features = ["derive"] } toml = "0.4" slog = { version = "1.3.2", features = ["max_level_trace", "release_max_level_info"] } @@ -45,3 +43,5 @@ default = [] [workspace] members = [ "bitcrustd", "monitor", "net", "encode-derive", "store", "hashstore"] + + diff --git a/bitcrustd/Cargo.toml b/bitcrustd/Cargo.toml index 274eab4..9311006 100644 --- a/bitcrustd/Cargo.toml +++ b/bitcrustd/Cargo.toml @@ -8,15 +8,17 @@ bitcrust-net = {path = "../net"} store = {path = "../store"} clap = "~2.25" simple_logger = "*" -log = "0.3" +log = "0.4" multiqueue = "~0.3.2" -ring = "0.12" +ring = "0.16" serde_derive = "1.0" serde = "1.0" toml = "0.4" -rusqlite = "~0.11" +# rusqlite = "~0.11" +rusqlite = "0.24.2" -serde_json = {path = "../serde_json"} +# serde_json = {path = "../serde_json"} +serde_json = "1.0.64" [dev-dependencies] tempfile = "2.2" diff --git a/bitcrustd/src/config.rs b/bitcrustd/src/config.rs index 1331fc3..451a61c 100644 --- a/bitcrustd/src/config.rs +++ b/bitcrustd/src/config.rs @@ -5,7 +5,7 @@ use std::io::{Read, Write}; use std::path::PathBuf; use clap::{App, Arg, ArgMatches, SubCommand}; -use log::LogLevel; +use log::Level; use ring::{digest, rand, hmac}; use ring::rand::SecureRandom; use toml; @@ -53,19 +53,19 @@ pub struct ConfigFile { } pub struct Config { - pub log_level: LogLevel, + pub log_level: Level, pub data_dir: PathBuf, raw_key: [u8; 32], - signing_key: hmac::SigningKey, + signing_key: hmac::Key, } impl<'a, 'b> Config { pub fn from_args(matches: &ArgMatches) -> Config { let log_level = match matches.occurrences_of("debug") { - 0 => LogLevel::Warn, - 1 => LogLevel::Info, - 2 => LogLevel::Debug, - 3 | _ => LogLevel::Trace, + 0 => Level::Warn, + 1 => Level::Info, + 2 => Level::Debug, + 3 | _ => Level::Trace, }; let config_file_path: PathBuf = matches.value_of("config").map(|p| PathBuf::from(&p)).unwrap_or_else(|| { let mut path = home_dir().expect("Can't figure out where your $HOME is"); @@ -81,7 +81,7 @@ impl<'a, 'b> Config { Config::create_default(config_file_path) }; - let key = hmac::SigningKey::new(&digest::SHA256, &config_from_file.key); + let key = hmac::Key::new(hmac::HMAC_SHA256, &config_from_file.key); let data_dir = PathBuf::from(&config_from_file.data_dir); let mut a: [u8; 32] = [0; 32]; @@ -160,7 +160,7 @@ impl<'a, 'b> Config { c } - pub fn key(&self) -> &hmac::SigningKey { + pub fn key(&self) -> &hmac::Key { &self.signing_key } } @@ -170,7 +170,7 @@ impl Clone for Config { Config { log_level: self.log_level, raw_key: self.raw_key, - signing_key: hmac::SigningKey::new(&digest::SHA256, &self.raw_key), + signing_key: hmac::Key::new(hmac::HMAC_SHA256, &self.raw_key), data_dir: self.data_dir.clone() } } diff --git a/bitcrustd/src/peer_manager.rs b/bitcrustd/src/peer_manager.rs index a52d94b..52a03a3 100644 --- a/bitcrustd/src/peer_manager.rs +++ b/bitcrustd/src/peer_manager.rs @@ -8,7 +8,7 @@ use std::str::FromStr; use std::thread; use multiqueue::{BroadcastReceiver, BroadcastSender, broadcast_queue}; -use rusqlite::{Error, Connection}; +use rusqlite::{Error, Connection, NO_PARAMS}; use bitcrust_net::{NetAddr, Services}; use client_message::ClientMessage; @@ -45,7 +45,7 @@ impl PeerManager { \ port INTEGER );", - &[]) + NO_PARAMS) .unwrap(); let addrs: HashSet = { @@ -54,14 +54,14 @@ impl PeerManager { limit 1000") .unwrap(); - let addrs: HashSet = stmt.query_map(&[], |row| { - NetAddr { - time: Some(row.get(0)), - services: Services::from(row.get::<_, i64>(1) as u64), - ip: Ipv6Addr::from_str(&row.get::<_, String>(2)) + let addrs: HashSet = stmt.query_map(NO_PARAMS, |row| { + Ok( NetAddr { + time: Some(row.get(0).unwrap_or(0u32)), + services: Services::from(row.get::<_, i64>(1).unwrap_or(0i64) as u64), + ip: Ipv6Addr::from_str(&row.get::<_, String>(2).unwrap_or("".to_string())) .unwrap_or(Ipv6Addr::from_str("::").unwrap()), - port: row.get(3), - } + port: row.get(3).unwrap_or(0u16), + }) }) .unwrap() .filter_map(|l| l.ok()) diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..83df5da --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +fn main() { + println!("cargo:rustc-link-search=/usr/local/Cellar/bitcoin/0.21.0/lib\n\ + cargo:rustc-link-lib=dylib=bitcoinconsensus"); +} \ No newline at end of file diff --git a/contrib/bitcoind.Dockerfile b/contrib/bitcoind.Dockerfile new file mode 100644 index 0000000..b7bce10 --- /dev/null +++ b/contrib/bitcoind.Dockerfile @@ -0,0 +1,19 @@ +FROM ubuntu:20.04 + +ENV DEBIAN_FRONTEND=noninteractive + +COPY contrib/bitcoind /usr/src/bitcoind + +WORKDIR /usr/src/bitcoind + +RUN /bin/bash /usr/src/bitcoind/install.sh dep +RUN /bin/bash /usr/src/bitcoind/install.sh bitcoind +RUN /bin/bash /usr/src/bitcoind/install.sh run +RUN /bin/bash /usr/src/bitcoind/install.sh user +RUN /bin/bash /usr/src/bitcoind/install.sh conf + +WORKDIR /home/bitcoinduser + +USER bitcoinduser + +CMD ["/usr/local/bin/run.sh"] \ No newline at end of file diff --git a/contrib/bitcoind/bitcoind.conf b/contrib/bitcoind/bitcoind.conf new file mode 100644 index 0000000..9da4ddd --- /dev/null +++ b/contrib/bitcoind/bitcoind.conf @@ -0,0 +1,97 @@ +#start in background +daemon=1 + +#select network -- comment out both for mainnet +#testnet=1 +#stn=1 +regtest=1 + +#Required Consensus Rules for Genesis +excessiveblocksize=10000000000 #10GB +maxstackmemoryusageconsensus=100000000 #100MB + +#Mining +#biggest block size you want to mine +blockmaxsize=4000000000 +blockassembler=journaling #journaling is default as of 1.0.5 + +#preload mempool +preload=1 + +#mempool usage allowance +maxmempool=8000 #8G +dbcache=8192 #8G + +#Pruning -- Uncomment to trim the chain in an effort to keep disk usage below the figure set +#prune=100000 #100GB + +#orphan transaction storage +#blockreconstructionextratxn=200000 +#maxorphantxsize=10000 + +#transaction options +#maxsigcachesize=260 +#maxscriptcachesize=260 +#minrelaytxfee=0.00000001 +#mintxfee=0.00000001 +#dustrelayfee=0.00000001 +#blockmintxfee=0.00000001 +#relaypriority=0 +#feefilter=0 +#limitfreerelay=1000 +#maxscriptsizepolicy=500000 + +#OP Return max size +#datacarriersize=100000 #Genesis default is UINT32_MAX + +#Max number and size of related Child and Parent transactions per block template +limitancestorcount=100 +limitdescendantcount=100 +#limitancestorsize=25000000 +#limitdescendantsize=25000000 + +#connection options +maxconnections=80 + +#ZMQ +zmqpubhashtx=tcp://127.0.0.1:28332 +zmqpubhashblock=tcp://127.0.0.1:28332 + +#Ports - Leave commented for defaults +#port=9333 +#rpcport=9332 + +#rpc settings +rpcworkqueue=600 +rpcthreads=16 +rpcallowip=0.0.0.0/0 +rpcuser=appuser +rpcpassword=abc123 + +#debug options +#can be: net, tor, +# mempool, http, bench, zmq, db, rpc, addrman, selectcoins, +# reindex, cmpctblock, rand, prune, proxy, mempoolrej, libevent, +# coindb, leveldb, txnprop, txnsrc, journal, txnval. +# 1 = all options enabled. +# 0 = off which is default +debug=1 + +#debugexclude to ignore set log items, can be used to keep log file a bit cleaner +debugexclude=libevent +debugexclude=leveldb +debugexclude=zmq +debugexclude=txnsrc +debugexclude=net + +#shrinkdebugfile=0 # Setting to 1 prevents bitcoind from clearning the log file on restart. 0/off is default + +#multi-threaded options +#threadsperblock=32 +#maxparallelblocks +#scriptvalidatormaxbatchsize +#maxparallelblocksperpeer +maxstdtxvalidationduration=15 +maxcollectedoutpoints=1000000 +maxstdtxnsperthreadratio=10000 +#maxnonstdtxvalidationduration \ No newline at end of file diff --git a/contrib/bitcoind/install.sh b/contrib/bitcoind/install.sh new file mode 100644 index 0000000..49bb286 --- /dev/null +++ b/contrib/bitcoind/install.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +set -e + + +decho(){ + 1>&2 echo $@ +} + +install_dep(){ + apt-get update + apt-get install -y wget +} + +install_bitcoind(){ + TMPDIR=$(mktemp --dir) + cd $TMPDIR + wget https://download.bitcoinsv.io/bitcoinsv/1.0.5/bitcoin-sv-1.0.5-x86_64-linux-gnu.tar.gz + sha256sum bitcoin-sv-1.0.5-x86_64-linux-gnu.tar.gz | grep 96f7c56c7ebd4ecb2dcd664297fcf0511169ac33eaf216407ebc49dae2535578 + tar xvf bitcoin-sv-1.0.5-x86_64-linux-gnu.tar.gz + ln -s bitcoin-sv-1.0.5 bitcoin + install -m 0755 bitcoin/bin/* /usr/local/bin + chmod +x /usr/local/bin/* + rm -rf $TMPDIR +} + +install_conf(){ + mkdir -p /etc/bitcoind/ + cp bitcoind.conf /etc/bitcoind/bitcoind.conf +} + +install_run(){ + install -m 0755 run.sh /usr/local/bin +} + +user_create(){ + useradd -ms /bin/bash bitcoinduser + mkdir /home/bitcoinduser/data + chown -R bitcoinduser:bitcoinduser /home/bitcoinduser/data +} + + +case $1 in + dep) + ( install_dep ) + ;; + bitcoind) + ( install_bitcoind ) + ;; + run) + ( install_run ) + ;; + user) + ( user_create ) + ;; + conf) + ( install_conf ) + ;; +esac \ No newline at end of file diff --git a/contrib/bitcoind/run.sh b/contrib/bitcoind/run.sh new file mode 100644 index 0000000..dd49968 --- /dev/null +++ b/contrib/bitcoind/run.sh @@ -0,0 +1,12 @@ +#!/bin/bash + + +decho(){ + 1>&2 echo $@ +} + +run_daemon(){ + exec /usr/local/bin/bitcoind -conf=/etc/bitcoind/bitcoind.conf -datadir=/home/bitcoinduser/data -daemon +} + +run_daemon \ No newline at end of file diff --git a/contrib/bitcrust.Dockerfile b/contrib/bitcrust.Dockerfile new file mode 100644 index 0000000..6cee6af --- /dev/null +++ b/contrib/bitcrust.Dockerfile @@ -0,0 +1,8 @@ +FROM rustlang/rust:nightly as builder +WORKDIR /usr/src/app +COPY . . +# RUN cargo install cargo-travis +RUN export PATH=$HOME/.cargo/bin:$PATH +# RUN cargo rustc -- -Awarnings +RUN cargo build --all --verbose --color always +# RUN cargo coveralls --exclude-pattern tests/,script/,bitcoin/src/,encode-derive/ --all \ No newline at end of file diff --git a/contrib/install.sh b/contrib/install.sh new file mode 100644 index 0000000..126a8f6 --- /dev/null +++ b/contrib/install.sh @@ -0,0 +1,606 @@ +#!/bin/sh +# shellcheck shell=dash + +# This is just a little script that can be downloaded from the internet to +# install rustup. It just does platform detection, downloads the installer +# and runs it. + +# It runs on Unix shells like {a,ba,da,k,z}sh. It uses the common `local` +# extension. Note: Most shells limit `local` to 1 var per line, contra bash. + +if [ "$KSH_VERSION" = 'Version JM 93t+ 2010-03-05' ]; then + # The version of ksh93 that ships with many illumos systems does not + # support the "local" extension. Print a message rather than fail in + # subtle ways later on: + echo 'rustup does not work with this ksh93 version; please try bash!' >&2 + exit 1 +fi + + +set -u + +# If RUSTUP_UPDATE_ROOT is unset or empty, default it. +RUSTUP_UPDATE_ROOT="${RUSTUP_UPDATE_ROOT:-https://static.rust-lang.org/rustup}" + +#XXX: If you change anything here, please make the same changes in setup_mode.rs +usage() { + cat 1>&2 < Choose a default host triple + --default-toolchain Choose a default toolchain to install + --default-toolchain none Do not install any toolchains + --profile [minimal|default|complete] Choose a profile + -c, --component ... Component name to also install + -t, --target ... Target name to also install +EOF +} + +main() { + downloader --check + need_cmd uname + need_cmd mktemp + need_cmd chmod + need_cmd mkdir + need_cmd rm + need_cmd rmdir + + get_architecture || return 1 + local _arch="$RETVAL" + assert_nz "$_arch" "arch" + + local _ext="" + case "$_arch" in + *windows*) + _ext=".exe" + ;; + esac + + local _url="${RUSTUP_UPDATE_ROOT}/dist/${_arch}/rustup-init${_ext}" + + local _dir + _dir="$(mktemp -d 2>/dev/null || ensure mktemp -d -t rustup)" + local _file="${_dir}/rustup-init${_ext}" + + local _ansi_escapes_are_valid=false + if [ -t 2 ]; then + if [ "${TERM+set}" = 'set' ]; then + case "$TERM" in + xterm*|rxvt*|urxvt*|linux*|vt*) + _ansi_escapes_are_valid=true + ;; + esac + fi + fi + + # check if we have to use /dev/tty to prompt the user + local need_tty=yes + for arg in "$@"; do + case "$arg" in + -h|--help) + usage + exit 0 + ;; + -y) + # user wants to skip the prompt -- we don't need /dev/tty + need_tty=no + ;; + *) + ;; + esac + done + + if $_ansi_escapes_are_valid; then + printf "\33[1minfo:\33[0m downloading installer\n" 1>&2 + else + printf '%s\n' 'info: downloading installer' 1>&2 + fi + + ensure mkdir -p "$_dir" + ensure downloader "$_url" "$_file" "$_arch" + ensure chmod u+x "$_file" + if [ ! -x "$_file" ]; then + printf '%s\n' "Cannot execute $_file (likely because of mounting /tmp as noexec)." 1>&2 + printf '%s\n' "Please copy the file to a location where you can execute binaries and run ./rustup-init${_ext}." 1>&2 + exit 1 + fi + + if [ "$need_tty" = "yes" ]; then + # The installer is going to want to ask for confirmation by + # reading stdin. This script was piped into `sh` though and + # doesn't have stdin to pass to its children. Instead we're going + # to explicitly connect /dev/tty to the installer's stdin. + if [ ! -t 1 ]; then + err "Unable to run interactively. Run with -y to accept defaults, --help for additional options" + fi + + ignore "$_file" "$@" < /dev/tty + else + ignore "$_file" "$@" + fi + + local _retval=$? + + ignore rm "$_file" + ignore rmdir "$_dir" + + return "$_retval" +} + +get_bitness() { + need_cmd head + # Architecture detection without dependencies beyond coreutils. + # ELF files start out "\x7fELF", and the following byte is + # 0x01 for 32-bit and + # 0x02 for 64-bit. + # The printf builtin on some shells like dash only supports octal + # escape sequences, so we use those. + local _current_exe_head + _current_exe_head=$(head -c 5 /proc/self/exe ) + if [ "$_current_exe_head" = "$(printf '\177ELF\001')" ]; then + echo 32 + elif [ "$_current_exe_head" = "$(printf '\177ELF\002')" ]; then + echo 64 + else + err "unknown platform bitness" + fi +} + +get_endianness() { + local cputype=$1 + local suffix_eb=$2 + local suffix_el=$3 + + # detect endianness without od/hexdump, like get_bitness() does. + need_cmd head + need_cmd tail + + local _current_exe_endianness + _current_exe_endianness="$(head -c 6 /proc/self/exe | tail -c 1)" + if [ "$_current_exe_endianness" = "$(printf '\001')" ]; then + echo "${cputype}${suffix_el}" + elif [ "$_current_exe_endianness" = "$(printf '\002')" ]; then + echo "${cputype}${suffix_eb}" + else + err "unknown platform endianness" + fi +} + +get_architecture() { + local _ostype _cputype _bitness _arch _clibtype + _ostype="$(uname -s)" + _cputype="$(uname -m)" + _clibtype="gnu" + + if [ "$_ostype" = Linux ]; then + if [ "$(uname -o)" = Android ]; then + _ostype=Android + fi + if ldd --version 2>&1 | grep -q 'musl'; then + _clibtype="musl" + fi + fi + + if [ "$_ostype" = Darwin ] && [ "$_cputype" = i386 ]; then + # Darwin `uname -m` lies + if sysctl hw.optional.x86_64 | grep -q ': 1'; then + _cputype=x86_64 + fi + fi + + if [ "$_ostype" = SunOS ]; then + # Both Solaris and illumos presently announce as "SunOS" in "uname -s" + # so use "uname -o" to disambiguate. We use the full path to the + # system uname in case the user has coreutils uname first in PATH, + # which has historically sometimes printed the wrong value here. + if [ "$(/usr/bin/uname -o)" = illumos ]; then + _ostype=illumos + fi + + # illumos systems have multi-arch userlands, and "uname -m" reports the + # machine hardware name; e.g., "i86pc" on both 32- and 64-bit x86 + # systems. Check for the native (widest) instruction set on the + # running kernel: + if [ "$_cputype" = i86pc ]; then + _cputype="$(isainfo -n)" + fi + fi + + case "$_ostype" in + + Android) + _ostype=linux-android + ;; + + Linux) + _ostype=unknown-linux-$_clibtype + _bitness=$(get_bitness) + ;; + + FreeBSD) + _ostype=unknown-freebsd + ;; + + NetBSD) + _ostype=unknown-netbsd + ;; + + DragonFly) + _ostype=unknown-dragonfly + ;; + + Darwin) + _ostype=apple-darwin + ;; + + illumos) + _ostype=unknown-illumos + ;; + + MINGW* | MSYS* | CYGWIN*) + _ostype=pc-windows-gnu + ;; + + *) + err "unrecognized OS type: $_ostype" + ;; + + esac + + case "$_cputype" in + + i386 | i486 | i686 | i786 | x86) + _cputype=i686 + ;; + + xscale | arm) + _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + fi + ;; + + armv6l) + _cputype=arm + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + + armv7l | armv8l) + _cputype=armv7 + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + + aarch64 | arm64) + _cputype=aarch64 + ;; + + x86_64 | x86-64 | x64 | amd64) + _cputype=x86_64 + ;; + + mips) + _cputype=$(get_endianness mips '' el) + ;; + + mips64) + if [ "$_bitness" -eq 64 ]; then + # only n64 ABI is supported for now + _ostype="${_ostype}abi64" + _cputype=$(get_endianness mips64 '' el) + fi + ;; + + ppc) + _cputype=powerpc + ;; + + ppc64) + _cputype=powerpc64 + ;; + + ppc64le) + _cputype=powerpc64le + ;; + + s390x) + _cputype=s390x + ;; + riscv64) + _cputype=riscv64gc + ;; + *) + err "unknown CPU type: $_cputype" + + esac + + # Detect 64-bit linux with 32-bit userland + if [ "${_ostype}" = unknown-linux-gnu ] && [ "${_bitness}" -eq 32 ]; then + case $_cputype in + x86_64) + _cputype=i686 + ;; + mips64) + _cputype=$(get_endianness mips '' el) + ;; + powerpc64) + _cputype=powerpc + ;; + aarch64) + _cputype=armv7 + if [ "$_ostype" = "linux-android" ]; then + _ostype=linux-androideabi + else + _ostype="${_ostype}eabihf" + fi + ;; + riscv64gc) + err "riscv64 with 32-bit userland unsupported" + ;; + esac + fi + + # Detect armv7 but without the CPU features Rust needs in that build, + # and fall back to arm. + # See https://github.com/rust-lang/rustup.rs/issues/587. + if [ "$_ostype" = "unknown-linux-gnueabihf" ] && [ "$_cputype" = armv7 ]; then + if ensure grep '^Features' /proc/cpuinfo | grep -q -v neon; then + # At least one processor does not have NEON. + _cputype=arm + fi + fi + + _arch="${_cputype}-${_ostype}" + + RETVAL="$_arch" +} + +say() { + printf 'rustup: %s\n' "$1" +} + +err() { + say "$1" >&2 + exit 1 +} + +need_cmd() { + if ! check_cmd "$1"; then + err "need '$1' (command not found)" + fi +} + +check_cmd() { + command -v "$1" > /dev/null 2>&1 +} + +assert_nz() { + if [ -z "$1" ]; then err "assert_nz $2"; fi +} + +# Run a command that should never fail. If the command fails execution +# will immediately terminate with an error showing the failing +# command. +ensure() { + if ! "$@"; then err "command failed: $*"; fi +} + +# This is just for indicating that commands' results are being +# intentionally ignored. Usually, because it's being executed +# as part of error handling. +ignore() { + "$@" +} + +# This wraps curl or wget. Try curl first, if not installed, +# use wget instead. +downloader() { + local _dld + local _ciphersuites + local _err + local _status + if check_cmd curl; then + _dld=curl + elif check_cmd wget; then + _dld=wget + else + _dld='curl or wget' # to be used in error message of need_cmd + fi + + if [ "$1" = --check ]; then + need_cmd "$_dld" + elif [ "$_dld" = curl ]; then + get_ciphersuites_for_curl + _ciphersuites="$RETVAL" + if [ -n "$_ciphersuites" ]; then + _err=$(curl --proto '=https' --tlsv1.2 --ciphers "$_ciphersuites" --silent --show-error --fail --location "$1" --output "$2" 2>&1) + _status=$? + else + echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure" + if ! check_help_for "$3" curl --proto --tlsv1.2; then + echo "Warning: Not enforcing TLS v1.2, this is potentially less secure" + _err=$(curl --silent --show-error --fail --location "$1" --output "$2" 2>&1) + _status=$? + else + _err=$(curl --proto '=https' --tlsv1.2 --silent --show-error --fail --location "$1" --output "$2" 2>&1) + _status=$? + fi + fi + if [ -n "$_err" ]; then + echo "$_err" >&2 + if echo "$_err" | grep -q 404$; then + err "installer for platform '$3' not found, this may be unsupported" + fi + fi + return $_status + elif [ "$_dld" = wget ]; then + get_ciphersuites_for_wget + _ciphersuites="$RETVAL" + if [ -n "$_ciphersuites" ]; then + _err=$(wget --https-only --secure-protocol=TLSv1_2 --ciphers "$_ciphersuites" "$1" -O "$2" 2>&1) + _status=$? + else + echo "Warning: Not enforcing strong cipher suites for TLS, this is potentially less secure" + if ! check_help_for "$3" wget --https-only --secure-protocol; then + echo "Warning: Not enforcing TLS v1.2, this is potentially less secure" + _err=$(wget "$1" -O "$2" 2>&1) + _status=$? + else + _err=$(wget --https-only --secure-protocol=TLSv1_2 "$1" -O "$2" 2>&1) + _status=$? + fi + fi + if [ -n "$_err" ]; then + echo "$_err" >&2 + if echo "$_err" | grep -q ' 404 Not Found$'; then + err "installer for platform '$3' not found, this may be unsupported" + fi + fi + return $_status + else + err "Unknown downloader" # should not reach here + fi +} + +check_help_for() { + local _arch + local _cmd + local _arg + _arch="$1" + shift + _cmd="$1" + shift + + case "$_arch" in + + # If we're running on OS-X, older than 10.13, then we always + # fail to find these options to force fallback + *darwin*) + if check_cmd sw_vers; then + if [ "$(sw_vers -productVersion | cut -d. -f2)" -lt 13 ]; then + # Older than 10.13 + echo "Warning: Detected OS X platform older than 10.13" + return 1 + fi + fi + ;; + + esac + + for _arg in "$@"; do + if ! "$_cmd" --help | grep -q -- "$_arg"; then + return 1 + fi + done + + true # not strictly needed +} + +# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites +# if support by local tools is detected. Detection currently supports these curl backends: +# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty. +get_ciphersuites_for_curl() { + if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then + # user specified custom cipher suites, assume they know what they're doing + RETVAL="$RUSTUP_TLS_CIPHERSUITES" + return + fi + + local _openssl_syntax="no" + local _gnutls_syntax="no" + local _backend_supported="yes" + if curl -V | grep -q ' OpenSSL/'; then + _openssl_syntax="yes" + elif curl -V | grep -iq ' LibreSSL/'; then + _openssl_syntax="yes" + elif curl -V | grep -iq ' BoringSSL/'; then + _openssl_syntax="yes" + elif curl -V | grep -iq ' GnuTLS/'; then + _gnutls_syntax="yes" + else + _backend_supported="no" + fi + + local _args_supported="no" + if [ "$_backend_supported" = "yes" ]; then + # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc. + if check_help_for "notspecified" "curl" "--tlsv1.2" "--ciphers" "--proto"; then + _args_supported="yes" + fi + fi + + local _cs="" + if [ "$_args_supported" = "yes" ]; then + if [ "$_openssl_syntax" = "yes" ]; then + _cs=$(get_strong_ciphersuites_for "openssl") + elif [ "$_gnutls_syntax" = "yes" ]; then + _cs=$(get_strong_ciphersuites_for "gnutls") + fi + fi + + RETVAL="$_cs" +} + +# Return cipher suite string specified by user, otherwise return strong TLS 1.2-1.3 cipher suites +# if support by local tools is detected. Detection currently supports these wget backends: +# GnuTLS and OpenSSL (possibly also LibreSSL and BoringSSL). Return value can be empty. +get_ciphersuites_for_wget() { + if [ -n "${RUSTUP_TLS_CIPHERSUITES-}" ]; then + # user specified custom cipher suites, assume they know what they're doing + RETVAL="$RUSTUP_TLS_CIPHERSUITES" + return + fi + + local _cs="" + if wget -V | grep -q '\-DHAVE_LIBSSL'; then + # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc. + if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then + _cs=$(get_strong_ciphersuites_for "openssl") + fi + elif wget -V | grep -q '\-DHAVE_LIBGNUTLS'; then + # "unspecified" is for arch, allows for possibility old OS using macports, homebrew, etc. + if check_help_for "notspecified" "wget" "TLSv1_2" "--ciphers" "--https-only" "--secure-protocol"; then + _cs=$(get_strong_ciphersuites_for "gnutls") + fi + fi + + RETVAL="$_cs" +} + +# Return strong TLS 1.2-1.3 cipher suites in OpenSSL or GnuTLS syntax. TLS 1.2 +# excludes non-ECDHE and non-AEAD cipher suites. DHE is excluded due to bad +# DH params often found on servers (see RFC 7919). Sequence matches or is +# similar to Firefox 68 ESR with weak cipher suites disabled via about:config. +# $1 must be openssl or gnutls. +get_strong_ciphersuites_for() { + if [ "$1" = "openssl" ]; then + # OpenSSL is forgiving of unknown values, no problems with TLS 1.3 values on versions that don't support it yet. + echo "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384" + elif [ "$1" = "gnutls" ]; then + # GnuTLS isn't forgiving of unknown values, so this may require a GnuTLS version that supports TLS 1.3 even if wget doesn't. + # Begin with SECURE128 (and higher) then remove/add to build cipher suites. Produces same 9 cipher suites as OpenSSL but in slightly different order. + echo "SECURE128:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-DTLS-ALL:-CIPHER-ALL:-MAC-ALL:-KX-ALL:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+AES-128-GCM:+CHACHA20-POLY1305:+AES-256-GCM" + fi +} + +main "$@" || exit 1 diff --git a/hashstore/src/hashstore.rs b/hashstore/src/hashstore.rs index 12a6e6e..8c19cd3 100644 --- a/hashstore/src/hashstore.rs +++ b/hashstore/src/hashstore.rs @@ -291,10 +291,8 @@ impl HashStore { let new_ptr = write_value(&mut self.append_file, prefix, value)?; - let swap_ptr = self.root[idx].compare_and_swap - (old_ptr, new_ptr, atomic::Ordering::Release); - - if swap_ptr == old_ptr { + if self.root[idx].compare_exchange + (old_ptr, new_ptr, atomic::Ordering::Release, atomic::Ordering::Relaxed).is_ok() { self.stats_add(HashStoreStats::Elements, 1); return Ok(new_ptr); } @@ -340,9 +338,7 @@ impl HashStore { } } - let swap_ptr = self.extrema[extremum].compare_and_swap(current_ptr, ptr, atomic::Ordering::Release); - - if swap_ptr == current_ptr { + if self.extrema[extremum].compare_exchange(current_ptr, ptr, atomic::Ordering::Release, atomic::Ordering::Relaxed).is_ok() { return Ok(()); } } diff --git a/hashstore/src/header.rs b/hashstore/src/header.rs index 516c646..045992f 100644 --- a/hashstore/src/header.rs +++ b/hashstore/src/header.rs @@ -48,12 +48,12 @@ impl Header { } pub fn read(rdr: &mut R) -> Result { - bincode::deserialize_from(rdr, bincode::Infinite) + bincode::deserialize_from(rdr) .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } pub fn write(wrt: &mut W, hdr: &Header) -> Result<(), io::Error> { - bincode::serialize_into(wrt, hdr, bincode::Infinite) + bincode::serialize_into(wrt, hdr) .map_err(|err| io::Error::new(io::ErrorKind::Other, err)) } } \ No newline at end of file diff --git a/hashstore/src/io.rs b/hashstore/src/io.rs index 2d4d584..0ffed50 100644 --- a/hashstore/src/io.rs +++ b/hashstore/src/io.rs @@ -14,7 +14,7 @@ pub fn write_value(wr: &mut W, prefix: ValuePrefix, con -> Result { - let mut buffer: Vec = bincode::serialize(&prefix, bincode::Infinite)?; + let mut buffer: Vec = bincode::serialize(&prefix)?; debug_assert!(buffer.len() == mem::size_of::()); buffer.extend_from_slice(content); diff --git a/hashstore/src/lib.rs b/hashstore/src/lib.rs index 6fedae0..f4406de 100644 --- a/hashstore/src/lib.rs +++ b/hashstore/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(integer_atomics)] +//#![feature(integer_atomics)] //! //! Key/value store with specific design properties //! optimized for storing the transactions of a blockchain diff --git a/hashstore/src/values.rs b/hashstore/src/values.rs index 285ac1b..ebf506e 100644 --- a/hashstore/src/values.rs +++ b/hashstore/src/values.rs @@ -54,7 +54,7 @@ mod tests { for n in 0..2000000 { let dp = ptr_new(0, n); let sz = ptr_size_est(dp); - assert!(sz >= n, format!("n={}", n)); + assert!(sz >= n, "n={}", n); } } } diff --git a/net/Cargo.toml b/net/Cargo.toml index 265834e..4fff41e 100644 --- a/net/Cargo.toml +++ b/net/Cargo.toml @@ -7,7 +7,7 @@ authors = [ ] [dependencies] -bitflags = "0.7" +bitflags = "*" circular = "~0.2" byteorder = "1" log = "0.3" @@ -15,9 +15,10 @@ multiqueue = "~0.3.2" # nom = "^2.2" rand = "0.3" regex = "*" -ring = "0.12" -rusqlite = "~0.11" -sha2 = "0.5" +ring = "0.16" +#rusqlite = "~0.11" +rusqlite = "0.24.2" +sha2 = "*" encode-derive = {path = "../encode-derive"} [dependencies.nom] diff --git a/net/src/lib.rs b/net/src/lib.rs index d64ac13..41645b1 100644 --- a/net/src/lib.rs +++ b/net/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(tcpstream_connect_timeout)] + #[macro_use] extern crate bitflags; diff --git a/net/src/message/bitcrust/mod.rs b/net/src/message/bitcrust/mod.rs index 01ccf61..882e5ab 100644 --- a/net/src/message/bitcrust/mod.rs +++ b/net/src/message/bitcrust/mod.rs @@ -5,7 +5,7 @@ use Encode; #[cfg(test)] mod tests { - use ring::digest; + //use ring::digest; use super::*; #[test] @@ -17,7 +17,7 @@ mod tests { #[test] fn it_creates_and_validates() { - let key = hmac::SigningKey::new(&digest::SHA256, &[0x00; 32]); + let key = hmac::Key::new(hmac::HMAC_SHA256, &[0x00; 32]); let m = AuthenticatedBitcrustMessage::create(&key); assert!(m.valid(&key)); } @@ -30,7 +30,7 @@ pub struct AuthenticatedBitcrustMessage { } impl AuthenticatedBitcrustMessage { - pub fn create(key: &hmac::SigningKey) -> + pub fn create(key: &hmac::Key) -> AuthenticatedBitcrustMessage { let mut rng = rand::thread_rng(); @@ -52,8 +52,8 @@ impl AuthenticatedBitcrustMessage { signature: a } } - pub fn valid(&self, key: &hmac::SigningKey) -> bool { - hmac::verify_with_own_key(key, &self.nonce, &self.signature).is_ok() + pub fn valid(&self, key: &hmac::Key) -> bool { + hmac::verify(key, &self.nonce, &self.signature).is_ok() } pub fn len(&self) -> usize { diff --git a/serde_network/Cargo.toml b/serde_network/Cargo.toml index f4d1df9..45ec576 100644 --- a/serde_network/Cargo.toml +++ b/serde_network/Cargo.toml @@ -10,6 +10,8 @@ include = ["Cargo.toml", "src/**/*.rs"] [dependencies] byteorder = "1.0" serde = "1.0" +#bincode = "1.3.2" +#serde-bench = "0.0.7" [dev-dependencies] serde_derive = "1.0" diff --git a/serde_network/benches/bincode.rs b/serde_network/benches/bincode.rs deleted file mode 100644 index e2060e3..0000000 --- a/serde_network/benches/bincode.rs +++ /dev/null @@ -1,80 +0,0 @@ -#![feature(test)] - -extern crate byteorder; - -#[macro_use] -extern crate serde_derive; - -extern crate bincode; -extern crate serde; -extern crate serde_bench; -extern crate test; - -use bincode::Infinite; -use byteorder::NetworkEndian; -use serde::{Serialize, Deserialize}; -use test::Bencher; - -#[derive(Serialize, Deserialize)] -struct Foo { - bar: String, - baz: u64, - derp: bool, -} - -impl Default for Foo { - fn default() -> Self { - Foo { - bar: "hello".into(), - baz: 1337u64, - derp: true, - } - } -} - -#[bench] -fn bincode_deserialize(b: &mut Bencher) { - let foo = Foo::default(); - let mut bytes = Vec::with_capacity(128); - type BincodeSerializer = bincode::internal::Serializer; - foo.serialize(&mut BincodeSerializer::new(&mut bytes)).unwrap(); - - b.iter(|| { - type BincodeDeserializer = bincode::internal::Deserializer; - let read = bincode::read_types::SliceReader::new(&bytes); - let mut de = BincodeDeserializer::new(read, Infinite); - Foo::deserialize(&mut de).unwrap() - }) -} - -#[bench] -fn bincode_serialize(b: &mut Bencher) { - let foo = Foo::default(); - - b.iter(|| { - let mut bytes = Vec::with_capacity(128); - type BincodeSerializer = bincode::internal::Serializer; - foo.serialize(&mut BincodeSerializer::new(&mut bytes)).unwrap() - }) -} - -#[bench] -fn serde_deserialize(b: &mut Bencher) { - let foo = Foo::default(); - let mut bytes = Vec::new(); - serde_bench::serialize(&mut bytes, &foo).unwrap(); - - b.iter(|| { - serde_bench::deserialize::(&bytes).unwrap() - }) -} - -#[bench] -fn serde_serialize(b: &mut Bencher) { - let foo = Foo::default(); - - b.iter(|| { - let mut bytes = Vec::with_capacity(128); - serde_bench::serialize(&mut bytes, &foo).unwrap() - }) -} diff --git a/serde_network/src/de.rs b/serde_network/src/de.rs index 82bea13..7fbe778 100644 --- a/serde_network/src/de.rs +++ b/serde_network/src/de.rs @@ -35,11 +35,11 @@ impl<'de> Deserializer<'de> { fn decode_compact_size(&mut self) -> Result { - let byte1: u8 = try!(Deserialize::deserialize(&mut *self)); + let byte1: u8 = Deserialize::deserialize(&mut *self)?; let result = match byte1 { - 0xff => { let u: u64 = try!(Deserialize::deserialize(&mut *self)); u as usize }, - 0xfe => { let u: u32 = try!(Deserialize::deserialize(&mut *self)); u as usize }, - 0xfd => { let u: u16 = try!(Deserialize::deserialize(&mut *self)); u as usize }, + 0xff => { let u: u64 = Deserialize::deserialize(&mut *self)?; u as usize }, + 0xfe => { let u: u32 = Deserialize::deserialize(&mut *self)?; u as usize }, + 0xfd => { let u: u16 = Deserialize::deserialize(&mut *self)?; u as usize }, _ => byte1 as usize }; Ok(result) @@ -47,7 +47,7 @@ impl<'de> Deserializer<'de> { #[inline] fn read_slice(&mut self) -> Result<&'de [u8]> { - let len = try!(self.decode_compact_size()); + let len = self.decode_compact_size()?; let (slice, rest) = self.bytes.split_at(len); self.bytes = rest; Ok(slice) @@ -61,7 +61,7 @@ macro_rules! impl_nums { fn $dser_method(self, visitor: V) -> Result where V: Visitor<'de> { - let value = try!(self.bytes.$reader_method::()); + let value = self.bytes.$reader_method::()?; visitor.$visitor_method(value) } }; @@ -104,14 +104,14 @@ impl<'de, 'a> serde::Deserializer<'de> for &'a mut Deserializer<'de> { fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_u8(try!(self.bytes.read_u8())) + visitor.visit_u8(self.bytes.read_u8()?) } #[inline] fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_i8(try!(self.bytes.read_i8())) + visitor.visit_i8(self.bytes.read_i8()?) } @@ -120,14 +120,14 @@ impl<'de, 'a> serde::Deserializer<'de> for &'a mut Deserializer<'de> { fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_borrowed_bytes(try!(self.read_slice())) + visitor.visit_borrowed_bytes(self.read_slice()?) } #[inline] fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de> { - visitor.visit_borrowed_bytes(try!(self.read_slice())) + visitor.visit_borrowed_bytes(self.read_slice()?) } #[inline] @@ -176,7 +176,7 @@ impl<'de, 'a> serde::Deserializer<'de> for &'a mut Deserializer<'de> { } } - let len = try!(self.decode_compact_size()); + let len = self.decode_compact_size()?; visitor.visit_seq(SeqAccess { deserializer: self, diff --git a/serde_network/src/error.rs b/serde_network/src/error.rs index a05a4b1..3cffe35 100644 --- a/serde_network/src/error.rs +++ b/serde_network/src/error.rs @@ -15,10 +15,11 @@ pub type Result = std::result::Result; impl error::Error for Error { fn description(&self) -> &str { - match *self { + let x = match *self { Error::EndOfBufferError => "Unexpected end of buffer", - Error::IOError(ref io) => io.description() - } + Error::IOError(ref _io) => "io error", // TODO need to get the error message out of io + }; + return x; } } diff --git a/serde_network/src/ser.rs b/serde_network/src/ser.rs index 785c20b..7a58dec 100644 --- a/serde_network/src/ser.rs +++ b/serde_network/src/ser.rs @@ -151,14 +151,14 @@ impl<'a, W> serde::Serializer for &'a mut Serializer fn serialize_some(self, v: &T) -> Result<()> where T: serde::Serialize { - try!(self.writer.write_u8(1)); + self.writer.write_u8(1)?; v.serialize(self) } #[inline] fn serialize_seq(self, len: Option) -> Result { let len = len.expect("do not know how to serialize a sequence with no length"); - try!(encode_compact_size(&mut self.writer, len)); + encode_compact_size(&mut self.writer, len)?; Ok(self) } @@ -182,7 +182,7 @@ impl<'a, W> serde::Serializer for &'a mut Serializer _variant: &'static str, _len: usize) -> Result { - try!(self.serialize_u32(variant_index)); + self.serialize_u32(variant_index)?; Ok(self) } @@ -203,7 +203,7 @@ impl<'a, W> serde::Serializer for &'a mut Serializer _variant: &'static str, _len: usize) -> Result { - try!(self.serialize_u32(variant_index)); + self.serialize_u32(variant_index)?; Ok(self) } @@ -223,7 +223,7 @@ impl<'a, W> serde::Serializer for &'a mut Serializer -> Result<()> where T: serde::ser::Serialize { - try!(self.serialize_u32(variant_index)); + self.serialize_u32(variant_index)?; value.serialize(self) } diff --git a/src/block_add.rs b/src/block_add.rs index 704db65..eaf9721 100644 --- a/src/block_add.rs +++ b/src/block_add.rs @@ -400,7 +400,7 @@ mod tests { // some rust experimenting; ignore - struct X { data: Vec }; + struct X { data: Vec } impl Clone for X { fn clone(&self) -> X { X { data: self.data.clone() } } } diff --git a/src/buffer.rs b/src/buffer.rs index 7745b66..f3a74ee 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -70,7 +70,7 @@ impl<'a> Buffer<'a> { let mut result_idx: Vec = Vec::with_capacity(count); for _ in 0..count { result_idx.push(original_len - self.inner.len() as u32); - result.push(try!(T::parse(self))); + result.push(T::parse(self)?); } Ok((result, result_idx)) @@ -79,11 +79,11 @@ impl<'a> Buffer<'a> { /// Parse a compact size /// This can be 1-8 bytes; see bitcoin-spec for details pub fn parse_compact_size(&mut self) -> Result { - let byte1 = { try!(u8::parse(self)) }; + let byte1 = { u8::parse(self)? }; Ok(match byte1 { - 0xff => { try!(u64::parse(self)) as usize }, - 0xfe => { try!(u32::parse(self)) as usize }, - 0xfd => { try!(u16::parse(self)) as usize }, + 0xff => { u64::parse(self)? as usize }, + 0xfe => { u32::parse(self)? as usize }, + 0xfd => { u16::parse(self)? as usize }, _ => byte1 as usize }) } @@ -102,7 +102,7 @@ impl<'a> Buffer<'a> { } pub fn parse_compact_size_bytes(&mut self) -> Result<&'a[u8], EndOfBufferError> { - let count = try!(self.parse_compact_size()); + let count = self.parse_compact_size()?; self.parse_bytes(count) } @@ -116,10 +116,10 @@ impl<'a, T : Parse<'a>> Parse<'a> for Vec { /// Parses a compact-size prefix vector of parsable stuff fn parse(buffer: &mut Buffer<'a>) -> Result, EndOfBufferError> { - let count = try!(buffer.parse_compact_size()); + let count = buffer.parse_compact_size()?; let mut result: Vec = Vec::with_capacity(count); for _ in 0..count { - result.push(try!(T::parse(buffer))); + result.push(T::parse(buffer)?); } Ok(result) } diff --git a/src/ffi.rs b/src/ffi.rs index 3e8509c..d8b6086 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -76,8 +76,6 @@ pub fn verify_script(previous_tx_out: &[u8], transaction: &[u8], input: u32) -> } } - - #[cfg(test)] mod tests { diff --git a/src/hash.rs b/src/hash.rs index ab091c2..cb626ef 100644 --- a/src/hash.rs +++ b/src/hash.rs @@ -67,7 +67,7 @@ impl<'a> buffer::Parse<'a> for Hash32<'a> { // we must transmute as rustc doesn't trust the slice is exactly 32 bytes // (transmuting &[u8] -> &[u8;32]) unsafe { mem::transmute( - try!(buffer.parse_bytes(32)).as_ptr()) } + buffer.parse_bytes(32)?.as_ptr()) } )) } } diff --git a/src/lib.rs b/src/lib.rs index 10d27e6..a647043 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,5 @@ -#![feature(link_args)] -#![feature(custom_derive, plugin)] -#![feature(integer_atomics)] - - - extern crate memmap; extern crate itertools; @@ -45,6 +39,7 @@ mod block_add; mod api; + pub use store::Store; diff --git a/src/script/context.rs b/src/script/context.rs index c40c740..a3a4091 100644 --- a/src/script/context.rs +++ b/src/script/context.rs @@ -53,7 +53,7 @@ impl<'a> Context<'a> { } pub fn next_uint(&mut self, count: u64) -> Result { - let bytes = try!(self.next_bytes(count)); + let bytes = self.next_bytes(count)?; // parse as little endian Ok(bytes.iter().enumerate().fold(0, diff --git a/src/script/opcode.rs b/src/script/opcode.rs index 62fbe9b..43ab26c 100644 --- a/src/script/opcode.rs +++ b/src/script/opcode.rs @@ -22,7 +22,7 @@ pub struct OpCode { pub name: &'static str, pub execute: fn(&mut Context) -> Result<(), ScriptError>, pub skip: fn(ctx: &mut Context) -> Result<(), ScriptError>, - pub display: fn(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()> + pub display: fn(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> } @@ -35,12 +35,12 @@ fn skip_invalid(_: &mut Context) -> Result<(), ScriptError> { } -fn disp_name(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()> { +fn disp_name(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> { let opcode = &OPCODES[ctx.script1[ctx.ip] as usize]; write!(writer, "{} ", opcode.name) } -fn disp_invalid(_: &mut Context, writer: &mut io::Write) -> io::Result<()> { +fn disp_invalid(_: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> { write!(writer, " [INVALID-OPCODE] ") } @@ -56,8 +56,8 @@ fn op_nop(_: &mut Context) -> Result<(), ScriptError> { } fn op_add(ctx: &mut Context) -> Result<(), ScriptError> { - let n1 = { try!(ctx.stack.pop_scriptnum()) }; - let n2 = { try!(ctx.stack.pop_scriptnum()) }; + let n1 = { ctx.stack.pop_scriptnum()? }; + let n2 = { ctx.stack.pop_scriptnum()? }; ctx.stack.push_scriptnum(n1 + n2) diff --git a/src/script/opcode_pushdata.rs b/src/script/opcode_pushdata.rs index 4bfe09b..c3bd3e0 100644 --- a/src/script/opcode_pushdata.rs +++ b/src/script/opcode_pushdata.rs @@ -37,7 +37,7 @@ pub fn skip_pushdata_count_by_opcode(ctx: &mut Context) -> Result<(), ScriptErro } /// Renders the next `n` bytes to `writer` where `n` is the current opcode -pub fn disp_pushdata_count_by_opcode(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()> { +pub fn disp_pushdata_count_by_opcode(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> { let count = ctx.script1[ctx.ip] as u64; @@ -46,13 +46,14 @@ pub fn disp_pushdata_count_by_opcode(ctx: &mut Context, writer: &mut io::Write) } pub fn op_pushdata_value_by_opcode(ctx: &mut Context) -> Result<(), ScriptError> { - let value = ctx.script1[ctx.ip] as i32 - 0x80_i32; - ctx.stack.push(Box::new([value as u8])) + let value = (ctx.script1[ctx.ip] as i32 - 0x80_i32) as u8; + ctx.stack.push(Box::new([value])) + } -pub fn disp_pushdata_value_by_opcode(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()> { +pub fn disp_pushdata_value_by_opcode(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> { let value = ctx.script1[ctx.ip] as i32 - 0x80_i32; write!(writer, "{:02x}", value) } @@ -73,7 +74,7 @@ fn size_from_opcode(ctx: &Context) -> u64 { /// pub fn skip_pushdata_count_by_next_bytes(ctx: &mut Context) -> Result<(), ScriptError> { let size = { size_from_opcode(ctx) }; - let bytecount = try!(ctx.next_uint(size)); + let bytecount = ctx.next_uint(size)?; ctx.ip += bytecount as usize; @@ -82,7 +83,7 @@ pub fn skip_pushdata_count_by_next_bytes(ctx: &mut Context) -> Result<(), Script /// Displays the pushdata for OP_PUSHDATA1, OP_PUSHDATA2 and OP_PUSHDATA4 as hex /// -pub fn disp_pushdata_count_by_next_bytes(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()> { +pub fn disp_pushdata_count_by_next_bytes(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()> { let size = { size_from_opcode(ctx) }; let bytecount = ctx.next_uint(size); @@ -94,7 +95,7 @@ pub fn disp_pushdata_count_by_next_bytes(ctx: &mut Context, writer: &mut io::Wr /// The number of bytes depends on the opcode being OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4 pub fn op_pushdata_count_by_next_bytes(ctx: &mut Context) -> Result<(), ScriptError> { let size = { size_from_opcode(ctx) }; - let bytecount = try!(ctx.next_uint(size)); + let bytecount = ctx.next_uint(size)?; op_pushdata_next_bytes(ctx, bytecount) } @@ -109,7 +110,7 @@ fn op_pushdata_next_bytes(ctx: &mut Context, count: u64) -> Result<(), ScriptEr // grab next bytes and box them // this means copying as we need ownership on the stack - let bytes = try!(ctx.next_bytes(count)) + let bytes = ctx.next_bytes(count)? .to_vec() .into_boxed_slice(); @@ -120,7 +121,7 @@ fn op_pushdata_next_bytes(ctx: &mut Context, count: u64) -> Result<(), ScriptEr /// Internal helper to display the next `count` bytes to writer; /// used to render one of the pushdata operations -fn disp_pushdata_next_bytes(ctx: &mut Context, writer: &mut io::Write, count: Result) -> io::Result<()> { +fn disp_pushdata_next_bytes(ctx: &mut Context, writer: &mut dyn io::Write, count: Result) -> io::Result<()> { const UNEXPECTED_EOS: &'static str = "[UNEXPECTED-END-OF-SCRIPT]"; const PUSHDATA_TOO_LARGE: &'static str = "[PUSHDATA-TOO-LARGE]"; @@ -138,11 +139,11 @@ fn disp_pushdata_next_bytes(ctx: &mut Context, writer: &mut io::Write, count: R match ctx.next_bytes(count_val) { Ok(bytes) => { for byte in bytes { - try!(write!(writer, "{:02x}", byte)); + write!(writer, "{:02x}", byte)?; } } Err(_) => { - try!(write!(writer, "{}", UNEXPECTED_EOS)); + write!(writer, "{}", UNEXPECTED_EOS)?; } } @@ -160,7 +161,7 @@ mod test { fn test_pushdata( script: Vec, expected: &'static str, - disp_func: fn(ctx: &mut Context, writer: &mut io::Write) -> io::Result<()>) + disp_func: fn(ctx: &mut Context, writer: &mut dyn io::Write) -> io::Result<()>) { let buf: Vec = Vec::new(); diff --git a/src/script/stack.rs b/src/script/stack.rs index 76f4fdf..bd434ea 100644 --- a/src/script/stack.rs +++ b/src/script/stack.rs @@ -42,7 +42,7 @@ impl Stack { /// Can return a stack-underflow if no items are on the stack /// pub fn pop_scriptnum(&mut self) -> Result { - let bytes = try!(self.pop()); + let bytes = self.pop()?; if bytes.len() == 0 { return Ok(0); diff --git a/src/store/flatfile.rs b/src/store/flatfile.rs index 45d1b35..2eecc55 100644 --- a/src/store/flatfile.rs +++ b/src/store/flatfile.rs @@ -111,7 +111,7 @@ impl FlatFile { } thread::sleep(time::Duration::from_millis(50)); } - panic!(format!("Data file '{:?}' exists but has invalid size", path)) + panic!("Data file '{:?}' exists but has invalid size", path) } @@ -177,12 +177,12 @@ impl FlatFile { return None; } - let old_write_pos = write_ptr.compare_and_swap - (write_pos, write_pos + size, atomic::Ordering::Relaxed); + let old_write_pos = write_ptr.compare_exchange + (write_pos, write_pos + size, atomic::Ordering::Relaxed, atomic::Ordering::Relaxed); // Only if we are overwriting the old value we are ok; otherwise retry - if old_write_pos == write_pos { - return Some(old_write_pos) + if old_write_pos == Ok(write_pos) { + return Some(old_write_pos.unwrap()) } } diff --git a/src/store/flatfileset.rs b/src/store/flatfileset.rs index 4bdbe75..96db1f2 100644 --- a/src/store/flatfileset.rs +++ b/src/store/flatfileset.rs @@ -89,9 +89,9 @@ fn filename_to_fileno(prefix: &str, name: &Path) -> Result Result { Ok(match byte { - b'A' ... b'F' => byte - b'A' + 10, - b'a' ... b'f' => byte - b'a' + 10, - b'0' ... b'9' => byte - b'0', + b'A' ..= b'F' => byte - b'A' + 10, + b'a' ..= b'f' => byte - b'a' + 10, + b'0' ..= b'9' => byte - b'0', _ => return Err(FilenameParseError) } as i16) } diff --git a/src/store/hash_index.rs b/src/store/hash_index.rs index f9bb5ab..3104b42 100644 --- a/src/store/hash_index.rs +++ b/src/store/hash_index.rs @@ -119,14 +119,13 @@ impl IndexPtr { let atomic_self: *mut atomic::AtomicU64 = unsafe { mem::transmute( self ) }; - let prev = unsafe { - (*atomic_self).compare_and_swap( + unsafe { + (*atomic_self).compare_exchange( mem::transmute(current_value), mem::transmute(new_value), - atomic::Ordering::Relaxed) - }; - - prev == unsafe { mem::transmute(current_value) } + atomic::Ordering::Relaxed, + atomic::Ordering::Relaxed).is_ok() + } } } diff --git a/src/store/spend_index.rs b/src/store/spend_index.rs index 7e03e25..d818ea8 100644 --- a/src/store/spend_index.rs +++ b/src/store/spend_index.rs @@ -77,7 +77,7 @@ impl SpendIndex let org = self.bitvector[idx].load(Ordering::Acquire); let new = org | (1 << (hash & 0x3F)); - if self.bitvector[idx].compare_and_swap(org, new, Ordering::Release) == org { + if self.bitvector[idx].compare_exchange(org, new, Ordering::Release, Ordering::Relaxed) == Ok(org) { break; } } diff --git a/src/store/tips.rs b/src/store/tips.rs index c57e904..69a65f4 100644 --- a/src/store/tips.rs +++ b/src/store/tips.rs @@ -20,13 +20,13 @@ -use std::path::{Path,PathBuf}; +use std::path::{PathBuf}; use std::fs; -use std::fs::File; +//use std::fs::File; use std::io; -use std::io::prelude::*; +//use std::io::prelude::*; -use util::*; +//use util::*; use hash::*; use config; @@ -39,7 +39,7 @@ pub struct Tips { pub fn add_tip( tips: &Tips, block_hash: Hash32Buf, - previous_hash: Option, + _previous_hash: Option, difficulty: u64, height: u64) { @@ -87,7 +87,7 @@ impl Tips { unimplemented!() } - pub fn remove_tip(tip: Tip) { + pub fn remove_tip(_tip: Tip) { unimplemented!() } diff --git a/src/transaction.rs b/src/transaction.rs index ef0d1c4..efacdc5 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -346,10 +346,10 @@ impl<'a> Parse<'a> for TxInput<'a> { fn parse(buffer: &mut Buffer<'a>) -> Result, EndOfBufferError> { Ok(TxInput { - prev_tx_out: try!(Hash32::parse(buffer)), - prev_tx_out_idx: try!(u32::parse(buffer)), - script: try!(buffer.parse_compact_size_bytes()), - sequence: try!(u32::parse(buffer)) + prev_tx_out: Hash32::parse(buffer)?, + prev_tx_out_idx: u32::parse(buffer)?, + script: buffer.parse_compact_size_bytes()?, + sequence: u32::parse(buffer)? }) } @@ -377,10 +377,10 @@ impl<'a> Parse<'a> for TxOutput<'a> { impl<'a> fmt::Debug for TxInput<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - try!(write!(fmt, "Prev-TX:{:?}, idx={:?}, seq={:?} script=", + write!(fmt, "Prev-TX:{:?}, idx={:?}, seq={:?} script=", self.prev_tx_out, self.prev_tx_out_idx, - self.sequence)); + self.sequence)?; let ctx = context::Context::new(&self.script); write!(fmt, "{:?}", ctx) @@ -392,7 +392,7 @@ impl<'a> fmt::Debug for TxInput<'a> { impl<'a> fmt::Debug for TxOutput<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - try!(write!(fmt, "v:{:?} ", self.value)); + write!(fmt, "v:{:?} ", self.value)?; let ctx = context::Context::new(&self.pk_script); write!(fmt, "{:?}", ctx) @@ -448,7 +448,7 @@ impl ::std::iter::Sum for TransactionStats { impl ::std::fmt::Debug for TransactionStats { fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - fn disp(d: Duration) -> u64 { d.as_secs() * 1_000_000 + d.subsec_nanos() as u64 / 1_000}; + fn disp(d: Duration) -> u64 { d.as_secs() * 1_000_000 + d.subsec_nanos() as u64 / 1_000} write!(fmt, "m,c,h: {},{},{} | wr:{},{} | rd:{},{} | s:{}, bt:{}", disp(self.merkle), disp(self.cloning), disp(self.hashing), diff --git a/src/util.rs b/src/util.rs index 8d64df6..fa7eeca 100644 --- a/src/util.rs +++ b/src/util.rs @@ -14,9 +14,9 @@ pub fn from_hex(str: &str) -> Vec { buf <<= 4; match byte { - b'A'...b'F' => buf |= byte - b'A' + 10, - b'a'...b'f' => buf |= byte - b'a' + 10, - b'0'...b'9' => buf |= byte - b'0', + b'A'..=b'F' => buf |= byte - b'A' + 10, + b'a'..=b'f' => buf |= byte - b'a' + 10, + b'0'..=b'9' => buf |= byte - b'0', b' '|b'\r'|b'\n'|b'\t' => { buf >>= 4; continue diff --git a/store/Cargo.toml b/store/Cargo.toml index 5e977a6..b5b4825 100644 --- a/store/Cargo.toml +++ b/store/Cargo.toml @@ -7,12 +7,13 @@ authors = ["Tomas van der Wansem "] byteorder = "1" itertools = "0.5.1" -ring = "0.12.1" +ring = "0.16" serde = "*" serde_derive = "*" -serde_json = { path = "../serde_json" } +# serde_json = { path = "../serde_json" } +serde_json = "1.0.64" serde_network = { path = "../serde_network" } hashstore = { path = "../hashstore" } diff --git a/store/src/db/db_transaction.rs b/store/src/db/db_transaction.rs index 47e6d09..8e4ea34 100644 --- a/store/src/db/db_transaction.rs +++ b/store/src/db/db_transaction.rs @@ -6,6 +6,7 @@ use ::{ValuePtr,Transaction}; use record::Record; use serde_network::{Deserializer,Serializer,deserialize}; use transaction; +//use std::iter::Map; /// An owned transaction that owns the data as extracted from the db @@ -55,8 +56,8 @@ impl DbTransaction { let output_count: u32 = de_tx.deserialize()?; let sig_ptr: ValuePtr = de_tx.deserialize()?; - let prev_outs: Vec = try!((0..input_count).map(|_| - de_tx.deserialize()).collect()); + let prev_outs: Vec = (0..input_count).map(|_| + de_tx.deserialize()).collect()?; let txs_in: Result,DbError> = prev_outs.iter().map(|rec| Ok(transaction::TxInput { diff --git a/store/src/util.rs b/store/src/util.rs index c81ff2e..e2ecb75 100644 --- a/store/src/util.rs +++ b/store/src/util.rs @@ -36,9 +36,9 @@ pub fn from_hex(str: &str) -> Vec { buf <<= 4; match byte { - b'A'...b'F' => buf |= byte - b'A' + 10, - b'a'...b'f' => buf |= byte - b'a' + 10, - b'0'...b'9' => buf |= byte - b'0', + b'A'..=b'F' => buf |= byte - b'A' + 10, + b'a'..=b'f' => buf |= byte - b'a' + 10, + b'0'..=b'9' => buf |= byte - b'0', b' '|b'\r'|b'\n'|b'\t' => { buf >>= 4; continue diff --git a/store/tests/blk_file.rs b/store/tests/blk_file.rs index 2b5cba3..0761ac7 100644 --- a/store/tests/blk_file.rs +++ b/store/tests/blk_file.rs @@ -92,7 +92,7 @@ fn read_block(rdr: &mut io::Read) -> Result>, io::Error> { let mut buffer = vec![0; length as usize]; - try!(rdr.read_exact(&mut buffer)); + rdr.read_exact(&mut buffer)?; Ok(Some(buffer)) diff --git a/tests/blk_file.rs b/tests/blk_file.rs index 5657ba6..9339352 100644 --- a/tests/blk_file.rs +++ b/tests/blk_file.rs @@ -16,7 +16,7 @@ const MAGIC: u32 = 0xD9B4BEF9; /// Reads a block from a blk_file as used by /// bitcoin-core and various other implementations -pub fn read_block(rdr: &mut io::Read) -> Result>, io::Error> { +pub fn read_block(rdr: &mut dyn io::Read) -> Result>, io::Error> { loop { let magicnr = rdr.read_u32::(); @@ -40,11 +40,11 @@ pub fn read_block(rdr: &mut io::Read) -> Result>, io::Error> { } - let length = try!(rdr.read_u32::()); + let length = rdr.read_u32::()?; let mut buffer = vec![0; length as usize]; - try!(rdr.read_exact(&mut buffer)); + rdr.read_exact(&mut buffer)?; Ok(Some(buffer)) diff --git a/tests/compare_core.rs b/tests/compare_core.rs index e4d70b3..1eb03ff 100644 --- a/tests/compare_core.rs +++ b/tests/compare_core.rs @@ -25,7 +25,7 @@ mod blk_file; const SKIP_FILES: usize = 0; fn blk_file_name(file_number: usize) -> String { - format!("/home/tomas/.bitcoin/blocks/blk{:05}.dat", file_number) + format!("~/.bitcoin/blocks/blk{:05}.dat", file_number) } /// A reference to a position in a blk file diff --git a/tests/test_bench.rs b/tests/test_bench.rs index 2977d50..60f4dc4 100644 --- a/tests/test_bench.rs +++ b/tests/test_bench.rs @@ -26,7 +26,7 @@ fn load_bench_init() { let f = File::open(name).unwrap(); let mut rdr = BufReader::new(f); - let mut blocks = 0; + let mut _blocks = 0; loop { let blk = blk_file::read_block(&mut rdr).unwrap(); @@ -36,7 +36,7 @@ fn load_bench_init() { bitcrust_lib::add_block(&mut store, &blk.unwrap()); - blocks += 1; + _blocks += 1; } }