Git Product home page Git Product logo

astria's People

Contributors

dereksione avatar itamarreif avatar jbowen93 avatar joroshiba avatar mattdf avatar mycodecrafting avatar noot avatar sambukowski avatar steezeburger avatar superfluffy avatar xiaolou86 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

astria's Issues

sequencer: implement account keys and signing scheme

currently we will be using ed25519 to start with.

requires:

  • creating address scheme based off public keys (probably just first 20 bytes of sha256(public_key_bytes) like every other chain for now)
  • adding signature and public key of sender to transactions
  • implement signing of transactions and signature verification of signed transactions

Public Block Explorer for EVM

Tasks

refactor conductor

Tasks

  1. conductor refactor
    SuperFluffy
  2. conductor refactor
    SuperFluffy
  3. conductor needs-scope refactor
  4. conductor needs-scope refactor

Replace logging by tracing, remove alert actor

tracing is the goto solution to logging/tracing in async applications. Moving the system to the tracing ecosystem will also allow replacing the alert actor:
https://github.com/astriaorg/astria-conductor/blob/ff6580f7de96301ff44ee3400a7e6a5293d37044/astria-conductor/src/bin/conductor.rs#L103-L112

As a suggested implementation detail: the executor can also received tracing::Spans so that it can delegate methods to be ran in the same span (or a child span) of the code that originally sent the message to it.

sequencer: app-side mempool

the sequencer requires an app-side mempool, which can be used as a public mempool, and will be required for sequencer-native txs.

we can start with a basic naive mempool which orders txs by fee, then in PrepareProposal takes as many txs from the mempool as it can and forms them into a block for tendermint.

questions:

  • how will we deal with gossiping txs? should we gossip through tendermint? will this require modifying tendermint so we don't have txs in two places?
  • how will the tx submission flow work? should txs still go through ABCI, or should the sequencer application have an endpoint to accept them directly?

Generate OCI images on github actions in monorepo

Will require some Github setup so that astria has permission to push to the package registry

Can we only build images for a specific crate when that crate actually changes?
Should we build on every push? Only pushes to main? This is something we need to figure out.

Replace Metro w/ Rust Sequencer

Tasks

  1. demo enhancement sequencer
    noot
  2. demo enhancement sequencer
    noot
  3. demo enhancement sequencer
    sambukowski
  4. demo sequencer-relayer
    noot
  5. composer demo sequencer
    noot
  6. demo enhancement gossipnet
    noot

refactor sequencer-relayer

Tasks

  1. refactor sequencer-relayer
    SuperFluffy
  2. refactor sequencer-relayer
    SuperFluffy
  3. refactor sequencer-relayer

Make CI block on breaking changes

Breaking changes in protobufs are bad, once we have long lived network, any sort of production state we should no longer allow them. Until then allow ourselves to iterate.

sequencer: implement parsing and updating of genesis file

cometbft creates a genesis.json file on init, however we want to be able to easily modify this file to add genesis balance allocations and validators. specifically we want to put the sequencer-specific type GenesisState into this genesis file.

requires:

  • parsing the existing genesis file, or a way to easily add fields to the existing genesis file
  • serializing/deserializing the app-specific GenesisState into this file
  • (optional) CLI commands for adding balance allocations/validators to the genesis file

Use single Dockerfile for Conductor & Relayer

Conductor and Relayer use an almost identical Dockerfile.

Let's merge them and use something like ARG TARGET_BINARY w/

  • TARGET_BINARY=astria-sequencer-relayer
  • TARGET_BINARY=astria-conductor

Considerations:

  • in what directory does this new, shared Dockerfile go?

newly proposed blocks should be marked "head", and commited should be marked "safe"

When tendermint proposes a new block, the block contains the commit for the parent block. However, the conductor currently treats this incorrectly, as when it receives a newly-proposed block, it executes it and marks it as safe/softly-committed, even though it's not actually finalized by tendermint yet. The correct logic when receiving a newly proposed block would be:

  • execute and mark newly proposed block as "head" of chain
  • verify commit contained in block (which is for the parent block), if it's verified, then mark parent block as "safe"
  • receiving block from DA remains the same

Requires:

  • updating the gRPC service to have methods such as:
ExecuteAndMarkAsHead(txs, prev_block_hash)
SetBlockAsSafe(block_hash)
SetBlockAsFinal(block_hash)
  • updating the geth fork to support these methods
  • updating conductor to correctly handle newly proposed vs committed blocks

blocked by #44

submit entire shared sequencer block to celestia in single transaction

Currently we submit a separate PFB (pay-for-bytes) transaction to Celestia for each rollup's transactions rather than a single transaction for the entire shared sequencer block.
The reason for this is that Celestia does not yet support batching data to multiple namespaces in a single transaction. However, this is likely to change in the near future as there is an existing PR to change this.

This means a cross-rollup bundle wouldn't be atomic because there would be one Celestia tx for rollup A and one for rollup B. This has several implications/problems:

  1. A shared sequencer block can be partially censored by a Celestia node.
  2. A shared sequencer block can be spread over several Celestia nodes due to gas limits.
    This affects the liveness guarantees that the shared sequencer provides to the rollups built on it and with it potentially the MEV market. Generally, the current situation is not desirable and needs to be updated once the changes are incorporated into Celestia.

