Code Monkey home page Code Monkey logo

core-rs's People

Contributors

curdbecker avatar fiaxh avatar jeffesquivels avatar jgraef avatar mar-v-in avatar paberr avatar riptl avatar sdschmidt avatar sisou avatar styppo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

core-rs's Issues

Build fails on ARM-based system

New issue checklist

General information

  • Library version(s): 0.2
  • Browser version(s): N/A
  • Devices/Simulators/Machine affected: Linux aarch64
  • Reproducible in the testnet? (Yes/No): N/A
  • Related issues:

Bug report

Expected behavior

Build doesn't fail

Actual behavior

Build fails

Steps to reproduce

cargo +nightly build --release

Crash log? Screenshots? Videos? Sample project?

error: failed to run custom build command for `libargon2-sys v0.2.0 (/home/ubuntu/nimiq/libargon2-sys)`

Caused by:
  process didn't exit successfully: `/home/ubuntu/nimiq/target/release/build/libargon2-sys-66ab85cb0894a5ef/build-script-build` (exit code: 1)
--- stdout
TARGET = Some("aarch64-unknown-linux-gnu")
HOST = Some("aarch64-unknown-linux-gnu")
CC_aarch64-unknown-linux-gnu = None
CC_aarch64_unknown_linux_gnu = None
HOST_CC = None
CC = None
CFLAGS_aarch64-unknown-linux-gnu = None
CFLAGS_aarch64_unknown_linux_gnu = None
HOST_CFLAGS = None
CFLAGS = None
CRATE_CC_NO_DEFAULTS = None
DEBUG = Some("false")
CARGO_CFG_TARGET_FEATURE = Some("fp,neon")
running: "cc" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-I" "native" "-Wall" "-Wextra" "-DARGON2_NO_THREADS" "-o" "/home/ubuntu/nimiq/target/release/build/libargon2-sys-1a40ba79533982af/out/native/argon2.o" "-c" "native/argon2.c"
exit code: 0
running: "cc" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-I" "native" "-Wall" "-Wextra" "-DARGON2_NO_THREADS" "-o" "/home/ubuntu/nimiq/target/release/build/libargon2-sys-1a40ba79533982af/out/native/core.o" "-c" "native/core.c"
exit code: 0
running: "cc" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-I" "native" "-Wall" "-Wextra" "-DARGON2_NO_THREADS" "-o" "/home/ubuntu/nimiq/target/release/build/libargon2-sys-1a40ba79533982af/out/native/blake2/blake2b.o" "-c" "native/blake2/blake2b.c"
exit code: 0
running: "cc" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-I" "native" "-Wall" "-Wextra" "-DARGON2_NO_THREADS" "-o" "/home/ubuntu/nimiq/target/release/build/libargon2-sys-1a40ba79533982af/out/native/opt.o" "-c" "native/opt.c"
cargo:warning=In file included from native/opt.c:26:0:
cargo:warning=native/blake2/blamka-round-opt.h:23:10: fatal error: emmintrin.h: No such file or directory
cargo:warning= #include <emmintrin.h>
cargo:warning=          ^~~~~~~~~~~~~
cargo:warning=compilation terminated.
exit code: 1

--- stderr


error occurred: Command "cc" "-O2" "-ffunction-sections" "-fdata-sections" "-fPIC" "-I" "native" "-Wall" "-Wextra" "-DARGON2_NO_THREADS" "-o" "/home/ubuntu/nimiq/target/release/build/libargon2-sys-1a40ba79533982af/out/native/opt.o" "-c" "native/opt.c" with args "cc" did not execute successfully (status code exit code: 1).

More sub-crates

Currently, it is very cumbersome to use/debug only parts of the implementation.
The main reason for that is almost all code residing in the main project source.

I propose to make use of more sub-crates (similar to parity-bitcoin).
This also helps cleaning up unwanted dependencies. Currently, for example, our consensus module has dependencies on the network module.
It also speeds up compilation and testing, when only some parts were changed.
Finally, it allows us to compile relevant parts of it to WebAssembly.

As there are many ways to divide the current code into sub-crates, this issue is meant for discussion about how to structure those.

My proposal would be something like:

  • db (database layer) ✅
  • hash (hashes, non-key related cryptography) ✅
  • keys (private keys, signatures, address,...) ✅
  • primitives (Target, Coin, Compact, everything related to blocks and transactions, contracts and basic accounts,...) ✅
  • datastructures (Accounts, Blockchain, ChainStore and other concrete db stores) ✅
  • consensus (Consensus, ConsensusAgent, Mempool) ✅
  • mnemonic (mnemonics) ✅
  • key-derivation (key derivation) ✅
  • network (all networking) ✅
  • network-primitives (primitives used in multiple locations) ✅
  • core (putting things together, but no binary) (currently in main folder ✅)
  • rpc (JSON-RPC) (to be merged)
  • utils (most utils, configurable via feature flags) ✅
  • Separate binary crate ✅ (by @jgraef)

