Git Product home page Git Product logo

chain-libs's Introduction

Chain-libs

๐Ÿšง This repo is not maintained anymore please submit your feature proposal or bug report to Catalyst Core.

chain-libs's People

Contributors

amias-iohk avatar anviking avatar cameron1024 avatar codesandwich avatar dependabot-preview[bot] avatar dependabot[bot] avatar dkijania avatar ecioppettini avatar edolstra avatar eugene-babichenko avatar filip-dulic-bloxico avatar gokyo avatar iquerejeta avatar jleni avatar ktorz avatar kukkok3 avatar minikin avatar mr-leshiy avatar mrzenioszeniou avatar mzabaluev avatar nicolasdp avatar nicopado avatar qnikst avatar rinor avatar rooooooooob avatar saibatizoku avatar sebastiengllmt avatar sjmackenzie avatar vincenthz avatar zeegomo 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

Watchers

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

chain-libs's Issues

Update rusqlite to 0.21, consolidate chain-storage-sqlite crates

The rusqlite version we use is quite old and has some problems for Windows builds: @danielSanchezQ reported it prevents fixing input-output-hk/jormungandr#1699, while my standalone experiment with 0.21 and "bundled" worked well with crt-static.

Update the rusqlite dependency to the latest version (keep "bundled" on or optionally-default for the time being). There is a use of r2d2_sqlite backend in chain-storage-sqlite, which is ironically the more outdated crate, so that needs to be dropped and chain-storage-sqlite-old renamed as the only surviving storage implementation.

Check enough stake is define in block0 before starting with consensus GPraos

If we start with consensus genesis praos in block0, we want to check that the system is in a working state. given that only the one that control the stake, control creation of the block, we need to make sure the system is defined correctly:

  1. check that there's some stake defined in the system, by calculating the stake distribution
  2. check that there's >= 1 stake pool certificates
  3. check there's some overlap between the stake pool certificate and the stake distribution

Update Proposal is not removed after expiry grace period (proposal_expiration)

UpdateState::process_proposals has bug in my opinion, which leads to problem in which proposal which was not accepted before proposal_expiration period won't be removed from proposal collection at all.

there are two conditions in mentioned method:

 if prev_date.epoch < new_date.epoch

and

else if proposal_state.proposal_date.epoch + settings.proposal_expiration
                    > new_date.epoch

if we apply proposal in the current epoch (let's say epoch 0 and our proposal_expiration is any value different than 0, then it's impossible to satisfy condition proposal_state.proposal_date.epoch + settings.proposal_expiration < new_date.epoch => 0 + 1 > 1 = false and then new_date.epoch will be increased i believe if we time proceeds, so above condition will be never met and therefore proposal will stay in collection forever).

In different scenario in which we apply proposal for epoch in the future let's say epoch 5 (while we are at epoch 0) then if proposal won't be accepted in epoch 0, then it will be immediately removed from proposals in process_proposals . (5 + 0 > 0 = true)

To fix this situation we need to reverse condition:

else if proposal_state.proposal_date.epoch + settings.proposal_expiration
                    < new_date.epoch

This will solve first scenario in epoch 2 (0+ 1 < 2 = true) and in second scenario proposal won't be removed from proposal before its time will come (5 + 0 < 0 =false )

Testing improvements

Testing improvements in the chain library

There is a lot of problem that are being reported that could be have
been discovered with better testing of the library.

Testing the blockchain property is an incredibly complex task that may
take a lot of CI time. In order to facilitate writing the testing and
not make the developer life too hard we will split the testing into
different layer of levels.

Level1