When making this change, issue #31 should also be addressed.

flatten `SequencerBlock` protos

Current situation

The current SequencerBlock proto definition has a nested array of transactions:

// data.proto
// IndexedTransaction represents a sequencer transaction along with the index
// it was originally in the sequencer block.
message IndexedTransaction {
    uint64 block_index = 1; // TODO: this is usize - how to define for variable size?
    bytes transaction = 2;
}

// block.proto
message NamespacedIndexedTransactions {
    bytes namespace = 1;
    repeated IndexedTransaction txs = 2;
}

// SequencerBlock
message SequencerBlock {
    bytes block_hash = 1;
    tendermint.types.Header header = 2;
    repeated IndexedTransaction sequencer_transactions = 3;
    repeated NamespacedIndexedTransactions rollup_txs = 4;
}

The problem

The problem with this, as described by Janis:
"From my experience deeply nested repeated types (so fields with aย repeatedย prefix and things likeย map) are tricky from a performance-standpoint, because rust (or any language) can't amortize memory allocation away.So if you have soomething likeย Vec<Vec<T>>ย and lots of small inner vectors (say with 20 elements on average), you will end up with 4 memory allocations per inner vector (4 -> 8 -> 16 -> 32). Let's say you have 100 elements in the outer vector, that's 406 memory allocations in total, 400 memory allocations for the inner vecs + 6 allocations for the outer vec (4 -> 8 -> 16 -> 32 -> 64 -> 128).If you find a way to flatten this data structure so that you just have a 1d vector with 400 elements in total, you can bring this down from 406 to 8 (128 -> 256 -> 512)."

Proposed solutions

As discussed, there are several possible solutions to this:

  1. Flatten the namespace into each IndexedTransaction, i.e. have:
    // block.proto
    message NamespacedIndexedTransaction {
        bytes namespace = 1;
        IndexedTransaction tx = 2;
    }
    
    // SequencerBlock
    message SequencerBlock {
        bytes block_hash = 1;
        tendermint.types.Header header = 2;
        repeated IndexedTransaction sequencer_transactions = 3;
        repeated NamespacedIndexedTransaction rollup_txs = 4;
    }
    where SequencerBlock.rollup_txs is the flattened vector of all the rollup txs.
    This has the effect of adding a namespace for each transaction, instead of one per rollup. The result is a potentially significantly increased block size for the sequencer-relayer to gossip along with soft commitments.
  2. Store all IndexedTransactions in one long vector, and add a vector of (namespace, length) tuples that can be used to break apart the long vector into rollup-specific vectors of IndexedTransactions:
    // block.proto
    message RollupTxLength {
        bytes namespace = 1;
        uint64 length = 2;
    }
    
    message SequencerBlock {
        bytes block_hash = 1;
        tendermint.types.Header header = 2;
        repeated IndexedTransaction sequencer_transactions = 3;
        repeated IndexedTransaction rollup_txs = 4;
        repeated RollupTxLength rollup_lengths = 5;
    }
    This makes the serialized blocks less resource intensive by avoiding the repeated namespaces added in the previous approach and the nested vector reallocations as described by Janis above.
    However, it comes at the cost of added complexity in implementation and requiring heavy documentation for future maintenance. More specifically, any implementation would have to add logic along the lines of:
    pub struct SequencerBlock {
        pub block_hash: Base64String,
        pub header: Header,
        pub sequencer_txs: Vec<IndexedTransaction>,
        pub rollup_txs: HashMap<Namespace, Vec<IndexedTransaction>>,
    }
    
    impl From<SequencerBlockProto> for SequencerBlock {
        fn from (value: SequencerBlockProto) -> Self {
            // init empty sequencer block
            let block: SequencerBlock = SequencerBlock::default();
            // convert from bytes to Base64String and so on
            // ...
            // parse rollup txs
            value.rollup_lengths
                .iter()
                .map(|(namespace, len)| 
                    block.rollup_txs[namespace] = value.rollup_txs.iter()
                        .take(len)
                        .collect::<Vector<IndexedTransaction>>();
                )
            }
    }

Context

I chose to leave this issue for later implementation because the definition of SequencerBlock is likely to change in the near future.
Specifically, the current structure is a result of the fact that we are submitting each rollup's transactions to Celestia in a separate PFB (pay-for-bytes) transactions. This is because Celestia does not support batching data to multiple namespaces in a single transaction.
However, this is likely to change in the near future as there is an existing PR to change this.

implement DHT discovery

right now, there's only local discovery with mDNS. need to add a DHT for non-local discovery

sequencer: basic PoA implementation

the sequencer node should have a basic PoA component type that is able to rotate the validator set. note that cometbft already has the ability to have any amount of validators at genesis, so this component would deal with changing the validator set.

open question:

  • when/how do we change the validator set? is it a multisig of the existing validators, or is there a "sudo" key that is allowed to authorize validator set changes?
  • do we change the validator set at the next block (or some other defined block height) once a change has been proposed and accepted? or do we implement an epoch-based system where all changes happen at a fixed height?