Note: I just quickly wrote down this as a starting point. Looking forward to your ideas. :)
Those that I already created are marked with ✅.
Those that are currently in progress are marked with ☑️.

config.example.toml suggests unavailable options

The example config file includes many "available settings" that are not actually available, such as the dumb mode, light and nano consensus etc.

These should be removed from the example config file for release.

Support loading PEM formatted certificates directly

Currently, we only support loading certificates (and private key) from a PKCS#12 file, but most certificate providers (including Let's Encrypt) issue their certificates in separate non-encrypted PEM formatted files, so it makes sense for us to support loading certificates this way too.

`AddressParseError`doesn't implement `std::fmt::Display`

I ran into this multiple times, but never got the time to fix it. So here is the issue open for anyone to fix. Or I will fix it, once I got some spare time.

error[E0277]: `keys::AddressParseError` doesn't implement `std::fmt::Display`
  --> src/config.rs:52:53
   |
52 |     Address::from_user_friendly_address(&s).map_err(Error::custom)
   |                                                     ^^^^^^^^^^^^^ `keys::AddressParseError` cannot be formatted with the default formatter
   |
   = help: the trait `std::fmt::Display` is not implemented for `keys::AddressParseError`
   = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
   = note: required by `config::_IMPL_DESERIALIZE_FOR_GenesisConfig::_serde::de::Error::custom`

Since keys::AddressParseError is an error, we should also implement the necessary traits.

Argon2 native CPU module selection

Like in nimiq/core-js#440 of core-js, I think it's useful to have a native module selection for packaged builds, and I'd like to take on this.

My idea is to statically link the different versions of libargon2 into the same binary, giving the function names a suffix of the target via a C macro.
We'd then have argon2d_hash_raw_avx2, argon2d_hash_raw_sse2 and so on built from the same source.

Like in nimiq/core-js#456, a $PACKAGING environment variable should be introduced, that will trigger a native build if it's false instead of the avx2, sse2… versions.

On startup, Rust then would set up function pointers to the native module and use rust-cupid to initialize them with the correct implementations.

I also filed #1 to reduce the number of functions so the module is easier to work with.

The alternative would be to dynamically load the implementations like the .node libraries in Node.js but that'd be more difficult and inconvenient, in my opinion.

Remember block producers

Currently, only producers of micro blocks during the latest two epochs are known.
The slot data should be included in ChainInfo to persist the producer info of historic blocks.

error[E0554]: #![feature] may not be used on the stable release channel

error[E0554]: #![feature] may not be used on the stable release channel
--> collections/src/lib.rs:2:1
|
2 | #![feature(box_into_raw_non_null)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
--> collections/src/lib.rs:3:1
|
3 | #![feature(specialization)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: #![feature] may not be used on the stable release channel
--> collections/src/lib.rs:4:1
|
4 | #![feature(map_get_key_value)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Compiling indexmap v1.0.2
error: aborting due to 3 previous errors

For more information about this error, try rustc --explain E0554.
error: Could not compile nimiq-collections.
warning: build failed, waiting for other jobs to finish...
error: build failed

Cannot build project on Mac

Bug report

Expected behavior

The project should build on Mac

Actual behavior

The project fails to build

Steps to reproduce

Clone repository.
Run 'cargo build'

Crash log? Screenshots? Videos? Sample project?

error: suffixes on a tuple index are invalid
  --> primitives/block/src/target.rs:12:64
   |
12 | #[derive(Default, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
   |                                                                ^^^^^^^^^ invalid suffix `i32`

error: proc-macro derive produced unparseable tokens
  --> primitives/block/src/target.rs:12:64
   |
12 | #[derive(Default, Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
   |                                                                ^^^^^^^^^

error: aborting due to 2 previous errors

error: Could not compile `nimiq-block`.
warning: build failed, waiting for other jobs to finish...
error: build failed

Backport checklist from Albatross

This issue is a meta issue with the information of all the features that should/could be backported from Albatross after the stable release:

  • Client API support
  • Build genesis block data from config file
  • Move paths of dependencies to root crate

Closing WebSocket connections

Currently, we close our WebSocket connections by:

  1. Having a select between a one-shot channel and the connection processing future.
  2. Sending a close event via the one-shot channel and thus terminating the connection processing future.
  3. Sending the WebSocket close frame after having terminated the connection processing future.