we need to be able to work on the small properties.

  • Encoding then Decoding the blockchain should returns the original content;
  • Addresses Discrimination should be the same as ledger (#16)
  • Simple property of the different components:
    • transaction (inputs == outputs + fee) (#728 )
    • the blockchain state's total value is constant (#729);
    • when building the stake distribution we need to retrieve the total value;
    • for a total of N value in the blockchain, a stake key with M (M < N),
      the stake distribution should be consistent.

Most of these tests can be property tests (utilising quickcheck). This is important
as proving these properties if hold independently, the higher composition of these
properties will be easier to test.

Level 2

These tests are still property tests, but may take a bit longer to execute as they
are testing small scenarios:

  • when applying a transaction to the blockchain the state needs to change
    • the total value remains the same;
    • the spent utxo are removed, a new one is added;
    • the accounts state are updated; #45
    • the stake distribution has changed;
  • we need more thorough testing on the update mechanism too;

Level 3

theses are slightly more complex tests that may takes some time to execute on the
CI. They intent to test long running properties:

  • leader election through an epoch is on average consistent with the stake distribution.
    if a leader as 30% of the total stake, they should be elected 30% of the time; #41
  • update and voting, we need to check that changes on the blockchain settings actually
    changes the settings when they are voted and adopted. #49

chain-storage-sqlite: Add consistency checks

The current storage implementation has issues with consistency, including:

  • It is possible to put a block while its parent is not present in the database.
  • It is possible to put a tag on a non-existent header.

Consider adding checks to the database queries to prevent inconsistency in an atomic way.

[VIT] vote plan certificate auth

add the necessary auth parameter for the vote plan certificate so we can create registration certificate, sign them and propagate them within transactions

Single bitmap implementation for different special cases

Now there are two different implementations of bitmaps:

  • One in imhamt (32 bits long)
  • Another one in sparse-array (256 bits long)

We need to implement a bitmap that will satisfy different corner-cases (8, 16, ... 256 bits) and be reusable so that we can remove functionality duplication.

Testing Lvl1: builder properties test - proposals

Before and after finalize operation:

  • each add input/ add output / add certificates changes transaction Id
  • After finalize it does not change

You can seal only transaction with the sufficient amount of witnesses and corresponding types (does order of witnesses matter?)

logging system: using slog

We used to run with the log crate. But we have a requirement for structural logging coming from different end users. log does not provide this feature yet. For simplicity we will be using slog-scope crate (and derivative).

LeadersParticipationRecord is increased even on error

There is an issue in code:

https://github.com/input-output-hk/chain-libs/blob/master/chain-impl-mockchain/src/block/leaderlog.rs#L41

It first increment total and then check if insert is correct which can leads to wrong counter values for participants record. See test:

 #[test]
    pub fn test_set_new_value_for_existing_stake_pool() {
        let stake_pool_id = new_stake_pool_id();

        let mut leaders_participation_record = create_log(vec![(stake_pool_id.clone(), 1)]);

        assert_eq!(
            InsertError::EntryExists,
            leaders_participation_record
                .set_for(stake_pool_id.clone(), 10)
                .err()
                .unwrap()
        );

        assert_eq!(
            1,
            get_count(&leaders_participation_record, &stake_pool_id).unwrap(),
            "wrong count for new stake pool"
        );

        verify_participants_count(&leaders_participation_record, 1);
        //correct expected value: 1
        verify_total(&leaders_participation_record, 11);
    }

in PR: #223

storage rework / simplification for next phase

  • get rid of chain-core (some of the) properties in storage (optional)
  • remove sqlite indices and replacing by in-memory indices in btree-map (BlockHash -> ..) and Sequential / Geographical data structure (data height, date)
  • remove the storage trait, in favor of a simple implementation with possibly only 3 backends (dynamic branching would do) that we care about for storing blocks : memory, sqlite, hdb (branch in chain-libs). it's possible that some backends could cache, e.g memory cache of blocks then other backend also.

per-certificate fees

Certificate might have different overhead on the chain, and thus might require more fees.

Introduce a certificate trait that allow to define extra fees depending on the certificate type and content, effectively Certificate -> ExtraFee

related to #427

overhaul certificate signing

general improvement to signing

  • cleanup signing capability
  • overhaul signing to be flexible to multi owners and different algorithms
  • transaction binding mechanism
  • document the security guarantees

Content/Fragment Slice

Just like Header and Transaction, refactor Content / Fragment and add ContentSlice / FragmentSlice to be cheaper to extract / parse.

chain-core: remove generic blockchain trait

  • core should be splitted in blockchain-traits (questionable need) and serialization (still needed)
  • remove use of the traits in network and existing storage
  • alternatively remove the trait as a dependency of chain-impl-mockchain and invert it to a package that consume the chain-impl-mockchain and add the trait to gradually get rid of things

[VIT] vote casting accounting in the Ledger

track down the votes in the ledger's vote plan state manager

  • a vote is valid is in a block within the allocated time for the vote
  • no duplicate vote, new votes erase the previous vote

[VIT] Vote casting certificate

  • contains a proposal ID: (Hash, u8), the Hash of the vote plan and the index (u8) of the specific proposal
  • contains the vote choice (TODO: define the choice with the vote crypto)

a vote is always associated to an account so we can track down the stake too. Stake Delegation certificate should be a good example starting point for this

StakeDistribution multiply dangling stake incorrectly

version: newest master

method: assign_account_value in stake/distribution.rs file. If we have a DelegationType::Ratio which delegates e.g. Value(100) to non existing 4 pool stakes it is expected that StakeDistribution struct will hold dangling value equal to 100, however it is equal to 800 (this is due to the face that
assign_account_value mutliply incoming value by 2 and does it 4 times (4 is the number of pools)).

Please run test: dangling_stake_multiplied in stake/distribution.rs to observe mentioned behavior (it is possible to uncomment commented assertion to get proper expected value).

Consider using crate bytes for serialization buffers

In the module mempack of chain-core, ReadBuf looks like a statically lifetime-bound analog of Bytes from crate bytes. Switching the Readable/Writable traits to working with Bytes/BytesMut may enable more flexible zero-copy processing of asynchronously streamable data in the style of tokio-io.

chain-crypto: More disciplined digest API

The method DigestOf::digest_with is arguably too loose for library API: it allows any closure to calculate a digest of an object, which is however, tied to the object type by its type parameter.

To reduce possibility of sneaky errors, this method should be replaced by a different method using a new trait similar to std::hash::Hash, which object types would need to implement to support calculation of a digest on their contents in a single canonical way.

DigestOf::coerce suffers from similar looseness, but at least its intent is explicit in the code. Its only usage so far is in a quickcheck Arbitrary impl for DigestOf, which is rather hackish.

Update tower-grpc dependencies, switch to tower-hyper

All dependencies of tower-grpc in its git master branch have graduated to be versioned on crates.io. It can be used with a crates.io version of tower-hyper as the HTTP stack. This means we can achieve build stability with revision-locked tower-grpc, but the HTTP stack crate needs to be switched from tower-h2 to tower-hyper.

Things to do

Blockers in tower-hyper

network-grpc

  • Finalize the porting branch after tower-hyper issues have been resoved and submit a PR.

Testing Lvl1: the blockchain state total value is constant

We need to be able to check that, for any new transaction applied to the state, the total value remains constant.

This task is a bit more complex as you need to create only valid transaction for a given state of the blockchain. but still possible:

  • for an arbitrary state of the blockchain (random UTxO, accounts, ledger parameters...);
  • for an arbitrary valid transaction;

apply the transaction on the blockchain state;

  • the total value should not have changed

relates to epic #727

Active Slot coefficient value is not check before applying it to the settings

ConfigParam::ConsensusGenesisPraosActiveSlotsCoeff(d) => {
new_state.active_slots_coeff = ActiveSlotsCoeff(*d);
}

and it is not checked from decoding the value from the config param either because we use Milli:

impl ConfigParamVariant for Milli {
fn to_payload(&self) -> Vec<u8> {
self.to_millis().to_payload()
}
fn from_payload(payload: &[u8]) -> Result<Self, Error> {
u64::from_payload(payload).map(Milli::from_millis)
}
}

Optimise Utxo representation

At the moment the unspent is implemented using a BtreeMap:

struct TransactionUnspents<OutAddress>(BTreeMap<TransactionIndex, Output<OutAddress>>);

whereas it could do with an optimised contiguous implementation with a bitmap and special cases (likely 1 index, 2 indices, 3 indices)

restructure fragment application to ledger

need to restructure the ledger checks / applications to separate some parts, which would give the ability to do more check on fragments ahead of application.

Errors need to splitted in two categories:

  • ErrorStateless: the fragment is not valid and never will be : e.g. structure is invalid, some cryptographic signature return Failed, ...
  • ErrorLedgerState: the fragment is not currently valid : it doesn't apply to the current ledger state (e.g. account doesn't have enough value), but could validly apply to a different ledger state.

Operations need to separate the stateless checks on a fragment from the stateful checks

Stateless:

  • Structural/Consistency checks
  • Limits
  • Hash calculation
  • Cryptographic signatures 1/2 (public key available)

Stateful:

  • Cryptographic signatures 2/2 (public key need to be retrieved from state)
  • Application to the state (e.g. spending money, creating a new entry)

strongly related to #7

[Rewards] max limit parameter has no effect on fixed tax

When using max_limit parameter along with fixed tax, reward mechanism does not take max_limit parameter value into account.

Example:
Given stake pool registration:

StakePool { ..., 
     rewards: TaxType { 
          fixed: Value(100), 
          ratio: Ratio { numerator: 0, denominator: 1 }, 
          max_limit: Some(30) 
     }, ....
 }

Actual reward: 100
Expected reward: 30

Optimise HAMT internal

  • mutable mode should kept the tree mutable and modify the tree on demand (Cow)
  • freezing: should replace all mutated cells, back to frozen nodes
  • replace recursive functions by explicit iterative functions
  • optimise node internals (unsafe / pointers / ..)

chain-storage: rework is_ancestor

the BlockStore method name is_ancestor is misleading. Ok(None) is returned when there are no ancestral relations.

Perhaps the method should be renamed and a purpose-specific enum can be introduced for self-descriptive explanation of the success cases.

separate transaction/certificate self-validation/ledger-validation

Separate the ledger checks for transaction (w or w/ certificate) that have to do with self-validation (making sure the format is ok, and that basic property is enforced correctly), and the context based validation.

e.g.:

X.valid_self() -> Result<(), Error>
X.apply_ledger(ledger: &Ledger) -> Result<Ledger, Error>

this is useful when wanting to make simple verification on transaction without having the Ledger available.

add an "old hash" configuration in block0

The intent is to optionally be able to bring an old blockchain latest hash as data of the chain. This can be thought as a logical block0.prev.

One alternative option, that I don't think make sense, is to use the official block0.prev which is right now set to 0, but it's only working if/when we have the same hash size.

Allow Genesis block to start at epoch=N

Allow the system to start at a defined offset epoch=N instead of assuming epoch=0, which need to de-hardcode couple of place that expect to start at date=0.0

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.