IBC Bridging between Celestia and Astria Sequencer

Stub issue epic to track work for IBC bridging between Celestia and Astria

Tasks

Maybe relevant issues

Separate k8s test environment deployments into pods

Because our test environment pods started their life on podman all containers were made part of a single pod. Now that we are running on kubernetes it makes more sense to split the containers out into separate pods, connect them via services, and stop worrying about overlapping ports. This should simplify a lot of test setups by using defaults.

As raised in a peer review:

2/3 of these arguments are default values. --sequencer-endpoint=http://localhost:1318 is the only one that is not a default because we're manually configuring Metro for 1318, but I think that was changed from 1317 to avoid port conflicts, which are no longer a concern.

Could we start Metro on 1317 again, which would allow us to get rid of all three of these arguments?

Originally posted by @steezeburger in #6 (comment)

Block Explorer for Sequencer

TODO: Fill out the stub

Tasks

Q: Is it easy to design parts of the sequencer so that it's easy to create a block explorer?

refactor services into rich library types and minimalist binary wrappers

At the moment astria-conductor and astria-sequencer-relayer have overly complex binary definitions. Their binary entrypoints should be as minimal as possible, while their backing libraries should only expose:

  1. getting the config
  2. setting up telemetry
  3. running the service (Conductor and `SequencerRelayer, respectively)

The primary goals are:

  1. code clarity (i.e. making it immediately clear where to main entrypoint to the services are)
  2. decoupling (binary crates must not import items from other binary crates)
  3. running integration tests against the same codepaths that are used when running the services as binaries

Tasks

  1. 4 of 4
    epic refactor sequencer-relayer
    SuperFluffy
  2. 3 of 4
    conductor refactor

Use system rocksdb in CI and docker

As a followup to #5 building rocksdb in CI and docker should be done with a system rocksdb instead of a vendoring it.

Because cargo does not seem to reason about the generated rocksdb artifacts, they are also not cached. Together with rocksdb builds being very slow this leads to very slow CI.

The rust-cache github action seems to cache rocksdb just fine, but the same cannot be said for docker.

Relevant github issues:

rust-rocksdb/rust-rocksdb#310 (comment)
rust-rocksdb/rust-rocksdb#354 (comment)

conductor reader validates `SequencerNamespaceData` before checking that block contains relevant namespace txs

as title says, this is because the Reader doesn't contain the namespace the conductor cares about, but the Executor does, and checks whether the block should be executed. this should be changed so we aren't validating irrelevant blocks.

note: this may not be relevant, and depends upon our design/relation of the conductor to a tendermint light client; if we run a light client internally to the conductor (ie. track the validator set) then we need to keep this, but if we assume we have a trusted external client as we do right now, we can change this.

Define Rollup interface to Shared Sequencer

What does it mean when a rollup is "deployed" to the shared sequencer? What components need to get stood up?

user-journeys

Tasks

No tasks being tracked yet.

move shared "read" and types code from relayer/conductor to utils crate

currently, there is a decent amount of code shared between the relayer and conductor, mainly by means of the conductor importing the relayer code. however, this shared code should live in some utils crate used by both. this will allow them to not depend on each other, and also facilitate testing within the conductor.

astria-rs-cnc integration tests need celestia running

The roundtrip test in astria-rs-cnc needs a celestia node listening on port 26659 and will fail otherwise.

Locally the error is not clear (might need a better message), but on CI we need to provide it with a test environment similar to what is done in astria-conductor and astria-sequencer-relayer.

sequencer: implement fee payments

transactions are currently free and don't cost anything. however, transactions should pay some fee.

requirements:

  • determine fee that Transfer and Secondary txs should take
  • Transfer should be fixed amount
  • Secondary should be based on tx size
  • implement checking that sender has enough balance to pay for the fee
  • implement fee deduction at execution time

related to but not necessarily blocked by #64 and #65

conductor: queue for block ordering and execution

we need to execute blocks in order, without any gaps. however, this is not guaranteed by the current implementation.

we should implement some sort of queue that ensures blocks are executed in the correct sequence, and a block cannot be executed without its parent being the current head.

sequencer: implement "secondary" transaction type

implement an un-executed transaction type that is a tx destined for a rollup:

pub struct SecondaryTransaction {
    tx: Vec<u8>,
    chain_id: Vec<u8>,
    signature,
    public_key,
}

validation will basically just be validating the signature.

blocked by #64 (at least the signature / public key parts)

validate tendermint commits on each block

when we read a block, we need to ensure that the block was actually finalized by the sequencer. since we have access to the sequencer's validator information, we need to ensure that the block's commit contains >2/3 validator stake signatures.

Add support for edge cases around soft commitments

Currently in conductor, soft commits (gossiped) transactions are executed (via DoBlock) and firm commits (from DA) are finalized (FinalizeBlock).

We need support for various edge cases where transactions aren't seen immediately:

  • gossip not working, transactions seen first in DA
  • missed astria block via gossip (ie block number 10 received but 9 is not)

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.