let (closing_tx, closing_rx) = oneshot::channel::<CloseType>();
let notifier = peer_stream.notifier.clone();
// `select` required Item/Error to be the same, that's why we need to map them both to ().
let connection = forward_future.map(|_| ()).map_err(|_| ()).select(peer_stream.process_stream().map_err(|_| ())); // TODO: throwing away error info here
// `select` required Item/Error to be the same.
// `closing_rx` has Item=ClosingType, which we want to use. But Error will be set to ().
let closing_future = closing_rx.map_err(|_| ());
// `connection` currently has a tuple type, but we will soon call `select`, so unify Error to ()
// and set Item=CloseType with `CloseType::ClosedByRemote` to identify a normal shutdown.
let connection = connection.map(|_| CloseType::ClosedByRemote).map_err(|_| ());
// Types have already been unified, so select over normal connection and `closing_future`.
let connection = connection.select(closing_future);
// Notify listeners when the future terminates.
let connection = connection.then(move |result| {
let ty = match result {
Ok((ty, _)) => ty,
// FIXME Connection closed by peer also reported as NetworkError
Err(_) => CloseType::NetworkError,
};
// Send WS close frame, ignore result.
let _ = shared_stream.close();
// Now send out notifications.
notifier.read().notify(PeerStreamEvent::Close(ty));
Ok(())
});

With the most recent version of tungstenite and tokio-tungstenite there might be a nicer way to do it:

I only skimmed over the two pull requests, but it seems that it is now possible to send the close frame via the Sink and shut down the Stream part when receiving the other party's close frame.

error: linking with `cc` failed: exit code: 1

New issue checklist

Tried to build core-rs from source by cloning from Github. I switched to nightly build with rustup default nightly. As soon as I started building with cargo +nightly build the compiling stopped with the following error:
error: linking with `cc` failed: exit code: 1

The README of core-rs states that besides rust nightly you need gcc, pkg-config and libssl-dev, which I installed through apt.

Solution

Install gcc-multilib as well and it started compiling with no issues.

Check that Coin is not serialized with values > Javascript's MAX_SAFE_INTEGER

In primitives/src/coin.rs there is a comment in the Deserialize implementation which says:

Check that the value does not exceed Javascript's Number.MAX_SAFE_INTEGER.

Shouldn't we check that then on serialization too? Serialization is currently auto-derived and thus just serializes the u64 even if it's greater than Javascripts MAX_SAFE_INTEGER.

Also the checked_add should check this.

Multiple pBFT processes

The current validator network can handle one concurrent pBFT process created after a proposal is received and its parent block is known. This leads to failures building a pBFT majority in some circumstances on high latency networks, specifically in two cases:

  1. Prepare/commit messages referencing an unknown proposal are dropped (if the proposal message gets delayed)
  2. Prepare/commit messages referencing a buffered proposal are dropped. Buffered proposals are intrinsically valid but the micro block chain leading up to them isn't complete yet.

To solve this, the validator network is rewritten to track multiple concurrent pBFT processes for different macro blocks, like so: Map<Blake2bHash, PbftState>.

The PbftState can exist in three settings:

  • Valid: The referenced micro block chain is available and the proposed macro block would be valid on-chain. It is the only setting that can complete a view change, if a 2/3 majority of commits is reached.
  • Buffered: The proposal is available but can't be checked for validity yet. (Failure case 2) It gets to a valid setting if the micro block chain is available and the proposal checks out.
  • Weak: No proposal is available but there are votes for this block hash. (Failure case 1) It gets upgraded to a buffered or valid setting respectively when a proposal gets available. To prevent spam, the number of weak proposals must be limited.

At the end of each epoch, old valid and buffered proposals are pruned. Additionally, their macro block hashes are pushed to a blacklist LimitHashSet to prevent accidental re-creation of a PbftState by pBFT prepares/commits received after committing the macro block.

Validator creates block with invalid justification

  • Branch terorie/albatross devnet
  • Sometimes, when crate validator produces a block, it gets rejected by crate blockchain
  • Failing check:
if !intended_slot_owner.verify(&micro_block.header, &justification) {
                warn!("Rejecting block - invalid justification for intended slot owner");
  • Log:
 INFO nimiq_validator::validator                 > Produced block: block_number=73529, view_number=0, hash=73e7f9e...                                                                                                                   
 INFO nimiq_consensus::consensus                 > Now at block #73529                                                                                         
 TRACE nimiq_validator::validator                 > Next block producer: CompressedPublicKey(ae88f18...)
 TRACE nimiq_validator::validator                 > Push result: Ok(Extended)                                                                                  
 INFO nimiq_validator::validator                 > Produced block: block_number=73530, view_number=0, hash=186435...
 WARN nimiq_blockchain_albatross::blockchain     > Rejecting block - invalid justification for intended slot owner                                             
 DEBUG nimiq_blockchain_albatross::blockchain     > Intended slot owner: CompressedPublicKey(ae88f18...)
 ERROR nimiq_validator::validator                 > Failed to push produced micro block to blockchain: InvalidBlock(InvalidJustification)                                                                                                                                                     

Checklist for 1.0 release

This is the checklist of pending items/bugs/tasks that need to be addressed in order to release a 1.0 version:

  • Looking into networking layer improvements in albatross and backporting anything that makes sense
  • Make sure TLS termination works properly with our current mainnet infrastructure setup
  • Backport the updated GitLab CI config from albatross
  • Fix bug where incomplete AccountsProof are sent
  • Code cleanup (warnings during compilation, etc.)
  • Support https for the metrics server
  • Make sure the name of metrics in Rust match those in JavaScript

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.