This doesn't have a well-defined affine representation. k256's behavior,
mapping it to (0, 0), means this would've been rejected anyways (so this isn't
a change of any current behavior), but it's best not to rely on such an
implementation detail.
This moves to Rust 1.86 as were prior on Rust 1.81, and the new alloy
dependencies require 1.82.
The revm API changes were notable for us. Instead of relying on a modified call
instruction (with deep introspection into the EVM design), we now use the more
recent and now more prominent Inspector API. This:
1) Lets us perform far less introspection
2) Forces us to rewrite the gas estimation code we just had audited
Thankfully, it itself should be much easier to read/review, and our existing
test suite has extensively validated it.
This resolves 001 which was a concern for if/when this upgrade occurs. By doing
it now, with a dedicated test case ensuring the issue we would have had with
alloy-core 0.8 and `validate=false` isn't actively an issue, we resolve it.
This allows the CREATE code to bork without the Serai router losing access to
the coins in question. It does incur overhead on the deployed contract, which
now no longer just has to query its balance but also has to call the
transferFrom, but its a safer pattern and not a UX detriment.
This also improves documentation.
CREATE was originally intended for gas savings. While one sketch did move to
CREATE2, the security concerns around address collisions (requiring all init
codes not be malleable to achieve security) continue to justify this.
To resolve the gas estimation concerns raised in the prior commit, the
createAddress function has been made constant-gas.
Adds a minimal amount of packages. Does add decent complexity. Avoids having
constants which aren't exact, due to things like the quadratic memory cost, and
the issues with such estimates accordingly.
It had sequential async calls with complexity O(n), with a variety of redundant
calls. There was also a constant of... 4? 5? for each item. Now, the total
sequence depth is just 3-4.
Completes the `Executed` enum in the router. Adds an `Escape` struct. Both are
needed for testing purposes.
Documents the gas constants in intent and reasoning.
Adds modernized tests around key rotation and the escape hatch.
Also updates the rest of the codebase which had accumulated errors.
Also removes the expectation Batches published via it are sent in an ordered
fashion. That won't be true if the signing protocols complete out-of-order (as
possible when we are signing them in parallel).
We explicitly no longer slash stakes but we still set the maximum slash to the
allocated stake + the rewards. Now, the reward slash is bound to the rewards
and the stake slash is bound to the stake. This prevents an improperly rounded
reward slash from effecting a stake slash.
This isn't necessary. Because we just log the error, we never match off of it,
we don't need any structure beyond String (or now Debug, which still gives us
a way to print the error). This is for the ergonomics of not having to
constantly write `.map_err(|e| format!("{e:?}"))`.
coordinator/tributary was tributary-chain. This crate has been renamed
tributary-sdk and moved to coordinator/tributary-sdk.
coordinator/src/tributary was our instantion of a Tributary, the Transaction
type and scan task. This has been moved to coordinator/tributary.
The main reason for this was due to coordinator/main.rs becoming untidy. There
is now a collection of clean, independent APIs present in the codebase.
coordinator/main.rs is to compose them. Sometimes, these compositions are a bit
silly (reading from a channel just to forward the message to a distinct
channel). That's more than fine as the code is still readable and the value
from the cleanliness of the APIs composed far exceeds the nits from having
these odd compositions.
This breaks down a bit as we now define a global database, and have some APIs
interact with multiple other APIs.
coordinator/src/tributary was a self-contained, clean API. The recently added
task present in coordinator/tributary/mod.rs, which bound it to the rest of the
Coordinator, wasn't.
Now, coordinator/src is solely the API compositions, and all self-contained
APIs are their own crates.
Makes `Clone` calls significantly cheaper as now only the outer Arc is cloned
(the inner ones have been removed). Also wraps uses of Serai in an Arc as we
shouldn't actually need/want multiple caller connection pools.
Decoding slash evidence requires specifying the instantiated generic
`TendermintNetwork`. While irrelevant, that generic includes a type satisfying
`tributary::P2p`. It was only possible to route now that we've redone the P2P
API.
The check in validators prevented connections from non-validators.
Non-validators could still participate in the network if they laundered their
connection through a malicious validator. allow_block_list ensures that peers,
not connections, are explicitly limited to validators.
Moves UpdateSharedValidatorsTask to validators.rs. While prior planned to
re-use a validators object across connecting and peer state management, the
current plan is to use an independent validators object for each to minimize
any contention. They should be built infrequently enough, and cheap enough to
update in the majority case (due to quickly checking if an update is needed),
that this is fine.
TaskHandle::close meant run_now may panic if the task was closed. Now, tasks
are only closed when all handles are dropped, causing all handles to point to
running tasks (ensuring run_now won't panic).
Renames `label` to `round` since `Label` was renamed to `SigningProtocolRound`.
Adds some more context-less validation to transactions which used to be done
within the custom decode function which was simplified via the usage of borsh.
Documents in processor-messages where the Coordinator sends each of its
messages.
It's not only helpful (to easily check where Serai's view of the external
network is) but it's necessary in case of a non-trivial chain fork to determine
which blockchain Serai considers canonical.
If Substrate has a block 500 with a key gen, and a block 600 with a key gen,
and the session starting on 500 never cosigns everything, everyone up-to-date
will want the cosigns for the session starting on block 500. Everyone
up-to-date will also be rebroadcasting the non-existent cosigns for the session
which has yet to start. This wouldn't cause a stall as eventually, each
individual set would cosign the latest notable block, and then that would be
explicitly synced, but it's still not the intended behavior.
We also won't even intake the cosigns for the latest intended session if it
exceeds the session we're currently evaluating. This does mean those behind on
the cosigning protocol wouldn't have rebroadcasted their historical cosigns,
and now will, but that's valuable as we don't actually know if we're behind or
up-to-date (per above posited issue).
We read from it but never writ to it.
It was used to check we didn't flag a block as notable after reporting it, but
it was called by the scan task as it scanned a block. We only batch/report
blocks after the scan task after scanning them, so it was very redundant.
It's only there to make the VariantSignid unique across Sessions. By localizing
the VariantSignid to a Session, we avoid this, and can better ensure we don't
queue work for historic sessions.
This is incomplete at this time. The logic is fine, but needs to be moved to a
distinct location to handle singular blocks which produce multiple Batches.
We don't have consensus on the session's last block, so we shouldn't check if
the cosign is before the session ends. What matters is that network, within its
set, claims it's still active at that block (on its view of the blockchain).
An archive of all GlobalSessions is necessary to check for faults. The storage
cost is also minimal. While it should be avoided if it can be, it can't be
here.
Cosigns was an archive of every single cosign ever received. By scoping
NetworksLatestCosignedBlock to be by the global session, we have the latest
cosign for each network in a session (valid to replace all prior cosigns by
that network within that session, even for the purposes of fault) and
automatically have the notable cosigns indexed (as they are the latest ones
within their session). This not only saves space yet also allows optimizing
evaluation a bit.
Not only cleans the existing cosign code but enables non-Serai-coordinators to
evaluate cosigns if they gain access to a feed of them (such as over an RPC).
This would let centralized services not only track the finalized chain yet the
cosigned chain without directly running a coordinator.
Still being wrapped up.
* WIP constant-time implementation of the ec-divisors library
* Fix misc logic errors in poly.rs
* Remove accidentally committed test statements
* Fix ConstantTimeEq for CoefficientIndex
* Correct the iterations formula
x**3 / (0 y + x**1) would prior be considered indivisible with iterations = 0.
It is divisible however. The amount of iterations should be the amount of
coefficients within the numerator *excluding the coefficient for y**0 x**0*.
* Poly PartialEq, conditional_select_poly which checks poly structure equivalence
If the first passed argument is smaller than the latter, it's padded to the
necessary length.
Also adds code to trim the remainder as the remainder is the value modulo, so
it's very important it remains concise and workable.
* Fix the line function
It selected the case if both were identity before selecting the case if either
were identity, the latter overwriting the former.
* Final fixes re: ct_get
1) Our quotient structure does need to be of size equal to the numerator
entirely to prevent out-of-bounds reads on it
2) We need to get from yx_coefficients if of length >=, so if the length is 1
we can read y_pow=1 from it. If y_pow=0, and its length is 0 so it has no
inner Vecs, we need to fall back with the guard y_pow != 0.
* Add a trim algorithm to lib.rs to prevent Polys from becoming unbearably gigantic
Our Poly algorithm is incredibly leaky. While it presumably should be improved,
we can take advantage of our known structure while constructing divisors (and
the small modulus) to simply trim out the zero coefficients leaked. This
maintains Polys in a manageable size.
* Move constant-time scalar mul gadget divisor creation from dkg to ec-divisors
Anyone creating a divisor for the scalar mul gadget should use constant time
code, so this code should at least be in the EC gadgets crate It's of
non-trivial complexity to deal with otherwise.
* Remove unsafe, cache timing attacks from ec-divisors
monero-wallet ships an Eventuality, yet it's across the entire transaction. It
can't prove a single output's state with a traditional payment proof. By adding
this new object, another library can obtain the ephemeral randomness used and
do any/every proof they want regarding a transaction's outputs.
Necessary for https://github.com/serai-dex/serai/issues/599.
This technically has a TOCTOU where we sync an Epoch's metadata (signifying we
did sync to that point), then check if the Router was deployed, yet at that
very moment the node resets to genesis. By ensuring the Router is deployed, we
avoid this (and don't need to track the deployment block in-contract).
Also uses a JoinSet to sync the 32 blocks in parallel.
The caller is paid a fixed fee per unit of gas spent. That arguably
incentivizes the publisher to raise the gas used by internal calls, yet this
doesn't effect the user UX as they'll have flatly paid the worst-case fee
already. It does pose a risk where callers are arguably incentivized to cause
transaction failures which consume all the gas, not just increased gas, yet:
1) Modern smart contracts don't error by consuming all the gas
2) This is presumably infeasible
3) Even if it was feasible, the gas fees gained presumably exceed the gas fees
spent causing the failure
The benefit to only paying the callers for the gas used, not the gas alotted,
is it allows Serai to build up a buffer. While this should be minor, a few
cents on every transaction at best, if we ever do have any costs slip through
the cracks, it ideally is sufficient to handle those.
contracts was smashed out of ethereum-serai. Both have now been smashed into
individual crates.
Creates a TODO directory with left-over test code yet to be moved.
The router will now match the top-level transfer so it isn't used as the
justification for the InInstruction it's handling. This allows the theoretical
case where a top-level transfer occurs (to any entity) and an internal call
performs a transfer to Serai.
Also uses a JoinSet for fetching transactions' top-level transfers in the ERC20
crate. This does add a dependency on tokio yet improves performance, and it's
scoped under serai-processor (which is always presumed to be tokio-based).
While we could instead import futures for join_all,
https://github.com/smol-rs/futures-lite/issues/6 summarizes why that wouldn't
be a good idea. While we could prefer async-executor over tokio's JoinSet,
JoinSet doesn't share the same issues as FuturesUnordered. That means our
question is solely if we want the async-executor executor or the tokio
executor, when we've already established the Serai processor is always presumed
to be tokio-based.
It makes sense for networks which support arbitrary data to do as part of their
address. This reduces the ability to perform DoSs, achieves better performance,
and better uses the type system (as now networks we don't support data on don't
have a data field).
Updates the Ethereum address definition in serai-client accordingly
If instead of intaking calls, we intake code, we can deploy a fresh contract
which makes arbitrary calls *without* attempting to build our abstraction
layer over the concept.
This should have the same gas costs, as we still have one contract deployment.
The new contract only has a constructor, so it should have no actual code and
beat the Sandbox in that regard? We do have to call into ourselves to meter the
gas, yet we already had to call into the deployed Sandbox to achieve that.
Also re-defines the OutInstruction to include tokens, implements
OutInstruction-specified gas amounts, bumps the Solidity version, and other
such misc changes.
I don't love this, but it's the only way to select decoys without using a local
database. While the prior commit added such a databse, the performance of it
presumably wasn't viable, and while TODOs marked the needed improvements, it
was still messy with an immense scope re: any auditing.
The relevant scheduler functions now take `&self` (intentional, as all
mutations should be via the `&mut impl DbTxn` passed). The calls to `&self` are
expected to be completely deterministic (as usual).
The provided message-queue queue functions runs unti it succeeds. This means
sending to the message-queue will no longer potentially block for arbitrary
amount of times as sending messages is just writing them to a DB.
Moves the coordinator loop out of serai-bitcoin-processor, completing it.
Fixes a potential race condition in the message-queue regarding multiple
sockets sending messages at once.
Before we yield a block for scanning, we save all of the contained script
public keys. Then, when we want the address credited for creating an output,
we read the script public key of the spent output from the database.
Fixes#559.
I don't love this. I wanted to simply add this function to `processor/key-gen`,
but then anyone who wants a view key needs to pull in Bulletproofs which is a
mess of code. They'd also be subject to an AGPL licensed library.
This is so small it should be a primitive elsewhere, yet there is no primitives
library eligible. Maybe serai-client since that has the code to make
transactions to Serai (and will have this as a dependency)? Except then the
processor has to import serai-client when this rewrite removed it as a
dependency.
We'd report the amount originally received, minus 2x the cost to aggregate,
regardless the amount successfully forwarded. We should've reduced to the
amount successfully forwarded, if it was smaller, in case the cost to
forward exceeded the aggregation cost.
The main benefit is whatever scheduler is in use, we now have a single API to
receive TXs to sign (which is of value to the TX signer crate we'll inevitably
build).
`acknowledge_batch` can only be run if we know what the Batch should be. If we
don't know what the Batch should be, we have to block until we do.
Specifically, we need the block number associated with the Batch.
Instead of blocking over the Scanner API, the Scanner API now solely queues
actions. A new task intakes those actions once we can. This ensures we can
intake the entire Substrate chain, even if our daemon for the external network
is stalled at its genesis block.
All of this for the block number alone seems ridiculous. To go from the block
hash in the Batch to the block number without this task, we'd at least need the
index task to be up to date (still requiring blocking or an API returning
ephemeral errors).
It's still unclear how we'll handle refunding failed InInstructions at this
time. Presumably, extending the InInstruction channel with the associated
output ID?
Has fetched blocks checked to be the indexed blocks. Has scanned outputs be
sorted, meaning they aren't subject to implicit order/may be non-deterministic
(such as if handled by a threadpool).
Scan now only handles External outputs, with an associated essay going over
why. Scan directly creates the InInstruction (prior planned to be done in
Report), and Eventuality is declared to end up yielding the outputs.
That will require making the Eventuality flow two-stage. One stage to evaluate
existing Eventualities and yield outputs, and one stage to incorporate new
Eventualities before advancing the scan window.
Abstract, to be done for the transactions, the batches, the cosigns, the slash
reports, everything. It has a minimal API itself, intending to be as clear as
possible.
* Upstream GBP, divisor, circuit abstraction, and EC gadgets from FCMP++
* Initial eVRF implementation
Not quite done yet. It needs to communicate the resulting points and proofs to
extract them from the Pedersen Commitments in order to return those, and then
be tested.
* Add the openings of the PCs to the eVRF as necessary
* Add implementation of secq256k1
* Make DKG Encryption a bit more flexible
No longer requires the use of an EncryptionKeyMessage, and allows pre-defined
keys for encryption.
* Make NUM_BITS an argument for the field macro
* Have the eVRF take a Zeroizing private key
* Initial eVRF-based DKG
* Add embedwards25519 curve
* Inline the eVRF into the DKG library
Due to how we're handling share encryption, we'd either need two circuits or to
dedicate this circuit to the DKG. The latter makes sense at this time.
* Add documentation to the eVRF-based DKG
* Add paragraph claiming robustness
* Update to the new eVRF proof
* Finish routing the eVRF functionality
Still needs errors and serialization, along with a few other TODOs.
* Add initial eVRF DKG test
* Improve eVRF DKG
Updates how we calculcate verification shares, improves performance when
extracting multiple sets of keys, and adds more to the test for it.
* Start using a proper error for the eVRF DKG
* Resolve various TODOs
Supports recovering multiple key shares from the eVRF DKG.
Inlines two loops to save 2**16 iterations.
Adds support for creating a constant time representation of scalars < NUM_BITS.
* Ban zero ECDH keys, document non-zero requirements
* Implement eVRF traits, all the way up to the DKG, for secp256k1/ed25519
* Add Ristretto eVRF trait impls
* Support participating multiple times in the eVRF DKG
* Only participate once per key, not once per key share
* Rewrite processor key-gen around the eVRF DKG
Still a WIP.
* Finish routing the new key gen in the processor
Doesn't touch the tests, coordinator, nor Substrate yet.
`cargo +nightly fmt && cargo +nightly-2024-07-01 clippy --all-features -p serai-processor`
does pass.
* Deduplicate and better document in processor key_gen
* Update serai-processor tests to the new key gen
* Correct amount of yx coefficients, get processor key gen test to pass
* Add embedded elliptic curve keys to Substrate
* Update processor key gen tests to the eVRF DKG
* Have set_keys take signature_participants, not removed_participants
Now no one is removed from the DKG. Only `t` people publish the key however.
Uses a BitVec for an efficient encoding of the participants.
* Update the coordinator binary for the new DKG
This does not yet update any tests.
* Add sensible Debug to key_gen::[Processor, Coordinator]Message
* Have the DKG explicitly declare how to interpolate its shares
Removes the hack for MuSig where we multiply keys by the inverse of their
lagrange interpolation factor.
* Replace Interpolation::None with Interpolation::Constant
Allows the MuSig DKG to keep the secret share as the original private key,
enabling deriving FROST nonces consistently regardless of the MuSig context.
* Get coordinator tests to pass
* Update spec to the new DKG
* Get clippy to pass across the repo
* cargo machete
* Add an extra sleep to ensure expected ordering of `Participation`s
* Update orchestration
* Remove bad panic in coordinator
It expected ConfirmationShare to be n-of-n, not t-of-n.
* Improve documentation on functions
* Update TX size limit
We now no longer have to support the ridiculous case of having 49 DKG
participations within a 101-of-150 DKG. It does remain quite high due to
needing to _sign_ so many times. It'd may be optimal for parties with multiple
key shares to independently send their preprocesses/shares (despite the
overhead that'll cause with signatures and the transaction structure).
* Correct error in the Processor spec document
* Update a few comments in the validator-sets pallet
* Send/Recv Participation one at a time
Sending all, then attempting to receive all in an expected order, wasn't working
even with notable delays between sending messages. This points to the mempool
not working as expected...
* Correct ThresholdKeys serialization in modular-frost test
* Updating existing TX size limit test for the new DKG parameters
* Increase time allowed for the DKG on the GH CI
* Correct construction of signature_participants in serai-client tests
Fault identified by akil.
* Further contextualize DkgConfirmer by ValidatorSet
Caught by a safety check we wouldn't reuse preprocesses across messages. That
raises the question of we were prior reusing preprocesses (reusing keys)?
Except that'd have caused a variety of signing failures (suggesting we had some
staggered timing avoiding it in practice but yes, this was possible in theory).
* Add necessary calls to set_embedded_elliptic_curve_key in coordinator set rotation tests
* Correct shimmed setting of a secq256k1 key
* cargo fmt
* Don't use `[0; 32]` for the embedded keys in the coordinator rotation test
The key_gen function expects the random values already decided.
* Big-endian secq256k1 scalars
Also restores the prior, safer, Encryption::register function.
* move economic security into it's own pallet
* fix deny
* Update Cargo.toml, .github for the new crates
* Remove unused import
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Preserves the fn accessors within the Monero crates so that we can use statics
in some cfgs yet not all (in order to provide support for more low-memory
devices) with the exception of `H` (which truly should be cached).
* Rename the coins folder to networks
Ethereum isn't a coin. It's a network.
Resolves#357.
* More renames of coins -> networks in orchestration
* Correct paths in tests/
* cargo fmt
* Clear upons upon round, not block
* Cache the proposal for a round
* Rebase onto develop, which reverted this PR, and re-apply this PR
* Set participation upon participation instead of constantly recalculating
* Cache message instances
* Add missing txn commit
Identified by @akildemir.
* Correct clippy lint identified upon rebase
* Fix tendermint chain sync (#581)
* fix p2p Reqres protocol
* stabilize tributary chain sync
* fix pr comments
---------
Co-authored-by: akildemir <34187742+akildemir@users.noreply.github.com>
* Remove unsafe creation of dalek_ff_group::EdwardsPoint in BP+
* Rename Bulletproofs to Bulletproof, since they are a single Bulletproof
Also bifurcates prove with prove_plus, and adds a few documentation items.
* Make CLSAG signing private
Also adds a bit more documentation and does a bit more tidying.
* Remove the distribution cache
It's a notable bandwidth/performance improvement, yet it's not ready. We need a
dedicated Distribution struct which is managed by the wallet and passed in.
While we can do that now, it's not currently worth the effort.
* Tidy Borromean/MLSAG a tad
* Remove experimental feature from monero-serai
* Move amount_decryption into EncryptedAmount::decrypt
* Various RingCT doc comments
* Begin crate smashing
* Further documentation, start shoring up API boundaries of existing crates
* Document and clean clsag
* Add a dedicated send/recv CLSAG mask struct
Abstracts the types used internally.
Also moves the tests from monero-serai to monero-clsag.
* Smash out monero-bulletproofs
Removes usage of dalek-ff-group/multiexp for curve25519-dalek.
Makes compiling in the generators an optional feature.
Adds a structured batch verifier which should be notably more performant.
Documentation and clean up still necessary.
* Correct no-std builds for monero-clsag and monero-bulletproofs
* Tidy and document monero-bulletproofs
I still don't like the impl of the original Bulletproofs...
* Error if missing documentation
* Smash out MLSAG
* Smash out Borromean
* Tidy up monero-serai as a meta crate
* Smash out RPC, wallet
* Document the RPC
* Improve docs a bit
* Move Protocol to monero-wallet
* Incomplete work on using Option to remove panic cases
* Finish documenting monero-serai
* Remove TODO on reading pseudo_outs for AggregateMlsagBorromean
* Only read transactions with one Input::Gen or all Input::ToKey
Also adds a helper to fetch a transaction's prefix.
* Smash out polyseed
* Smash out seed
* Get the repo to compile again
* Smash out Monero addresses
* Document cargo features
Credit to @hinto-janai for adding such sections to their work on documenting
monero-serai in #568.
* Fix deserializing v2 miner transactions
* Rewrite monero-wallet's send code
I have yet to redo the multisig code and the builder. This should be much
cleaner, albeit slower due to redoing work.
This compiles with clippy --all-features. I have to finish the multisig/builder
for --all-targets to work (and start updating the rest of Serai).
* Add SignableTransaction Read/Write
* Restore Monero multisig TX code
* Correct invalid RPC type def in monero-rpc
* Update monero-wallet tests to compile
Some are _consistently_ failing due to the inputs we attempt to spend being too
young. I'm unsure what's up with that. Most seem to pass _consistently_,
implying it's not a random issue yet some configuration/env aspect.
* Clean and document monero-address
* Sync rest of repo with monero-serai changes
* Represent height/block number as a u32
* Diversify ViewPair/Scanner into ViewPair/GuaranteedViewPair and Scanner/GuaranteedScanner
Also cleans the Scanner impl.
* Remove non-small-order view key bound
Guaranteed addresses are in fact guaranteed even with this due to prefixing key
images causing zeroing the ECDH to not zero the shared key.
* Finish documenting monero-serai
* Correct imports for no-std
* Remove possible panic in monero-serai on systems < 32 bits
This was done by requiring the system's usize can represent a certain number.
* Restore the reserialize chain binary
* fmt, machete, GH CI
* Correct misc TODOs in monero-serai
* Have Monero test runner evaluate an Eventuality for all signed TXs
* Fix a pair of bugs in the decoy tests
Unfortunately, this test is still failing.
* Fix remaining bugs in monero-wallet tests
* Reject torsioned spend keys to ensure we can spend the outputs we scan
* Tidy inlined epee code in the RPC
* Correct the accidental swap of stagenet/testnet address bytes
* Remove unused dep from processor
* Handle Monero fee logic properly in the processor
* Document v2 TX/RCT output relation assumed when scanning
* Adjust how we mine the initial blocks due to some CI test failures
* Fix weight estimation for RctType::ClsagBulletproof TXs
* Again increase the amount of blocks we mine prior to running tests
* Correct the if check about when to mine blocks on start
Finally fixes the lack of decoy candidates failures in CI.
* Run Monero on Debian, even for internal testnets
Change made due to a segfault incurred when locally testing.
https://github.com/monero-project/monero/issues/9141 for the upstream.
* Don't attempt running tests on the verify-chain binary
Adds a minimum XMR fee to the processor and runs fmt.
* Increase minimum Monero fee in processor
I'm truly unsure why this is required right now.
* Distinguish fee from necessary_fee in monero-wallet
If there's no change, the fee is difference of the inputs to the outputs. The
prior code wouldn't check that amount is greater than or equal to the necessary
fee, and returning the would-be change amount as the fee isn't necessarily
helpful.
Now the fee is validated in such cases and the necessary fee is returned,
enabling operating off of that.
* Restore minimum Monero fee from develop
* fix total allocated stake update in wrong time
* Restore mid-set increases
* Correct typo I introduced
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* add node side unit test
* complete rotation test for all networks
* set up the fast-epoch docker file
* fix pr comments
* add coordinator side rotation test
* bug fixes
* Remove EPOCH_INTERVAL
* Minor nits
* Add note on origin of publish_tx function in tests/coordinator
* Correct ThresholdParams assert_eq
* fmt
* Correct detection of handover completion
* Restore key gen message match from develop
It was modified in response to the handover completion bug, which has now been
resolved.
* bug fixes
* Correct invalid constant
* Typo fixes
* remove selecting participant to remove at random
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
We prior required they had the same encoding, yet this ensures they do by
making them one and the same. This does require an large, ugly, From/TryInto
block which is deemed preferable for moving this more and more into syntax
(from semantics).
Further improvements (notably re: Extra) is possible, and this already lets us
strip some members from the Call enum.
* Check if the serai wasm was built successfully by verifying the build container's status code and state, instead of checking the volume mountpoint locally
* Use a log statement for which wasm is used
* Minor typo fix
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
1) Removes the key image DLEq on the Monero side of things, as the produced
signature share serves as a DLEq for it.
2) Removes the nonce DLEqs from modular-frost as they're unnecessary for
monero-serai. Updates documentation accordingly.
Without the proof the nonces are internally consistent, the produced signatures
from modular-frost can be argued as a batch-verifiable CP93 DLEq (R0, R1, s),
or as a GSP for the CP93 DLEq statement (which naturally produces (R0, R1, s)).
The lack of proving the nonces consistent does make the process weaker, yet
it's also unnecessary for the class of protocols this is intended to service.
To provide DLEqs for the nonces would be to provide PoKs for the nonce
commitments (in the traditional Schnorr case).
* Clean up Ethereum
* Consistent contract address for deployed contracts
* Flesh out Router a bit
* Add a Deployer for DoS-less deployment
* Implement Router-finding
* Use CREATE2 helper present in ethers
* Move from CREATE2 to CREATE
Bit more streamlined for our use case.
* Document ethereum-serai
* Tidy tests a bit
* Test updateSeraiKey
* Use encodePacked for updateSeraiKey
* Take in the block hash to read state during
* Add a Sandbox contract to the Ethereum integration
* Add retrieval of transfers from Ethereum
* Add inInstruction function to the Router
* Augment our handling of InInstructions events with a check the transfer event also exists
* Have the Deployer error upon failed deployments
* Add --via-ir
* Make get_transaction test-only
We only used it to get transactions to confirm the resolution of Eventualities.
Eventualities need to be modularized. By introducing the dedicated
confirm_completion function, we remove the need for a non-test get_transaction
AND begin this modularization (by no longer explicitly grabbing a transaction
to check with).
* Modularize Eventuality
Almost fully-deprecates the Transaction trait for Completion. Replaces
Transaction ID with Claim.
* Modularize the Scheduler behind a trait
* Add an extremely basic account Scheduler
* Add nonce uses, key rotation to the account scheduler
* Only report the account Scheduler empty after transferring keys
Also ban payments to the branch/change/forward addresses.
* Make fns reliant on state test-only
* Start of an Ethereum integration for the processor
* Add a session to the Router to prevent updateSeraiKey replaying
This would only happen if an old key was rotated to again, which would require
n-of-n collusion (already ridiculous and a valid fault attributable event). It
just clarifies the formal arguments.
* Add a RouterCommand + SignMachine for producing it to coins/ethereum
* Ethereum which compiles
* Have branch/change/forward return an option
Also defines a UtxoNetwork extension trait for MAX_INPUTS.
* Make external_address exclusively a test fn
* Move the "account" scheduler to "smart contract"
* Remove ABI artifact
* Move refund/forward Plan creation into the Processor
We create forward Plans in the scan path, and need to know their exact fees in
the scan path. This requires adding a somewhat wonky shim_forward_plan method
so we can obtain a Plan equivalent to the actual forward Plan for fee reasons,
yet don't expect it to be the actual forward Plan (which may be distinct if
the Plan pulls from the global state, such as with a nonce).
Also properly types a Scheduler addendum such that the SC scheduler isn't
cramming the nonce to use into the N::Output type.
* Flesh out the Ethereum integration more
* Two commits ago, into the **Scheduler, not Processor
* Remove misc TODOs in SC Scheduler
* Add constructor to RouterCommandMachine
* RouterCommand read, pairing with the prior added write
* Further add serialization methods
* Have the Router's key included with the InInstruction
This does not use the key at the time of the event. This uses the key at the
end of the block for the event. Its much simpler than getting the full event
streams for each, checking when they interlace.
This does not read the state. Every block, this makes a request for every
single key update and simply chooses the last one. This allows pruning state,
only keeping the event tree. Ideally, we'd also introduce a cache to reduce the
cost of the filter (small in events yielded, long in blocks searched).
Since Serai doesn't have any forwarding TXs, nor Branches, nor change, all of
our Plans should solely have payments out, and there's no expectation of a Plan
being made under one key broken by it being received by another key.
* Add read/write to InInstruction
* Abstract the ABI for Call/OutInstruction in ethereum-serai
* Fill out signable_transaction for Ethereum
* Move ethereum-serai to alloy
Resolves#331.
* Use the opaque sol macro instead of generated files
* Move the processor over to the now-alloy-based ethereum-serai
* Use the ecrecover provided by alloy
* Have the SC use nonce for rotation, not session (an independent nonce which wasn't synchronized)
* Always use the latest keys for SC scheduled plans
* get_eventuality_completions for Ethereum
* Finish fleshing out the processor Ethereum integration as needed for serai-processor tests
This doesn't not support any actual deployments, not even the ones simulated by
serai-processor-docker-tests.
* Add alloy-simple-request-transport to the GH workflows
* cargo update
* Clarify a few comments and make one check more robust
* Use a string for 27.0 in .github
* Remove optional from no-longer-optional dependencies in processor
* Add alloy to git deny exception
* Fix no longer optional specification in processor's binaries feature
* Use a version of foundry from 2024
* Correct fetching Bitcoin TXs in the processor docker tests
* Update rustls to resolve RUSTSEC warnings
* Use the monthly nightly foundry, not the deleted daily nightly
* Rewrite tendermint's message handling loop to much more clearly match the paper
No longer checks relevant branches upon messages, yet all branches upon any
state change. This is slower, yet easier to review and likely without one or
two rare edge cases.
When reviewing, please see page 5 of https://arxiv.org/pdf/1807.04938.pdf.
Lines from the specified algorithm can be found in the code by searching for
"// L".
* Sane rebroadcasting of consensus messages
Instead of broadcasting the last n messages on the Tributary side of things, we
now have the machine rebroadcast the message tape for the current block.
* Only rebroadcast messages which didn't error in some way
* Only rebroadcast our own messages for tendermint
Instead of saving, for every sent message, if it was sent or not, we track the
latest block/round participated in. These two keys are comprehensive to all
prior block/rounds. We then use three keys for the latest round's
proposal/prevote/precommit, enabling tracking current state as necessary to
prevent equivocations with just 5 keys.
The storage of the latest three messages also enables proper rebroadcasting of
the current round (not implemented in this commit).
Online validators should inherently have them. Offline validators will receive
from the sync protocol.
This does somewhat eliminate the class of nodes who would follow the blockchain
(without validating it), yet that's fine for the performance benefit.
I didn't remove async-recursion when I updated the repo to 1.77 as I forgot we
used it in the tests. I still had to add some Box::pins, which may have been a
valid option, on the prior Rust version, yet at least resolves everything now.
Also updates everything which doesn't introduce further depends.
* start Router contract
* use calldata for function args
* var name changes
* start testing router contract
* test with and without abi.encode
* cleanup
* why tf isn't tests/utils working
* cleanup tests
* remove unused files
* wip
* fix router contract and tests, add set/update public keys funcs
* impl some Froms
* make execute non-reentrant
* cleanup
* update Router to use ReentrancyGuard
* update contract to use errors, use bitfield in Executed event, minor other fixes
* wip
* fix build issues from merge, tests ok
* Router.sol cleanup
* cleanup, uncomment stuff
* bump ethers.rs version to latest
* make contract functions take generic middleware
* update build script to assert no compiler errors
* hardcode pubkey parity into contract, update tests
* Polish coins/ethereum in various ways
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Exposes flush calls.
Adds safety, at the cost of a panic risk, as multiple TXNs simultaneously
writing to a key will now cause a panic. This should be fine and the safety is
appreciated.
Part of https://github.com/serai-dex/serai/issues/345.
The lack of full DB persistence does mean enough nodes rebooting at the same
time may cause a halt. This will prevent slashes.
* monero: only mask user features on new polyseed, not on decode
- This commit ensures a polyseed string that has unsupported features correctly errors on decode (rather than panic in debug build or return an incorrect successful response in prod build)
- Also avoids panicking when checksum calculation is unexpectedly wrong
Polyseed reference impl for feature masking:
- polyseed_create: b7c35bb3c6/src/polyseed.c (L61)
- polyseed_decode: b7c35bb3c6/src/polyseed.c (L212)
* PR comments
* Make from_internal a member of Polyseed
* Add accidentally removed newline
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Monero: fix decoy selection algo and add test for latest spendable
- DSA only selected coinbase outputs and didn't match the wallet2
implementation
- Added test to make sure DSA will select a decoy output from the
most recent unlocked block
- Made usage of "height" in DSA consistent with other usage of
"height" in Monero code (height == num blocks in chain)
- Rely on monerod RPC response for output's unlocked status
* xmr runner tests mine until outputs are unlocked
* fingerprintable canoncial select decoys
* Separate fingerprintable canonical function
Makes it simpler for callers who are unconcered with consistent
canonical output selection across multiple clients to rely on
the simpler Decoy::select and not worry about fingerprintable
canonical
* fix merge conflicts
* Put back TODO for issue #104
* Fix incorrect check on distribution len
The RingCT distribution on mainnet doesn't start until well after
genesis, so the distribution length is expected to be < height.
To be clear, this was my mistake from this series of changes
to the DSA. I noticed this mistake because the DSA would error
when running on mainnet.
* monero: Use fee priority enums from monero repo CLI/RPC wallets
* Update processor for fee priority change
* Remove FeePriority::Default
Done in consultation with @j-berman.
The RPC/CLI/GUI almost always adjust up except barring very explicit commands,
hence why FeePriority 0 is now only exposed via the explicit command of
FeePriority::Custom { priority: 0 }.
Also helps with terminology.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* use median price instead of the highest sustained
* add test for lexicographically reversing a byte slice
* fix pr comments
* fix CI fail
* fix dex tests
* Use a fuzz-tested list of prices
* Working median algorithm based on position + lints
---------
Co-authored-by: akildemir <aeg_asd@hotmail.com>
* add input script check
* add test
* optimizations
* bug fix
* fix pr comments
* Test SegWit-encoded data using a single output (not two)
* Remove TODO used as a question, document origins when SegWit encoding
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Moves from concatted Dockerfiles to pseudo-templated Dockerfiles via a dedicated Rust program.
Removes the unmaintained kubernetes, not because we shouldn't have/use it, but because it's unmaintained and needs to be reworked before it's present again.
Replaces the compose with the work in the new orchestrator binary which spawns everything as expected. While this arguably re-invents the wheel, it correctly manages secrets and handles the variadic Dockerfiles.
Also adds an unrelated patch for zstd and simplifies running services a bit by greater utilizing the existing infrastructure.
---
* Delete all Dockerfile fragments, add new orchestator to generate Dockerfiles
Enables greater templating.
Also delete the unmaintained kubernetes folder *for now*. This should be
restored in the future.
* Use Dockerfiles from the orchestator
* Ignore Dockerfiles in the git repo
* Remove CI job to check Dockerfiles are as expected now that they're no longer committed
* Remove old Dockerfiles from repo
* Use Debian for monero-wallet-rpc
* Remove replace_cmds for proper usage of entry-dev
Consolidates ports a bit.
Updates serai-docker-tests from "compose" to "build".
* Only write a new dockerfile if it's distinct
Preserves the updated time metadata.
* Update serai-docker-tests
* Correct the path Dockerfiles are built from
* Correct inclusion of orchestration folder in Docker builds
* Correct debug/release flagging in the cargo command
Apparently, --debug isn't an effective NOP yet an error.
* Correct path used to run the Serai node within a Dockerfile
* Correct path in Monero Dockerfile
* Attempt storing monerod in /usr/bin
* Use sudo to move into /usr/bin in CI
* Correct 18.3.0 to 18.3.1
* Escape * with quotes
* Update deny.toml, ADD orchestration in runtime Dockerfile
* Add --detach to the Monero GH CI
* Diversify dockerfiles by network
* Fixes to network-diversified orchestration
* Bitcoin and Monero testnet scripts
* Permissions and tweaks
* Flatten scripts folders
* Add missing folder specification to Monero Dockerfile
* Have monero-wallet-rpc specify the monerod login
* Have the Docker CMD specify env variables inserted at time of Dockerfile generation
They're overrideable with the global enviornment as for tests. This enables
variable generation in orchestrator and output to productionized Docker files
without creating a life-long file within the Docker container.
* Don't add Dockerfiles into Docker containers now that they have secrets
Solely add the source code for them as needed to satisfy the workspace bounds.
* Download arm64 Monero on arm64
* Ensure constant host architecture when reproducibly building the wasm
Host architecture, for some reason, can effect the generated code despite the
target architecture always being foreign to the host architecture.
* Randomly generate infrastructure keys
* Have orchestrator generate a key, be able to create/start containers
* Ensure bash is used over sh
* Clean dated docs
* Change how quoting occurs
* Standardize to sh
* Have Docker test build the dev Dockerfiles
* Only key_gen once
* cargo update
Adds a patch for zstd and reconciles the breaking nightly change which just
occurred.
* Use a dedicated network for Serai
Also fixes SERAI_HOSTNAME passed to coordinator.
* Support providing a key over the env for the Serai node
* Enable and document running daemons for tests via serai-orchestrator
Has running containers under the dev network port forward the RPC ports.
* Use volumes for bitcoin/monero
* Use bitcoin's run.sh in GH CI
* Only use the volume for testnet (not dev)
* Remove unused brew packages on macOS
* Remove reference to Docker in macOS CI
* Remove gems, explicitly test Intel and m1 macOS
* Allow gem to error since it still mostly runs
* complete various todos
* fix pr comments
* Document bounds on unique hashes in TransactionKind
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Specifically use bash as a shell to try and get rustup to work on Windows
* Use bash for the call to echo
* Add macOS clippy
* Debug why git diff failed
* Restore macos-latest to matrix
* Allow whitespace before the fact 0 lines were modified
* Add LC_ALL env variable to grep
* Replace usage of -P with -e
* Add windows clippy
* Adjust build-dependencies for Linux/Windows
* Specifically use bash as a shell to try and get rustup to work on Windows
* Use bash for the call to echo
* report_slashes plumbing in Substrate
Notably delays the SetRetired event until it provides a slash report or the set
after it becomes the set to report its slashes.
* Add dedicated AcceptedHandover event
* Add SlashReport TX to Tributary
* Create SlashReport TXs
* Handle SlashReport TXs
* Add logic to generate a SlashReport to the coordinator
* Route SlashReportSigner into the processor
* Finish routing the SlashReport signing/TX publication
* Add serai feature to processor's serai-client
* create Dockerfile for monero wallet rpc with dockerfiles.sh
* make monero wallet rpc docker accessible from outside
* connect wallet-rpc with monerod
* add generated Dockerfile for monero wallet rpc
* add monero wallet rpcs to docker profiles
* update getting started guide to refer to wallet rpc docker
Pseudo-resolves shlex advisory (due to the deprecation of the vulnerable
functions, which hopefully should prevent their use). shlex is only used by
bindgen, a sufficiently trusted dependency.
Not only is this more performant, the definition of retired won't be if a newer
session is active. It will be if the session has posted a slash report or the
stake for that session has unlocked.
Initial commit towards implementing SlashReports.
The behavior appears to match monero core. monero core isn't
throwing an exception in the linked code, it's returning
boost::none (and logging an error) which is the same functional
behavior as finding that the output does not belong to the user.
* Use only the first input ring length for all RCT input signatures.
This is what Monero does:
ac02af9286/src/ringct/rctTypes.h (L422)https://github.com/monero-project/monero/blob/master/src/cryptonote_basic/cryptonote_basic.h#L308-L309
This isn't an issue for current transactions as from hf 12 Monero requires
all inputs to have the same number of decoys but for transactions before
that Monero would reject RCT txs with differing ring lengths. Monero would
deserialize each inputs signature using the ring length of the first so the
signatures for inputs other than the first would have a different
(wrong) number of elements for that input meaning the signature is invalid.
But as we are using the ring length of each input, which arguably is the
*correct* way, we would approve of transactions with inputs differing in
ring lengths.
* Check that there is more than one ring member for MLSAG signatures.
ac02af9286/src/ringct/rctSigs.cpp (L462)
* monero: require seed lang when decoding seed
- Require the seed language when decoding a Classic|Polyseed seed string
- As per https://github.com/monero-project/monero/issues/9089 and https://github.com/tevador/polyseed/issues/11
- Fixes#478
- Implementation note: I reused the `SeedType` enum and required it as a param to `Seed::from_string` because it seemed simplest, but perhaps there is a cleaner way to require the seed lang.
- Made sure the print statements from #487 print the seed as early as possible to help debug future issues
- A future PR could support deducing which languages a seed decodes to in order to support the UX @kayabaNerve suggested in https://github.com/monero-project/monero/issues/9089:
- "Wallets can also try to abstract [language specification], by decoding with all languages, and only asking the user if/when multiple valid options show up ("Is this seed Spanish or Italian?")."
* Lint
* Use an extended timeout for DKGs specifically
* Add a log statement when message-queue connection fails
* Add a 60 second keep-alive to connections
* Use zalloc for processor/message-queue/coordinator
An additional layer which protects us against edge cases with Zeroizing
(objects which don't support it or don't miss it).
* Add further logs to message-queue
* Further increase re-attempt timeouts in CI
* Remove misplaced continue inmessage-queue client
Fixes observed CI failures.
* Revert "Further increase re-attempt timeouts in CI"
This reverts commit 3723530cf6.
The rational is detailed in the root Cargo.toml.
While I don't personally mind MPL dependencies, even if I don't prefer them
(they're allowed in the deny.toml for a reason), I do mind the pointless scope
creep and wish to highlight how little it actually used from the crate by
re-defining it as the single function.
We could also fork directories-next, or directories, and remove the usage of
option-ext per https://github.com/dirs-dev/dirs-sys-rs/issues/24, yet that'd be
a much larger task than what was done here.
In the future, it may be beneficial to submit a PR to wasmtime replacing
directories-next with home, a cargo-team maintained library to get the home
directory and associated folders. An example migration can be found at
https://github.com/harryfei/which-rs/pull/80.
* Route validators for any active set through sc-authority-discovery
Additionally adds an RPC route to retrieve their P2P addresses.
* Have the coordinator get peers from substrate
* Have the RPC return one address, not up to 3
Prevents the coordinator from believing it has 3 peers when it has one.
* Add missing feature to serai-client
* Correct network argument in serai-client for p2p_validators call
* Add a test in serai-client to check DHT population with a much quicker failure than the coordinator tests
* Update to latest Substrate
Removes distinguishing BABE/AuthorityDiscovery keys which causes
sc_authority_discovery to populate as desired.
* Update to a properly tagged substrate commit
* Add all dialed to peers to GossipSub
* cargo fmt
* Reduce common code in serai-coordinator-tests with amore involved new_test
* Use a recursive async function to spawn `n` DockerTests with the necessary networking configuration
* Merge UNIQUE_ID and ONE_AT_A_TIME
* Tidy up the new recursive code in tests/coordinator
* Use a Mutex in CONTEXT to let it be set multiple times
* Make complimentary edits to full-stack tests
* Augment coordinator P2p connection logs
* Drop lock acquisitions before recursing
* Better scope lock acquisitions in full-stack, preventing a deadlock
* Ensure OUTER_OPS is reset across the test boundary
* Add cargo deny allowance for dockertest fork
Slight downscope which helps combat the antipattern which is the futures glob
crate. While futures_util is still a large crate, it has better defaults and
is smaller by virtue of not pulling the executor.
Makes RemoveParticipantDueToDkg a voted-on event instead of a Provided.
This removes the requirement for offline parties to be able to fully validate
blame, yet unfortunately lets an dishonest supermajority have an honest node
label any arbitrary node as dishonest.
Corrects a variety of `.i(...)` calls which panicked when they shouldn't have.
Cleans up a couple no-longer-used storage values.
* implement general design
* add slashing
* bug fixes
* fix pr comments
* misc fixes
* fix grandpa abi call type
* Correct rebase artifacts I introduced
* Cleanups and corrections
1) Uses vec![] for the OpaqueKeyProof as there's no value to passing it around
2) Remove usage of Babe/Grandpa Offences for tracking if an offence is known
for checking if can slash. If can slash, no prior offence must have been
known.
3) Rename DisabledIndices to SeraiDisabledIndices, drop historical data for
current session only.
4) Doesn't remove from the pre-declared upcoming Serai set upon slash due to
breaking light clients.
5) Into/From instead of AsRef for KeyOwnerProofSystem's generic to ensure
safety of the conversion.
* Correct deduction from TotalAllocatedStake on slash
It should only be done if in set and only with allocations contributing to
TotalAllocatedStake (Allocation + latest session's PendingDeallocation).
* Changes meant for prior commit
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
With a DKG removal comes a reduction in the amount of participants which was
ignored by re-attempts.
Now, we determine n/i based on the parties removed, and deterministically
obtain the context of who was removd.
* Schedule re-attempts and add a (not filled out) match statement to actually execute them
A comment explains the methodology. To copy it here:
"""
This is because we *always* re-attempt any protocol which had participation. That doesn't
mean we *should* re-attempt this protocol.
The alternatives were:
1) Note on-chain we completed a protocol, halting re-attempts upon 34%.
2) Vote on-chain to re-attempt a protocol.
This schema doesn't have any additional messages upon the success case (whereas
alternative #1 does) and doesn't have overhead (as alternative #2 does, sending votes and
then preprocesses. This only sends preprocesses).
"""
Any signing protocol which reaches sufficient participation will be
re-attempted until it no longer does.
* Have the Substrate scanner track DKG removals/completions for the Tributary code
* Don't keep trying to publish a participant removal if we've already set keys
* Pad out the re-attempt match a bit more
* Have CosignEvaluator reload from the DB
* Correctly schedule cosign re-attempts
* Actuall spawn new DKG removal attempts
* Use u32 for Batch ID in SubstrateSignableId, finish Batch re-attempt routing
The batch ID was an opaque [u8; 5] which also included the network, yet that's
redundant and unhelpful.
* Clarify a pair of TODOs in the coordinator
* Remove old TODO
* Final comment cleanup
* Correct usage of TARGET_BLOCK_TIME in reattempt scheduler
It's in ms and I assumed it was in s.
* Have coordinator tests drop BatchReattempts which aren't relevant yet may exist
* Bug fix and pointless oddity removal
We scheduled a re-attempt upon receiving 2/3rds of preprocesses and upon
receiving 2/3rds of shares, so any signing protocol could cause two re-attempts
(not one more).
The coordinator tests randomly generated the Batch ID since it was prior an
opaque byte array. While that didn't break the test, it was pointless and did
make the already-succeeded check before re-attempting impossible to hit.
* Add log statements, correct dead-lock in coordinator tests
* Increase pessimistic timeout on recv_message to compensate for tighter best-case timeouts
* Further bump timeout by a minute
AFAICT, GH failed by just a few seconds.
This also is worst-case in a single instance, making it fine to be decently long.
* Further further bump timeout due to lack of distinct error
* Move logic for evaluating if a cosign should occur to its own file
Cleans it up and makes it more robust.
* Have expected_next_batch return an error instead of retrying
While convenient to offer an error-free implementation, it potentially caused
very long lived lock acquisitions in handle_processor_message.
* Unify and clean DkgConfirmer and DkgRemoval
Does so via adding a new file for the common code, SigningProtocol.
Modifies from_cache to return the preprocess with the machine, as there's no
reason not to. Also removes an unused Result around the type.
Clarifies the security around deterministic nonces, removing them for
saved-to-disk cached preprocesses. The cached preprocesses are encrypted as the
DB is not a proper secret store.
Moves arguments always present in the protocol from function arguments into the
struct itself.
Removes the horribly ugly code in DkgRemoval, fixing multiple issues present
with it which would cause it to fail on use.
* Set SeraiBlockNumber in cosign.rs as it's used by the cosigning protocol
* Remove unnecessary Clone from lambdas in coordinator
* Remove the EventDb from Tributary scanner
We used per-Transaction DB TXNs so on error, we don't have to rescan the entire
block yet only the rest of it. We prevented scanning multiple transactions by
tracking which we already had.
This is over-engineered and not worth it.
* Implement borsh for HasEvents, removing the manual encoding
* Merge DkgConfirmer and DkgRemoval into signing_protocol.rs
Fixes a bug in DkgConfirmer which would cause it to improperly handle indexes
if any validator had multiple key shares.
* Strictly type DataSpecification's Label
* Correct threshold_i_map_to_keys_and_musig_i_map
It didn't include the participant's own index and accordingly was offset.
* Create TributaryBlockHandler
This struct contains all variables prior passed to handle_block and stops them
from being passed around again and again.
This also ensures fatal_slash is only called while handling a block, as needed
as it expects to operate under perfect consensus.
* Inline accumulate, store confirmation nonces with shares
Inlining accumulate makes sense due to the amount of data accumulate needed to
be passed.
Storing confirmation nonces with shares ensures that both are available or
neither. Prior, one could be yet the other may not have been (requiring an
assert in runtime to ensure we didn't bungle it somehow).
* Create helper functions for handling DkgRemoval/SubstrateSign/Sign Tributary TXs
* Move Label into SignData
All of our transactions which use SignData end up with the same common usage
pattern for Label, justifying this.
Removes 3 transactions, explicitly de-duplicating their handlers.
* Remove CurrentlyCompletingKeyPair for the non-contextual DkgKeyPair
* Remove the manual read/write for TributarySpec for borsh
This struct doesn't have any optimizations booned by the manual impl. Using
borsh reduces our scope.
* Use temporary variables to further minimize LoC in tributary handler
* Remove usage of tuples for non-trivial Tributary transactions
* Remove serde from dkg
serde could be used to deserialize intenrally inconsistent objects which could
lead to panics or faults.
The BorshDeserialize derives have been replaced with a manual implementation
which won't produce inconsistent objects.
* Abstract Future generics using new trait definitions in coordinator
* Move published_signed_transaction to tributary/mod.rs to reduce the size of main.rs
* Split coordinator/src/tributary/mod.rs into spec.rs and transaction.rs
Event retrieval was prior:
- Retrieve all events in the block, which may be hundreds of KB
- Filter to just a few
Since it's frequent to want multiple sets of events, each filtered in their own
way, this caused the retrieval to happen multiple times. Now, it only will
happen once.
Also has the scoped clients take a reference, not an owned TemporalSerai.
* Make it clear not providing a change address is fingerprintable
When no change address is provided, all change is shunted to the
fee. This PR makes it clear to the caller that it is fingerprintable
when the caller does this.
* Review comments
* chore: implement create_db for substrate (fix broken branch)
* Correct rebase artifacts
* chore: remove todo statement
* chore: rename BlockDb to NextBlock
* chore: return empty tuple instead of empty array for event storage
* Finish rebasing
* .Minor tweaks to remove leftover variables
These may be rebase artifacts.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* coordinator/src/db.rs db macro implimentation
* fixed fmt errors
* converted txn functions to get/set counterparts
* use take_signed_transaction function
* fix for two fo the tests
* Misc tweaks
* Minor tweaks
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Uses a full-fledged serai-abi to do so.
Removes use of UncheckedExtrinsic as a pointlessly (for us) length-prefixed
block with a more complicated signing algorithm than advantageous.
In the future, we should considering consolidating the various primitives
crates. I'm not convinced we benefit from one primitives crate per pallet.
Call and Event are both from the pallets, which are AGPL licensed. Accordingly,
they make serai-client AGPL licensed when serai-client must end up MIT
licensed. This creates a MIT-licensed variant of Calls and Events such that
they can be used by serai-client, enabling transitioning it to MIT.
Relevant to https://github.com/serai-dex/serai/issues/337.
Updates off a yanked version of zerocopy, fixing the failing deny CI.
Bites the bullet on windows-sys 0.52. While I was hoping to update everything
at once, unfortunately tokio won't update until March (see
https://github.com/tokio-rs/mio/pull/1725). I don't want to withold these
updates for that long.
They're a bit more binding, smaller, provided by the Rust bitcoin library,
sane, and we don't have to worry about malleability since all of our inputs are
SegWit.
The test failures were caused by not inserting any price, causing the first
price to immediately become the oraclized price. While that's not inherently
invalid, suggesting the tests should've been the ones updated, it opens an
exploit where whoever first adds liquidity has the opportunity to set a
ridiculous price and DoS the set. Not oraclizing until we have an entire
period, achieved by inserting 0s during the initial blocks, ensures an open
launch for such discovery.
There's an exploit where the prior set improperly mints coins, the new set
occurs (resetting the oracle), and they immediately deallocate 49.9% of their
coins (which is more than enough to achieve profitability).
Now, anyone in set must wait until after the next set completes to perform any
deallocation, enabling time to halt upon improper mints.
* Update ValidatorSets with a remove_participant call
* Add DkgRemoval, a sign machine for producing the relevant MuSig signatures
* Don't use position-dependent u8s yet Public when removing validators from the DKG
* Add DkgRemovalPreprocess, DkgRemovalShares
Implementation is via a new publish_tributary_tx lambda.
This is code is a copy-pasted mess which will need to be cleaned up.
* Only allow non-removed validators to vote for removals
Otherwise, it's risked that the remaining validators fall below 67% of the
original set.
* Correct publish_serai_tx, which was prior publish_set_keys in practice
This mirrors how Provided TXs handle topics.
Now, instead of managing a global nonce stream, we can use items such as plan
IDs as topics.
This massively benefits re-attempts, as else we'd need a NOP TX to clear unused
nonces.
* Use redb and in Dockerfiles
The motivation for redb was to remove the multiple rocksdb compile times from
CI.
* Correct feature flagging of coordinator and message-queue in Dockerfiles
* Correct message-queue DB type alias
* Use consistent table typing in redb
* Correct rebase artifacts
* Correct removal of binaries feature from message-queue
* Correct processor feature flagging
* Replace redb with parity-db
It still has much better compile times yet doesn't block when creating multiple
transactions. It also is actively maintained and doesn't grow our tree. The MPT
aspects are irrelevant.
* Correct stray Redb
* clippy warning
* Correct txn get
* Use debug builds in our Dockerfiles to reduce CI times
Also enables only spawning the mdns service when debug in the coordinator.
* Correct underflow in processor
Prior undetected due to relase builds not having bounds checks enabled.
* Restore Serai release due to CI/RPC failures caused by compiling it in debug mode
This is *probably* worth an issue filed upstream, if it can be tracked down.
* Correct failing debug asserts in Monero
These debug asserts assumed there was a change address to take the remainder.
If there's no change address, the remainder is shunted to the fee, causing the
fee to be distinct from the estimate.
We presumably need to modify monero-serai such that change: None isn't valid,
and users must use Change::Fingerprintable(None).
* Remove subxt
Removes ~20 crates from our Cargo.lock.
Removes downloading the metadata and enables removing the getMetadata RPC route
(relevant to #379).
Moves forward #337.
Done now due to distinctions in the subxt 0.32 API surface which make it
justifiable to not update.
* fmt, update due to deny triggering on a yanked crate
* Correct the handling of substrate_block_notifier now that it's ephemeral, not long-lived
* Correct URL in tests/coordinator from ws to http
* Remove NetworkId from processor-messages
Because intent binds to the sender/receiver, it's not needed for intent.
The processor knows what the network is.
The coordinator knows which to use because it's sending this message to the
processor for that network.
Also removes the unused zeroize.
* ProcessorMessage::Completed use Session instead of key
* Move SubstrateSignId to Session
* Finish replacing key with session
* Move message-queue to a fully binary representation
Additionally adds a timeout to the message queue test.
* coordinator clippy
* Remove contention for the message-queue socket by using per-request sockets
* clippy
For some reason, these constantly failed for me while waiting for the key pair
to confirm. This adds a sleep during the mining process, to ensure blocks
actually have time between them, and mines several more blocks to handle the
median code recently added.
Monero doesn't assert the time increases with each block, solely that it
doesn't decrease. Now, the block number is added to the time to ensure it
increases.
processor isn't intended to be used as a library, yet serai-processor-tests
does pull it in as a lib. This caused serai-processor-tests to need to compile
rocksdb, which added multiple minutes to the compilation time.
* Add SignalsConfig to chain_spec
* Correct multiexp feature flagging for rand_core std
* Remove bincode for borsh
Replaces a non-canonical encoding with a canonical encoding which additionally
should be faster.
Also fixes an issue where we used bincode in transcripts where it cannot be
trusted.
This ended up fixing a myriad of other bugs observed, unfortunately.
Accordingly, it either has to be merged or the bug fixes from it must be ported
to a new PR.
* Make serde optional, minimize usage
* Make borsh an optional dependency of substrate/ crates
* Remove unused dependencies
* Use [u8; 64] where possible in the processor messages
* Correct borsh feature flagging
Relevant to #394.
Prevents hand-over due to hand-over occurring via a `Batch` publication.
Expects a new protocol to restore functionality (after a retirement of the
current protocol).
* implement db macro for processor/substrate_signer
* Use ()
* Correct AttemptDb usage of ()
* () -> &()
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Remove dtolnay's rust-toolchain action
I believe our rust-toolchain.toml handles its use case exactly.
I don't believe this'll work, as it'd require rustup install a cargo stub
before any toolchain is installed, yet I want to confirm it doesn't.
* Place quotes around nightly toolchain version
* Put toolchain before options to resolve what appears to be a bug in rustup's help strings
* Add wasm32-unkknown-unknown to clippy workflow
Adds a Rust toolchain file to be less disruptive to developers who don't keep
their toolchain synchronized (by now having rustup automatically synchronize).
Hopefully helps resolve how +nightly clippy may pass for the coordinator, yet
building would fail due to stable's (hopefully prior?) failure to model some
async functions re: Send/Sync.
Also adds rust-src as a component in preparation of
https://github.com/paritytech/polkadot-sdk/pull/2217
The coordinator already had one of these, albeit implemented much worse than
the one now properly introduced. It had to either be sending or receiving,
whereas the new one can do both at the same time.
This replaces said instance and enables pleasant patterns when implementing the
processor/coordinator.
They were already banned form publishing `Batch`s, yet the ability to set keys
enabled changing how certain functionality in the coordinator operated.
Removing this malleability ensures operation as expected.
* Add a function to deterministically decide which Serai blocks should be co-signed
Has a 5 minute latency between co-signs, also used as the maximal latency
before a co-sign is started.
* Get all active tributaries we're in at a specific block
* Add and route CosignSubstrateBlock, a new provided TX
* Split queued cosigns per network
* Rename BatchSignId to SubstrateSignId
* Add SubstrateSignableId, a meta-type for either Batch or Block, and modularize around it
* Handle the CosignSubstrateBlock provided TX
* Revert substrate_signer.rs to develop (and patch to still work)
Due to SubstrateSigner moving when the prior multisig closes, yet cosigning
occurring with the most recent key, a single SubstrateSigner can be reused.
We could manage multiple SubstrateSigners, yet considering the much lower
specifications for cosigning, I'd rather treat it distinctly.
* Route cosigning through the processor
* Add note to rename SubstrateSigner post-PR
I don't want to do so now in order to preserve the diff's clarity.
* Implement cosign evaluation into the coordinator
* Get tests to compile
* Bug fixes, mark blocks without cosigners available as cosigned
* Correct the ID Batch preprocesses are saved under, add log statements
* Create a dedicated function to handle cosigns
* Correct the flow around Batch verification/queueing
Verifying `Batch`s could stall when a `Batch` was signed before its
predecessors/before the block it's contained in was cosigned (the latter being
inevitable as we can't sign a block containing a signed batch before signing
the batch).
Now, Batch verification happens on a distinct async task in order to not block
the handling of processor messages. This task is the sole caller of verify in
order to ensure last_verified_batch isn't unexpectedly mutated.
When the processor message handler needs to access it, or needs to queue a
Batch, it associates the DB TXN with a lock preventing the other task from
doing so.
This lock, as currently implemented, is a poor and inefficient design. It
should be modified to the pattern used for cosign management. Additionally, a
new primitive of a DB-backed channel may be immensely valuable.
Fixes a standing potential deadlock and a deadlock introduced with the
cosigning protocol.
* Working full-stack tests
After the last commit, this only required extending a timeout.
* Replace "co-sign" with "cosign" to make finding text easier
* Update the coordinator tests to support cosigning
* Inline prior_batch calculation to prevent panic on rotation
Noticed when doing a final review of the branch.
Resolves#391.
Given this code already wasn't modular/composable, this should be overall
equivalent regarding functionality and security. It's much less opinionated
though and has fewer dependencies.
Closes https://github.com/serai-dex/serai/issues/342.
Under ideal network conditions, this is fine. While I won't claim ideal network
conditions will occur IRL, b0fcdd3367 has the
Tributary rebroadcast messages and should brute-force its way into a
functioning system.
* De-duplicate Dockerfiles by using a bash file to concatenate common parts
Resolves#375.
Dockerfiles are still committed to the repo to avoid a dependency on bash.
* Add a CI job to confirm the committed dockerfiles are the currently generated ones
* Create dedicated Dockerfiles per processor network
Ensures the compromising of network-specific dependencies doesn't lead to a
compromise of the build process for all processors.
* Dockerfile corrections
* Correct call to build processor Docker image in tests/processor
* chore: convert nonce_deicer to use create_db macro
* Restore pub NonceDecider
* Remove extraneous comma
I forgot to run git commit --amend on the prior commit :/
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Add v1 ring sig verifying
* allow calculating signature hash for v1 txs
* add unreduced scalar type with recovery
I have added this type for borromen sigs, the ee field can be a normal
scalar as in the verify function the ee
field is checked against a reduced scalar mean for it to verify as
correct ee must be reduced
* change block major/ minor versions to u8
this matches Monero
I have also changed a couple varint functions to accept the `VarInt`
trait
* expose `serialize_hashable` on `Block`
* add back MLSAG verifying functions
I still need to revert the commit removing support for >1 input MLSAG FULL
This adds a new rct type to separate Full and simple rct
* add back support for multiple inputs for RCT FULL
* comment `non_adjacent_form` function
also added `#[allow(clippy::needless_range_loop)]` around a loop as without a re-write satisfying clippy without it will make the function worse.
* Improve Mlsag verifying API
* fix rebase errors
* revert the changes on `reserialize_chain`
plus other misc changes
* fix no-std
* Reduce the amount of rpc calls needed for `get_block_by_number`.
This function was causing me problems, every now and then a node would return a block with a different number than requested.
* change `serialize_hashable` to give the POW hashing blob.
Monero calculates the POW hash and the block hash using *slightly* different blobs :/
* make ring_signatures public and add length check when verifying.
* Misc improvements and bug fixes
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Have processor report errors during the DKG to the coordinator
* Add RemoveParticipant, InvalidDkgShare to coordinator
* Route DKG blame around coordinator
* Allow public construction of AdditionalBlameMachine
Necessary for upcoming work on handling DKG blame in the processor and
coordinator.
Additionally fixes a publicly reachable panic when commitments parsed with one
ThresholdParams are used in a machine using another set of ThresholdParams.
Renames InvalidProofOfKnowledge to InvalidCommitments.
* Remove unused error from dleq
* Implement support for VerifyBlame in the processor
* Have coordinator send the processor share message relevant to Blame
* Remove desync between processors reporting InvalidShare and ones reporting GeneratedKeyPair
* Route blame on sign between processor and coordinator
Doesn't yet act on it in coordinator.
* Move txn usage as needed for stable Rust to build
* Correct InvalidDkgShare serialization
If a user transferred in without an InInstruction, and the amount exactly
matched a forwarded output, the user's output would fulfill the
forwarding. Then the forwarded output would come along, have no InInstruction,
and be refunded (to the prior multisig) when the user should've been refunded.
Adding this new address type resolves such concerns.
The higher-level scanner code in multisigs/mod.rs now creates a series of plans
with limited context. These include forwarding and refunding plans, moving all
handling of forwarding flags on the scanner's clock and therefore safe.
Also simplifies the refunding a decent bit.
This code is still largely designed around the idea a payment for a network is
fungible with any other, which isn't true. This starts moving past that.
Asserts are added to ensure the integrity of coin to the scheduler (which is
now per key per coin, not per key alone) and in Bitcoin/Monero prepare_send.
ethers-solc was used for a type (now manually specified) and to call out to
solc. Since Foundry was already a documented dependency, a call to it now
handles building.
Removing this single crate removes a total of 17 crates from our dependency
tree. While these may still be around due to Foundry, they at least may not
be.
Further work to remove the requirement on Foundry for solc alone would be
appreciated.
Not currently used, notably increases our dependency tree.
I wouldn't remove it if we planned to use it. From my understanding, all
benchmarking will be per pallet, voiding our need to have this for the node.
I don't like blindly retrying in the Monero library. The amount of errors,
which weren't present with reqwest (well, the error rate was the same, yet due
to a distinct bug this code fixed), demand we do *something* though.
The trace log shows hyper is erroring with 0 bytes of the response read. My
guess is it's somehow a closed connection? A connection pool would detect this
and have created a new connection (as this does, except once finding out
there's an issue).
While we should be able to detect this with `ready()`, we do call ready and it
claims no error. We also can successfully write which makes this... a mess.
Hopefully, it either actually works as intended, yet it at least requires two
consecutive errors which should be much less frequent.
The prior system spawned a new connection per request to enable parallelism,
yet kept hitting hyper::IncompleteMessages I couldn't track down. This
attempts to resolve those by a long-lived socket.
Halves the amount of requests per-authenticated RPC call, and accordingly is
likely still better overall.
I don't believe this is resolved yet but this is still worth pushing.
reqwest was replaced with hyper and hyper-rustls within monero-serai due to
reqwest *solely* offering a connection pool API. In the process, it was
demonstrated how quickly we can achieve equivalent functionality to reqwest for
our use cases with a fraction of the code.
This adds our own reqwest alternative to the tree, applying it to both
bitcoin-serai and message-queue. By doing so, bitcoin-serai decreases its tree
by 21 packages and the processor by 18. Cargo.lock decreases by 8 dependencies,
solely adding simple-request. Notably removed is openssl-sys and openssl.
One noted decrease functionality is the requirement on the system having
installed CA certificates. While we could fallback to the rustls certificates
if the system doesn't have any, that's blocked by
https://github.com/rustls/hyper-rustls/pulls/228.
Removes bitcoin-serai's usage of sha2 for bitcoin-hashes. While sha2 is still
in play due to modular-frost (more specifically, due to ciphersuite), this
offers a bit more performance (assuming equivalency between sha2 and
bitcoin-hashes' impl) due to removing a static for a const.
Makes secp256k1 a dev dependency for bitcoin-serai. While secp256k1 is still
pulled in via bitcoin, it's hopefully slightly better to compile now and makes
usage of secp256k1 an implementation detail of bitcoin (letting it change it
freely).
Also offers slightly more efficient signing as we don't decode to a signature
just to re-encode for the transaction.
Removes a 20s sleep for a check every second, up to 20 times, for reduced test
times in the processor.
* Move pallet-asset-conversion
* update licensing
* initial integration
* Integrate Currency & Assets types
* integrate liquidity tokens
* fmt
* integrate dex pallet tests
* fmt
* compilation error fixes
* integrate dex benchmarks
* fmt
* cargo clippy
* replace all occurrences of "asset" with "coin"
* add the actual add liq/swap logic to in-instructions
* add client side & tests
* fix deny
* Lint and changes
- Renames InInstruction::AddLiquidity to InInstruction::SwapAndAddLiquidity
- Makes create_pool an internal function
- Makes dex-pallet exclusively create pools against a native coin
- Removes various fees
- Adds new crates to GH workflow
* Fix rebase artifacts
* Correct other rebase artifact
* Correct CI specification for liquidity-tokens
* Correct primitives' test to the standardized pallet account scheme
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* db_macro
* wip: converted prcessor/key_gen to use create_db macro
* wip: converted prcessor/key_gen to use create_db macro
* wip: formatting
* fix: added no_run to doc
* fix: documentation example had extra parenths
* fix: ignore doc test entirely
* Corrections from rebasing
* Misc lint
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* add reasons to slash evidence
* fix CI failing
* Remove unnecessary clones
.encode() takes &self
* InvalidVr to InvalidValidRound
* Unrelated to this PR: Clarify reasoning/potentials behind dropping evidence
* Clarify prevotes in SlashEvidence test
* Replace use of read_to_end
* Restore decode_signed_message
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
It *looks like* hyper will drop the connection once its request sender is
dropped, regardless of if the last request hasn't had its response completed.
This attempts to resolve some spurious connection errors.
* Update the coordinator to give key shares based on weight, not based on existence
Participants are now identified by their starting index. While this compiles,
the following is unimplemented:
1) A conversion for DKG `i` values. It assumes the threshold `i` values used
will be identical for the MuSig signature used to confirm the DKG.
2) Expansion from compressed values to full values before forwarding to the
processor.
* Add a fn to the DkgConfirmer to convert `i` values as needed
Also removes TODOs regarding Serai ensuring validator key uniqueness +
validity. The current infra achieves both.
* Have the Tributary DB track participation by shares, not by count
* Prevent a node from obtaining 34% of the maximum amount of key shares
This is actually mainly intended to set a bound on message sizes in the
coordinator. Message sizes are amplified by the amount of key shares held, so
setting an upper bound on said amount lets it determine constants. While that
upper bound could be 150, that'd be unreasonable and increase the potential for
DoS attacks.
* Correct the mechanism to detect if sufficient accumulation has occured
It used to check if the latest accumulation hit the required threshold. Now,
accumulations may jump past the required threshold. The required mechanism is
to check the threshold wasn't prior met and is now met.
* Finish updating the coordinator to handle a multiple key share per validator environment
* Adjust stategy re: preventing noce reuse in DKG Confirmer
* Add TODOs regarding dropped transactions, add possible TODO fix
* Update tests/coordinator
This doesn't add new multi-key-share tests, it solely updates the existing
single key-share tests to compile and run, with the necessary fixes to the
coordinator.
* Update processor key_gen to handle generating multiple key shares at once
* Update SubstrateSigner
* Update signer, clippy
* Update processor tests
* Update processor docker tests
If a crate has std set, it should enable std for all dependencies in order to
let them properly select which algorithms to use. Some crates fallback to
slower/worse algorithms on no-std.
Also more aggressively sets default-features = false leading to a *10%*
reduction in the amount of crates coordinator builds.
Even though the intent was to test against 0.17.3.2, and a Monero 0.17.3.2 node
was running, the processor now uses docker which will always use 0.18.
Accordingly, while the intent was valid, it was pointless.
This is unfortunate, as testing against 0.17 helped protect against edge cases.
The infra to preserve their tests isn't worth the benefit we'd gain from said
tests however.
The lack of locking the connection when making an authenticated request, which
is actually two sequential requests, risked another caller making a request in
between, invalidating the state.
Now, only unauthenticated connections share a connection object.
Disables the unused zmq RPC.
Removes authentication which seems to be unstable as hell when under load
(see #351).
No longer use Network::Isolated as it's not needed here (the Monero nodes run
with `--offline`).
* Updates to modern dockertest
* More updates to latest dockertest
* Update Cargo.lock to dockertest with handle restored
* clippy coordinator tests
* clippy full-stack tests
* Remove kayabaNerve branch for official repo's latest commit hash
* Update serai-client, remove reliance on the existence of a handle fn
* Don't use the hex encoding of unique_id in dockertests
Gets our hostnames just below 64 bytes, resolving test failures on at least
Debian-based systems.
* Use Network::Isolated for all dockertest instances
* Correct error from prior commit's edits
Also halves the minimum fee policy, which still may be 2x-4x higher than
necessary due to API limitations within bitcoin-serai (which we can fix as it's
within our scope).
Resolves#353
Implements code such that:
- 80% of validators (by stake) must be in favor of a signal for the network to
be
- 80% of networks (by stake) must be in favor of a signal for it to be locked
in
- After a signal has been locked in for two weeks, the network halts
The intention is to:
1) Not allow validators to unilaterally declare new consensus rules.
No method of declaring new consensus rules is provided by this pallet. Solely a
way to deprecate the current rules, with a signaled for successor. All nodes
must then individually decide whether or not to download and run a new node
which has new rules, and if so, which rules.
2) Not place blobs on chain.
Even if they'd be reproducible, it's just a lot of data to chuck on the
blockchain.
Monero would select decoys with a new RNG seed, which may have used more bytes,
increasing the fee.
There's a few comments here.
1) Non-determinism wasn't removed via distinguishing the edits. It was done by
removing part of the transcript. A TODO exists to improve this.
2) Distinct TX fees is a test failure, not an issue in prod *unless* the distinct
fee is greater. So long as the distinct fee is lesser, it's fine.
3) Removing outputs is expected to only decrease fees.
The existing code should've mostly handled this fine. Only a single edge case
(TX fee reduction on no-change Plans) would cause an improper increase in
operating costs.
* initial implementation
* add function to get a balance of an account
* add support for multiple coins
* rename pallet to "coins-pallet"
* replace balances, assets and tokens pallet with coins pallet in runtime
* add total supply info
* update client side for new Coins pallet
* handle fees
* bug fixes
* Update FeeAccount test
* Fmt
* fix pr comments
* remove extraneous Imbalance type
* Minor tweaks
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Implements most of #297 to the point I'm fine closing it. The solution
implemented is distinct than originally designed, yet much simpler.
Since we have a fully-linear view of created transactions, we don't have to
per-output track operating costs incurred by that output. We can track it
across the entire Serai system, without hooking into the Eventuality system.
Also updates documentation.
Replaces plan IDs with key + ID, letting the coordinator determine the sessions
for the plans.
Properly scopes which plan IDs are set on which tributaries, and ensures we
have the necessary tributaries at time of handling.
Adds Event::SetRetired to validator-sets.
Emit TributaryRetired.
Replaces is_active_set, which made multiple network requests, with
is_retired_tributary, a DB read.
Performs most of the removals necessary upon TributaryRetired.
Still needs to clean up the actual Tributary/Tendermint tasks.
The tests have recently had their timing stilted, causing failures. The tests
are... fine. They're fragile, as obvious, yet they're logical. The simplest fix
is to unstilt their timing rather to make them non-fragile.
The recent change, which presumably caused said stilting, was the the
rebroadcasting added. This de-duplication prevents most of the impact of
rebroadcasting. While there's still the async task, and the lock acquisition on
attempt to rebroadcast, this hopefully is enough.
* fix typos
* remove tributary sleeping
* handle not locally provided txs
* use topic number instead of waiting list
* Clean-up, fixes
1) Uses a single TXN in provided
2) Doesn't continue on non-local provided inside verify_block, skipping further
execution of checks
3) Upon local provision of already on-chain TX, compares
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Revert "Correct the prior documented TOCTOU"
This reverts commit d50fe87801.
* Correct the prior documented TOCTOU
d50fe87801 edited the challenge for the Batch to
fix it. This won't produce Batch n+1 until Batch n is successfully published
and verified. It's an alternative strategy able to be reviewed, with a much
smaller impact to scope.
Now, if a malicious validator set publishes a malicious `Batch` at the last
moment, it'll cause all future `Batch`s signed by the next validator set to
require a bool being set (yet they never will set it).
This will prevent the handover.
The only overhead is having two distinct `batch_message` calls on-chain.
The new set publishing a `Batch` completes the handover protocol. The new set
should only publish a `Batch` once it believes the old set has completed all of
its on-external-chain activity, marking it honest and finite.
With the handover comes the acceptance of liability, hence the requirement for
all of the on-Serai-chain activity also needing verification. While most
activity would be verified in-real-time (upon ::Batch messages), the new set
will now explicitly verify the complete set of `Batch`s before beginning its
preprocess for its own `Batch` (the one accepting the handover).
pre_dispatch is guaranteed by documentation to be called and persisted.
validate_unsigned is not, though the provided pre_dispatch does by default call
validate_unsigned. By explicitly providing our own pre_dispatch, we accomplish
the bounds we require and expect, only being invalidated on Substrate
redefining their API.
We should still test this, yet since we call retire_session in
validate_unsigned, any test of rotation will test it's being properly called.
Sets a stake requirement of 100k for Serai and Monero, as Serai doesn't have
stake requirements and Monero isn't expected to see as much
volume/institutional support as Bitcoin/Ethereum.
The reproducible runtime test failed due to running out of space. If we have
multiple tests failing due to out of space, and all of our tests have these
unused, it makes sense just to always so uninstall.
Also extends the time limit of reproducible-runtime, as 2h has been hit a few
times before.
They assumed processor 0 had keys `i = 1`. Under the new validator-set code,
the first key is the one with the highest amount, In case of tie, the key (or
as of the last commit, a Blake hash) decides order.
This commit kludges in a mapping from processor index to assigned key index, no
longer assuming its value.
We took with `amount`, not `prior`, allowing multiple presences in
SortedAllocations.
While spam is limited by the amount of nibbles in the amount, the key provides
a much larger space to abuse. Inserting a cryptographic hash prevents its use
for abuse.
* initial staking pallet
* add staking pallet to runtime
* support session rotation for serai
* optimizations & cleaning
* fix deny
* add serai network to initial networks
* a few tweaks & comments
* fix some pr comments
* Rewrite validator-sets with logarithmic algorithms
Uses the fact the underlying DB is sorted to achieve sorting of potential
validators by stake.
Removes release of deallocated stake for now.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Renames Update to SignedBatch.
Checks Batch equality via a hash of the InInstructions. That prevents needing
to keep the Batch in node state or TX introspect.
key used to be empty. As part of implementing support for multisig rotation
into the coordinator, it was easiest to set the key to the substrate key. While
the coordinator and full stack tests were updated, the processor tests weren't.
This does that.
Prior, we only supported a single Tributary per network, and spawned a task to
handled Processor messages per Tributary. Now, we handle Processor messages per
network, yet we still only supported a single Tributary in that handling
function.
Now, when we handle a message, we load the Tributary which is relevant. Once we
know it, we ensure we have it (preventing race conditions), and then proceed.
We do need work to check if we should have a Tributary, or if we're not
participating. We also need to check if a Tributary has been retired, meaning
we shouldn't handle any transactions related to them, and to clean up retired
Tributaries.
This is a possibility under the new deterministic nonce scheme.
While there is a concern of us never creating a transaction with a nonce,
blocking everything, we should always create transactions. We'll always publish
preprocesses, and while we'll only publish shares if everyone else does, we
only allocate for shares once everyone else does.
This isn't an unacceptable timeout. It matches a prior timeout. I'm unsure why
it's now needed to be extended though. My best guess is the test runtime is
single threaded and there's now new overhead in the task management (or perhaps
higher latency now that messages per-tributary is serialized).
* Design and document a multisig rotation flow
* Make Scanner::eventualities a HashMap so it's per-key
* Don't drop eventualities, always follow through on them
Technical improvements made along the way.
* Start creating an isolate object to manage multisigs, which doesn't require being a signer
Removes key from SubstrateBlock.
* Move Scanner/Scheduler under multisigs
* Move Batch construction into MultisigManager
* Clarify "should" in Multisig Rotation docs
* Add block_number to MultisigManager, as it controls the scanner
* Move sign_plans into MultisigManager
Removes ThresholdKeys from prepare_send.
* Make SubstrateMutable an alias for MultisigManager
* Rewrite Multisig Rotation
The prior scheme had an exploit possible where funds were sent to the old
multisig, then burnt on Serai to send from the new multisig, locking liquidity
for 6 hours. While a fee could be applied to stragglers, to make this attack
unprofitable, the newly described scheme avoids all this.
* Add mini
mini is a miniature version of Serai, emphasizing Serai's nature as a
collection of independent clocks. The intended use is to identify race
conditions and prove protocols are comprehensive regarding when certain clocks
tick.
This uses loom, a prior candidate for evaluating the processor/coordinator as
free of race conditions (#361).
* Use mini to prove a race condition in the current multisig rotation docs, and prove safety of alternatives
Technically, the prior commit had mini prove the race condition.
The docs currently say the activation block of the new multisig is the block
after the next Batch's. If the two next Batches had already entered the
mempool, prior to set_keys being called, the second next Batch would be
expected to contain the new key's data yet fail to as the key wasn't public
when the Batch was actually created.
The naive solution is to create a Batch, publish it, wait until it's included,
and only then scan the next block. This sets a bound of
`Batch publication time < block time`. Optimistically, we can publish a Batch
in 24s while our shortest block time is 2m. Accordingly, we should be fine with
the naive solution which doesn't take advantage of throughput. #333 may
significantly change latency however and require an algorithm whose throughput
exceeds the rate of blocks created.
In order to re-introduce parallelization, enabling throughput, we need to
define a safe range of blocks to scan without Serai ordering the first one.
mini demonstrates safety of scanning n blocks Serai hasn't acknowledged, so
long as the first is scanned before block n+1 is (shifting the n-block window).
The docs will be updated next, to reflect this.
* Fix Multisig Rotation
I believe this is finally good enough to be final.
1) Fixes the race condition present in the prior document, as demonstrated by
mini.
`Batch`s for block `n` and `n+1`, may have been in the mempool when a
multisig's activation block was set to `n`. This would cause a potentially
distinct `Batch` for `n+1`, despite `n+1` already having a signed `Batch`.
2) Tightens when UIs should use the new multisig to prevent eclipse attacks,
and protection against `Batch` publication delays.
3) Removes liquidity fragmentation by tightening flow/handling of latency.
4) Several clarifications and documentation of reasoning.
5) Correction of "prior multisig" to "all prior multisigs" regarding historical
verification, with explanation why.
* Clarify terminology in mini
Synchronizes it from my original thoughts on potential schema to the design
actually created.
* Remove most of processor's README for a reference to docs/processor
This does drop some misc commentary, though none too beneficial. The section on
scanning, deemed sufficiently beneficial, has been moved to a document and
expanded on.
* Update scanner TODOs in line with new docs
* Correct documentation on Bitcoin::Block::time, and Block::time
* Make the scanner in MultisigManager no longer public
* Always send ConfirmKeyPair, regardless of if in-set
* Cargo.lock changes from a prior commit
* Add a policy document on defining a Canonical Chain
I accidentally committed a version of this with a few headers earlier, and this
is a proper version.
* Competent MultisigManager::new
* Update processor's comments
* Add mini to copied files
* Re-organize Scanner per multisig rotation document
* Add RUST_LOG trace targets to e2e tests
* Have the scanner wait once it gets too far ahead
Also bug fixes.
* Add activation blocks to the scanner
* Split received outputs into existing/new in MultisigManager
* Select the proper scheduler
* Schedule multisig activation as detailed in documentation
* Have the Coordinator assert if multiple `Batch`s occur within a block
While the processor used to have ack_up_to_block, enabling skips in the block
acked, support for this was removed while reworking it for multiple multisigs.
It should happen extremely infrequently.
While it would still be beneficial to have, if multiple `Batch`s could occur
within a block (with the complexity here not being worth adding that ban as a
policy), multiple `Batch`s were blocked for DoS reasons.
* Schedule payments to the proper multisig
* Correct >= to <
* Use the new multisig's key for change on schedule
* Don't report External TXs to prior multisig once deprecated
* Forward from the old multisig to the new one at all opportunities
* Move unfulfilled payments in queue from prior to new multisig
* Create MultisigsDb, splitting it out of MainDb
Drops the call to finish_signing from the Signer. While this will cause endless
re-attempts, the Signer will still consider them completed and drop them,
making this an O(n) cost at boot even if we did nothing from here.
The MultisigManager should call finish_signing once the Scanner completes the
Eventuality.
* Don't check Scanner-emitted completions, trust they are completions
Prevents needing to use async code to mark the completion and creates a
fault-free model. The current model, on fault, would cause a lack of marked
completion in the signer.
* Fix a possible panic in the processor
A shorter-chain reorg could cause this assert to trip. It's fixed by
de-duplicating the data, as the assertion checked consistency. Without the
potential for inconsistency, it's unnecessary.
* Document why an existing TODO isn't valid
* Change when we drop payments for being to the change address
The earlier timing prevents creating Plans solely to the branch address,
causing the payments to be dropped, and the TX to become an effective
aggregation TX.
* Extensively document solutions to Eventualities being potentially created after having already scanned their resolutions
* When closing, drop External/Branch outputs which don't cause progress
* Properly decide if Change outputs should be forward or not when closing
This completes all code needed to make the old multisig have a finite lifetime.
* Commentary on forwarding schemes
* Provide a 1 block window, with liquidity fragmentation risks, due to latency
On Bitcoin, this will be 10 minutes for the relevant Batch to be confirmed. On
Monero, 2 minutes. On Ethereum, ~6 minutes.
Also updates the Multisig Rotation document with the new forwarding plan.
* Implement transaction forwarding from old multisig to new multisig
Identifies a fault where Branch outputs which shouldn't be dropped may be, if
another output fulfills their next step. Locking Branch fulfillment down to
only Branch outputs is not done in this commit, but will be in the next.
* Only let Branch outputs fulfill branches
* Update TODOs
* Move the location of handling signer events to avoid a race condition
* Avoid a deadlock by using a RwLock on a single txn instead of two txns
* Move Batch ID out of the Scanner
* Increase from one block of latency on new keys activation to two
For Monero, this offered just two minutes when our latency to publish a Batch
is around a minute already. This does increase the time our liquidity can be
fragmented by up to 20 minutes (Bitcoin), yet it's a stupid attack only
possible once a week (when we rotate). Prioritizing normal users' transactions
not being subject to forwarding is more important here.
Ideally, we'd not do +2 blocks yet plus `time`, such as +10 minutes, making
this agnostic of the underlying network's block scheduling. This is a
complexity not worth it.
* Split MultisigManager::substrate_block into multiple functions
* Further tweaks to substrate_block
* Acquire a lock on all Scanner operations after calling ack_block
Gives time to call register_eventuality and initiate signing.
* Merge sign_plans into substrate_block
Also ensure the Scanner's lock isn't prematurely released.
* Use a HashMap to pass to-be-forwarded instructions, not the DB
* Successfully determine in ClosingExisting
* Move from 2 blocks of latency when rotating to 10 minutes
Superior as noted in 6d07af92ce10cfd74c17eb3400368b0150eb36d7, now trivial to
implement thanks to prior commit.
* Add note justifying measuring time in blocks when rotating
* Implement delaying of outputs received early to the new multisig per specification
* Documentation on why Branch outputs don't have the race condition concerns Change do
Also ensures 6 hours is at least N::CONFIRMATIONS, for sanity purposes.
* Remove TODO re: sanity checking Eventualities
We sanity check the Plan the Eventuality is derived from, and the Eventuality
is handled moments later (in the same file, with a clear call path). There's no
reason to add such APIs to Eventualities for a sanity check given that.
* Add TODO(now) for TODOs which must be done in this branch
Also deprecates a pair of TODOs to TODO2, and accepts the flow of the Signer
having the Eventuality.
* Correct errors in potential/future flow descriptions
* Accept having a single Plan Vec
Per the following code consuming it, there's no benefit to bifurcating it by
key.
* Only issue sign_transaction on boot for the proper signer
* Only set keys when participating in their construction
* Misc progress
Only send SubstrateBlockAck when we have a signer, as it's only used to tell
the Tributary of what Plans are being signed in response to this block.
Only immediately sets substrate_signer if session is 0.
On boot, doesn't panic if we don't have an active key (as we wouldn't if only
joining the next multisig). Continues.
* Correctly detect and set retirement block
Modifies the retirement block from first block meeting requirements to block
CONFIRMATIONS after.
Adds an ack flow to the Scanner's Confirmed event and Block event to accomplish
this, which may deadlock at this time (will be fixed shortly).
Removes an invalid await (after a point declared unsafe to use await) from
MultisigsManager::next_event.
* Remove deadlock in multisig_completed and document alternative
The alternative is simpler, albeit less efficient. There's no reason to adopt
it now, yet perhaps if it benefits modeling?
* Handle the final step of retirement, dropping the old key and setting new to existing
* Remove TODO about emitting a Block on every step
If we emit on NewAsChange, we lose the purpose of the NewAsChange period.
The only concern is if we reach ClosingExisting, and nothing has happened, then
all coins will still be in the old multisig until something finally does. This
isn't a problem worth solving, as it's latency under exceptional dead time.
* Add TODO about potentially not emitting a Block event for the reitrement block
* Restore accidentally deleted CI file
* Pair of slight tweaks
* Add missing if statement
* Disable an assertion when testing
One of the test flows currently abuses the Scanner in a way triggering it.
Eventualities need to be binding not just to a plan, yet to the execution of
the plan (the outputs). Bitcoin's Eventuality definition short-cutted this
under a honest multisig assumption, causing the following issue:
If multisig n+1 is verifying multisig n's actions, as detailed in
multi-multisig's document on multisig rotation, it'll check no outstanding
eventualities exist. If we solely bind to the plan, a malicious multisig n
could steal outbound payments yet cause the plan to be marked as successfully
completed.
By modifying the eventuality to also include the expected outputs, this is no
longer possible. Binding to the expected input is preserved in order to remain
binding to the plan (allowing two plans with the same output-set to co-exist).
It was a piece of duplicated data used to achieve context-less
de)serialization. This new Vec code is a bit tricker to first read, yet overall
clean and removes a potential fault.
Saves 2 bytes from DkgShares messages.
See prior commit message for more info.
With the plan for the batch sign ID to be just 5 bytes (potentially 4), this
does incur a +5 bytes cost compared to the ExternalBlock system *even in the
standard case*. The simplicity remains preferred at this time.
The initial TODO was simply to use one ExternalBlock per all batches in the
block. This would require publishing ExternalBlock after the last batch,
requiring knowing the last batch. While we could add such a pipeline, it'd
require:
1) Initial preprocesses using a distinct message from BatchPreprocess
2) An additional message sent after all BatchPreprocess are sent
Unfortunately, both would require tweaks to the SubstrateSigner which aren't
worth the complexity compared to the solution here, at least, not at this time.
While this will cause, if a Tributary is signing a block whose total batch data
exceeds 25 kB, to use multiple transactions which could be optimized out by
'better' local data pipelining, that's an extreme edge case. Given the temporal
nature of each Tributary, it's also an acceptable edge.
This does no longer achieve synchrony over external blocks accordingly. While
signed batches have synchrony, as they embed their block hash, batches being
signed don't have cryptographic synchrony on their contents. This means
validators who are eclipsed may produce invalid shares, as they sign a
different batch. This will be introduced in a follow-up commit.
Updates Tributary values to allow 999ms for block processing (from 2s) and
1667ms for latency (up from 1s).
The intent is to resolve#365. I don't know if this will, but it increases the
chances of success and these values should be fine in prod since Tributary is a
post-execution chain (making block procesisng time minimal).
Does embed the dagger of N::block_time() panicking if the block time in ms
doesn't cleanly divide by 1000.
Fixes where ram_scanned is updated in processor. The prior version, while safe,
would redo massive amounts of work during periods of inactivity. It also hit an
undocumented invariant where get_eventuality_completions assumes new blocks,
yet redone work wouldn't have new blocks.
Modifies Monero's generate_blocks to return the hashes of the generated blocks.
We only expect processor messages when we have the relevant Tributary. We
queued Tributary creation, yet then kicked off processor messages. We need to
wait until the Tributary is actually created to kick off processor messages.
* Add in an implementation of BP+ based off the paper, intended for clarity and review
This was done as part of my work on FCMPs from Monero, and is copied from https://github.com/kayabaNerve/full-chain-membership-proofs
* Remove crate structure of BP+
* Remove arithmetic circuit code
* Remove AC/VC generators code
* Remove generator transcript
Monero uses non-transcripted static generators.
* Further trimming of generators
* Remove the single range proof
It's unused by Monero and accordingly unhelpful.
* Work on getting BP+ to compile in its new env
* Correct BP+ folder name
* Further tweaks to get closer to compiling
* Remove the ScalarMatrix file
It's only used for AC proofs
* Compiles, with tests passing
* Lock BP+ to Ed25519 instead of the generic Ciphersuite
* Resolve most warnings in BP+
* Make existing bulletproofs test easier to read
* Further strip generators
* Swap G/H as Monero did
* Replace RangeCommitment with Commitment
* Hard-code BP+ h to Ed25519's generator
* Use pub(crate) for BP+, not pub
* Replace initial_transcript with hash_plus
* Rename hash_plus to initial_transcript
* Finish integrating the FCMP BP+ impl
* Move BP+ folder
* Correct no-std support
* Rename "long_n" to eta
* Add note on non-prime order dfg points
Prior to the previous commit, whatever async scheduling occurred caused them to
all have the same tip. Now, some are one block ahead of others. This adds
tolerance for that, as it's an acceptable variance, so long as it's solely one
block.
They used &mut self to prevent execution at the same time. This uses a lock
over the channel to achieve the same security, without requiring a lock over
the entire tributary.
This fixes post-provided Provided transactions. sync_block waited for the TX to
be provided, yet it never would as sync_block held a mutable reference over the
entire Tributary, preventing any other read/write operations of any scope.
A timeout increased (bc2f23f72b) due to this bug
not being identified has been decreased back, thankfully.
Also shims in basic support for Completed, which was the WIP before this bug
was identified.
This should be egregious unless the GitHub CI is so inperformant it's breaking
Tendermint consensus's synchrony expectations, which likely points to our own
code being unviable.
This solely serves as an immediate fix to the problem, not a justification of
the unevaluated performance.
Putting a signer first doesn't work because signers can only publish once a
supermajority sync. Now, the code uses an excluded signer (instead of an
included signer) to determine signing set.
Further simplifications are available. Also adds accurate documentation on
latency/sleep reasoning.
Adds 17 new crates, which I'm extremely unhappy about. Unfortunately, it's
needed to resolve a security issue (RUSTSEC-2023-0052) and is inevitable.
Closes#355.
A commit made while testing moved them from network-key-indexed to
Substrate-key-indexed. Since Substrate keys have a fixed-length, fitting within
the Copy boundary, there's no reason for it to not use an array.
1) Updates to time 0.3.27, which allows modern serde_derive's (post binary
fiasco)
2) Updates rustls-webpki to a version not affected by RUSTSEC-2023-0053
3) Updates wasmtime to 12
(d5923df083)
One update replaces one package with another.
The Substrate pulls get ed25519-zebra (still in tree) to dalek 4.0. While noise
still pulls in 3.2, for now, this does let us drop one crate.
Arguably not meaningful, as it adds the scanner yet not the RPC, and no signing
code since modular-frost doesn't support no-std yet. It's a step in the right
direction though.
Only recently (I believe the most recent HF) were output keys checked to be
valid. This means returned keys may be invalid points, despite being the
legitimate keys for the specified outputs.
Does still label the node as invalid if it doesn't return 32 bytes,
hex-encoded.
The Heartbeat was meant to serve for this, yet no Heartbeats are fired when we
don't have active tributaries.
libp2p does offer an explicit KeepAlive protocol, yet it's not recommended in
prod. While this likely has the same pit falls as LibP2p's KeepAlive protocol,
it's at least tailored to our timing.
* dalek 4.0
* cargo update
Moves to a version of Substrate which uses curve25519-dalek 4.0 (not a rc).
Doesn't yet update the repo to curve25519-dalek 4.0 (as a branch does) due
to the official schnorrkel using a conflicting curve25519-dalek. This would
prevent installation of frost-schnorrkel without a patch.
* use half-aggregation for tm messages
* fmt
* fix pr comments
* cargo update
Achieves three notable updates.
1) Resolves RUSTSEC-2022-0093 by updating libp2p-identity.
2) Removes 3 old rand crates via updating ed25519-dalek (a dependency of
libp2p-identity).
3) Sets serde_derive to 1.0.171 via updating to time 0.3.26 which pins at up to
1.0.171.
The last one is the most important. The former two are niceties.
serde_derive, since 1.0.171, ships a non-reproducible binary blob in what's a
complete compromise of supply chain security. This is done in order to reduce
compile times, yet also for the maintainer of serde (dtolnay) to leverage
serde's position as the 8th most downloaded crate to attempt to force changes
to the Rust build pipeline.
While dtolnay's contributions to Rust are respectable, being behind syn, quote,
and proc-macro2 (the top three crates by downloads), along with thiserror,
anyhow, async-trait, and more (I believe also being part of the Rust project),
they have unfortunately decided to refuse to listen to the community on this
issue (or even engage with counter-commentary). Given their political agenda
they seem to try to be accomplishing with force, I'd go as far as to call their
actions terroristic (as they're using the threat of the binary blob as
justification for cargo to ship 'proper' support for binary blobs).
This is arguably representative of dtolnay's past work on watt. watt was a wasm
interpreter to execute a pre-compiled proc macro. This would save the compile
time of proc macros, yet sandbox it so a full binary did not have to be run.
Unfortunately, watt (while decreasing compile times) fails to be a valid
solution to supply chain security (without massive ecosystem changes). It never
implemented reproducible builds for its wasm blobs, and a malicious wasm blob
could still fundamentally compromise a project. The only solution for an end
user to achieve a secure pipeline would be to locally build the project,
verifying the blob aligns, yet doing so would negate all advantages of the
blob.
dtolnay also seems to be giving up their role as a FOSS maintainer given that
serde no longer works in several environments. While FOSS maintainers are not
required to never implement breaking changes, the version number is still 1.0.
While FOSS maintainers are not required to follow semver, releasing a very
notable breaking change *without a new version number* in an ecosystem which
*does follow semver*, then refusing to acknowledge bugs as bugs with their work
does meet my personal definition of "not actively maintaining their existing
work". Maintenance would be to fix bugs, not introduce and ignore.
For now, serde > 1.0.171 has been banned. In the future, we may host a fork
without the blobs (yet with the patches). It may be necessary to ban all of
dtolnay's maintained crates, if they continue to force their agenda as such,
yet I hope this may be resolved within the next week or so.
Sources:
https://github.com/serde-rs/serde/issues/2538 - Binary blob discussion
This includes several reports of various workflows being broken.
https://github.com/serde-rs/serde/issues/2538#issuecomment-1682519944
dtolnay commenting that security should be resolved via Rust toolchain edits,
not via their own work being secure. This is why I say they're trying to
leverage serde in a political game.
https://github.com/serde-rs/serde/issues/2526 - Usage via git broken
dtolnay explicitly asks the submitting user if they'd be willing to advocate
for changes to Rust rather than actually fix the issue they created. This is
further political arm wrestling.
https://github.com/serde-rs/serde/issues/2530 - Usage via Bazel broken
https://github.com/serde-rs/serde/issues/2575 - Unverifiable binary blob
https://github.com/dtolnay/watt - dtolnay's prior work on precompilation
* add Rs() api to SchnorrAggregate
* Correct serai-processor-tests to dalek 4
* fmt + deny
* Slash malevolent validators (#294)
* add slash tx
* ignore unsigned tx replays
* verify that provided evidence is valid
* fix clippy + fmt
* move application tx handling to another module
* partially handle the tendermint txs
* fix pr comments
* support unsigned app txs
* add slash target to the votes
* enforce provided, unsigned, signed tx ordering within a block
* bug fixes
* add unit test for tendermint txs
* bug fixes
* update tests for tendermint txs
* add tx ordering test
* tidy up tx ordering test
* cargo +nightly fmt
* Misc fixes from rebasing
* Finish resolving clippy
* Remove sha3 from tendermint-machine
* Resolve a DoS in SlashEvidence's read
Also moves Evidence from Vec<Message> to (Message, Option<Message>). That
should meet all requirements while being a bit safer.
* Make lazy_static a dev-depend for tributary
* Various small tweaks
One use of sort was inefficient, sorting unsigned || signed when unsigned was
already properly sorted. Given how the unsigned TXs were given a nonce of 0, an
unstable sort may swap places with an unsigned TX and a signed TX with a nonce
of 0 (leading to a faulty block).
The extra protection added here sorts signed, then concats.
* Fix Tributary tests I broke, start review on tendermint/tx.rs
* Finish reviewing everything outside tests and empty_signature
* Remove empty_signature
empty_signature led to corrupted local state histories. Unfortunately, the API
is only sane with a signature.
We now use the actual signature, which risks creating a signature over a
malicious message if we have ever have an invariant producing malicious
messages. Prior, we only signed the message after the local machine confirmed
it was okay per the local view of consensus.
This is tolerated/preferred over a corrupt state history since production of
such messages is already an invariant. TODOs are added to make handling of this
theoretical invariant further robust.
* Remove async_sequential for tokio::test
There was no competition for resources forcing them to be run sequentially.
* Modify block order test to be statistically significant without multiple runs
* Clean tests
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Add DSTs to Tributary TX sig_hash functions
Prevents conflicts with other systems/other parts of the Tributary.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* add slash tx
* ignore unsigned tx replays
* verify that provided evidence is valid
* fix clippy + fmt
* move application tx handling to another module
* partially handle the tendermint txs
* fix pr comments
* support unsigned app txs
* add slash target to the votes
* enforce provided, unsigned, signed tx ordering within a block
* bug fixes
* add unit test for tendermint txs
* bug fixes
* update tests for tendermint txs
* add tx ordering test
* tidy up tx ordering test
* cargo +nightly fmt
* Misc fixes from rebasing
* Finish resolving clippy
* Remove sha3 from tendermint-machine
* Resolve a DoS in SlashEvidence's read
Also moves Evidence from Vec<Message> to (Message, Option<Message>). That
should meet all requirements while being a bit safer.
* Make lazy_static a dev-depend for tributary
* Various small tweaks
One use of sort was inefficient, sorting unsigned || signed when unsigned was
already properly sorted. Given how the unsigned TXs were given a nonce of 0, an
unstable sort may swap places with an unsigned TX and a signed TX with a nonce
of 0 (leading to a faulty block).
The extra protection added here sorts signed, then concats.
* Fix Tributary tests I broke, start review on tendermint/tx.rs
* Finish reviewing everything outside tests and empty_signature
* Remove empty_signature
empty_signature led to corrupted local state histories. Unfortunately, the API
is only sane with a signature.
We now use the actual signature, which risks creating a signature over a
malicious message if we have ever have an invariant producing malicious
messages. Prior, we only signed the message after the local machine confirmed
it was okay per the local view of consensus.
This is tolerated/preferred over a corrupt state history since production of
such messages is already an invariant. TODOs are added to make handling of this
theoretical invariant further robust.
* Remove async_sequential for tokio::test
There was no competition for resources forcing them to be run sequentially.
* Modify block order test to be statistically significant without multiple runs
* Clean tests
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Achieves three notable updates.
1) Resolves RUSTSEC-2022-0093 by updating libp2p-identity.
2) Removes 3 old rand crates via updating ed25519-dalek (a dependency of
libp2p-identity).
3) Sets serde_derive to 1.0.171 via updating to time 0.3.26 which pins at up to
1.0.171.
The last one is the most important. The former two are niceties.
serde_derive, since 1.0.171, ships a non-reproducible binary blob in what's a
complete compromise of supply chain security. This is done in order to reduce
compile times, yet also for the maintainer of serde (dtolnay) to leverage
serde's position as the 8th most downloaded crate to attempt to force changes
to the Rust build pipeline.
While dtolnay's contributions to Rust are respectable, being behind syn, quote,
and proc-macro2 (the top three crates by downloads), along with thiserror,
anyhow, async-trait, and more (I believe also being part of the Rust project),
they have unfortunately decided to refuse to listen to the community on this
issue (or even engage with counter-commentary). Given their political agenda
they seem to try to be accomplishing with force, I'd go as far as to call their
actions terroristic (as they're using the threat of the binary blob as
justification for cargo to ship 'proper' support for binary blobs).
This is arguably representative of dtolnay's past work on watt. watt was a wasm
interpreter to execute a pre-compiled proc macro. This would save the compile
time of proc macros, yet sandbox it so a full binary did not have to be run.
Unfortunately, watt (while decreasing compile times) fails to be a valid
solution to supply chain security (without massive ecosystem changes). It never
implemented reproducible builds for its wasm blobs, and a malicious wasm blob
could still fundamentally compromise a project. The only solution for an end
user to achieve a secure pipeline would be to locally build the project,
verifying the blob aligns, yet doing so would negate all advantages of the
blob.
dtolnay also seems to be giving up their role as a FOSS maintainer given that
serde no longer works in several environments. While FOSS maintainers are not
required to never implement breaking changes, the version number is still 1.0.
While FOSS maintainers are not required to follow semver, releasing a very
notable breaking change *without a new version number* in an ecosystem which
*does follow semver*, then refusing to acknowledge bugs as bugs with their work
does meet my personal definition of "not actively maintaining their existing
work". Maintenance would be to fix bugs, not introduce and ignore.
For now, serde > 1.0.171 has been banned. In the future, we may host a fork
without the blobs (yet with the patches). It may be necessary to ban all of
dtolnay's maintained crates, if they continue to force their agenda as such,
yet I hope this may be resolved within the next week or so.
Sources:
https://github.com/serde-rs/serde/issues/2538 - Binary blob discussion
This includes several reports of various workflows being broken.
https://github.com/serde-rs/serde/issues/2538#issuecomment-1682519944
dtolnay commenting that security should be resolved via Rust toolchain edits,
not via their own work being secure. This is why I say they're trying to
leverage serde in a political game.
https://github.com/serde-rs/serde/issues/2526 - Usage via git broken
dtolnay explicitly asks the submitting user if they'd be willing to advocate
for changes to Rust rather than actually fix the issue they created. This is
further political arm wrestling.
https://github.com/serde-rs/serde/issues/2530 - Usage via Bazel broken
https://github.com/serde-rs/serde/issues/2575 - Unverifiable binary blob
https://github.com/dtolnay/watt - dtolnay's prior work on precompilation
Moves to a version of Substrate which uses curve25519-dalek 4.0 (not a rc).
Doesn't yet update the repo to curve25519-dalek 4.0 (as a branch does) due
to the official schnorrkel using a conflicting curve25519-dalek. This would
prevent installation of frost-schnorrkel without a patch.
* restrict batch size to ~25kb
* add batch size check to node
* rate limit batches to 1 per serai block
* add support for multiple batches for block
* fix review comments
* Misc fixes
Doesn't yet update tests/processor until data flow is inspected.
* Move the block from SignId to ProcessorMessage::BatchPreprocesses
* Misc clean up
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
For logging purposes, I added code to handle negative time till start. I forgot
to only sleep on positive time till start.
Should fix the recent CI failure.
It was improperly implemented, as it assumed rounds had a constant time
interval, which they do not. It also is against the spec and was meant to
absolve us of issues with poor performance when post-starting blockchains. The
new, and much more proper, workaround for the latter is a 120-second delay
between the Substrate time and the Tributary start time.
By default, tokio-spawned worker panics will only kill the task, not the
program. Due to our extensive use of panicking on invariants, we should ensure
the program exits.
It's largely unoptimized, and not yet exclusive to validators, yet has basic
sanity (using message content for ID instead of sender + index).
Fixes bugs as found. Notably, we used a time in milliseconds where the
Tributary expected seconds.
Also has Tributary::new jump to the presumed round number. This reduces slashes
when starting new chains (whose times will be before the current time) and was
the only way I was able to observe successful confirmations given current
surrounding infrastructure.
Allows running `cargo build` in monero-serai and message-queue without
erroring, since it'd automatically try to build the binaries which require
additional features.
While we could make those features not optional, it'd increase time to build
and disk space required, which is why the features exist for monero-serai and
message-queue in the first place (since both are frequently used as libs).
This will effectively add msrv protections to the entire project as almost
everything grabs from these.
Doesn't add msrv to coins as coins/bitcoin is still frozen.
Doesn't add msrv to services since cargo msrv doesn't play nice with anything
importing the runtime.
The Processor's coins folder referred to the networks it could process, as did
its Coin trait. This, and other similar cases throughout the codebase, have now
been corrected.
Also corrects dated documentation for a key pair is confirmed under the
validator-sets pallet.
This is a horrible impl which does a full ser of everything on every change.
It's just the minimal changes to resolve this TODO and able testnet deployment.
Due to the ordered message-queue, there's no benefit to multiple emissions as
there's no risk a completion will be missed. If it has yet to be read, sending
another which only be read after isn't helpful.
Simplifies code a decent bit.
This is technically over-agressive, as a dropped output will reduce the fee,
yet this edge case is so minor the flow for it to not be over-aggressive (over
a few fractions of a cent) is by no means worth it.
Fixes the crash causable by the WIP send_test.
Stops work where it does to the processor panickinng for Monero, yet not
Bitcoin, under what's present.
Cleans up processor tests to consolidate shared code.
zstd was recommended for the base layer only, due to its CPU requirements. That
was a misreading on mhy behalf.
lz4 gets ~5% better compression than snappy with ~30% faster performance. zstd
does ~25% better than lz4 yet at ~30% of the performance.
Also moves from bullseye in the processor to bullseye-slim. This requires
adding back the apt intall, yet the tests/docker cache should handle it.
Minimizes processor image surface, hopefully also shrinks the CI down a bit.
It waited for CONFIRMATIONS + 1 confirmations, instead of CONFIRMATIONS
confirmations.
Also adds a lib interface to access the coin traits and its constants.
While I tried Alpine, RocksDB won't build unless it's statically linked. Then
async-trait (and proc-macro's in general) won't compile when statically linked.
All uses were safe due to addresses being converted to script_pubkeys which
don't embed their network. The only risk of there being an issue is if a
future address spec did embed the net ID into the script_pubkey and that was
moved to.
This resolves the audit note and does offer that tightening.
common/ is now only run when common is edited. crypto/ when common/ or crypto/.
coins/ when common/ or crypto/ or coins/. The rest of the tests are run
whenever any package is edited (as they're all inter-connected).
Duee to signature replaying, it's very annoying to provide meanigful data
access privacy. None of these messages should be private/have sensitive data
anyways though.
Due to each service having multiple distinct clocks, we can't expect a stable
ordering except the ordering an intact message-queue provides. The messages
emitted should be consistent however, solely with unknown order, which is why
we can craft intents based on their contents (already implemented by
processor-messages).
* add polyseed support
* fix pr comments
* fix tests
* Embed the mempool into the Blockchain
* Plan scheduled payments whenever outputs are received
The scheduler prior waited for the next series of payments to be added.
* Replace Tendermint step with sync_block
Step moved a step forward after an externally synced/added block. This created
a race condition to add the block between the sync process and the Tendermint
machine. Now that the block routes through Tendermint, there is no such race
condition.
* Finish binding Tendermint into Tributary and define a Tributary master object
* Add correction the last commit missed
* Add DoS limits to tributary and require provided transactions be ordered
* Fix the scheduler from dropping UTXOs when there weren't any payments
* Documentation and cargo update
* Add a dedicated db crate with a basic DB trait
It's needed by the processor and tributary (coordinator).
* Add a DB to Tributary
Adds support for reloading most of the blockchain.
* Reloaded provided transactions from the disk
Also resolves a race condition by asserting provided transactions must be
unique, allowing them to be safely provided multiple times.
* must_use annotations on DbTxn
* Support reloading the mempool from disk
* Add a NewSet event to validator-sets
Updates to the latest serai-dex/substrate due to depending on
10ccaca0eb498a2316bbf627d419b29b1a75933a.
* Add basic getters to tributary
* cargo update
* Update to the latest subxt
Writes a custom unsigned extrinic creator due to subxt having an internal error
with the scale metadata. While the code in our scope increased, it's much more
ergonomic to our usage. We may end up rewriting most of subxt, eventually.
* Make unsigned private due to unsafe calling potential
* Start defining the coordinator
* Merge AckBlock with Burns
Offers greater efficiency while reducing concerns re: atomicity.
* Correct processor flow to have the coordinator decide signing set/re-attempts
The signing set should be the first group to submit preprocesses to Tributary.
Re-attempts shouldn't be once every 30s, yet n blocks since the last relevant
message.
Removes the use of an async task/channel in the signer (and Substrate signer).
Also removes the need to be able to get the time from a coin's block, which was
a fragile system marked with a TODO already.
* cargo +nightly fmt
* cargo update
Since p256 now pulls in an extra crate with this update, the {k,p}256 imports
disable default-features to prevent growing the tree.
* Support extracting timestamps from blocks
* Make progres on handling NewSet events
Further bones out the coordinator.
* Resolve#245
* Have InInstructions track the latest block for a network in storage
* Fill out code for the rest of the Substrate events
* Clean up the Substrate block processing code
* Rename transaction file to tributary, add function for genesis
* Add a processor API to the coordinator
* Add extensive commentary on mutable to the processor's main file
Clearly establishes why consistency is guaranteed from a Rust borrow-checker
mindset. While there are plenty of... 'violations', they're clearly explained.
Hopefully, this method of thinking helps promote/ensure consistency in the
future.
* Move ConfirmKeyPair from key_gen to substrate
Clarifies the emitter and accordingly why its mutations are justified.
* Remove BatchSigned
SubstrateBlock's provision of the most recently acknowledged block has
equivalent information with the same latency. Accordingly, there's no need for
it.
* Add note to processor_messages
* Use a single txn for an entire coordinator message
Removes direct DB accesses whre possible. Documents the safety of the rest.
Does uncover one case of unsafety not previously noted.
* cargo update to remove usage of yanked crate
* Clarify safety of Scanner::block_number and KeyGen::keys
* Tweak ConfirmKeyPair to alleviate database requirements of coordinator
* Use an enum for Coin/NetworkId
It originally wasn't an enum so software which had yet to update before an
integration wouldn't error (as now enums are strictly typed). The strict typing
is preferable though.
* Code a method to determine the activation block before any block has consensus
[0; 32] is a magic for no block has been set yet due to this being the first
key pair. If [0; 32] is the latest finalized block, the processor determines
an activation block based on timestamps.
This doesn't use an Option for ergonomic reasons.
* automate whitespace & trimming test cases
* Save keys by their tweaked group_key
Keys are referred to by their tweaked versions. If a tweak was needed, keys
would fail to confirm.
* Use crypto-bigint's reduction in ed448
Achieves feasible performance in the ed448 which makes it potentially viable
for real world usage.
Accordingly prepares a new release, updating the README.
* Move the entirety of ed448 to Residue, offering a further 2-4x speedup
* Resolve#68
Notably speeds up monero-serai's build and CLSAG performance.
* Make MainDB into SubstrateDB
* Initial Tributary handling
* Add additional checks to key_gen/sign
There is the ability to cause state bloat by flooding Tributary.
KeyGen/Sign specifically shouldn't allow bloat since we check the
commitments/preprocesses/shares for validity. Accordingly, any invalid data
(such as bloat) should be detected.
It was posssible to place bloat after the valid data. Doing so would be
considered a valid KeyGen/Sign message, yet could add up to 50k kB per sign.
* Apply DKG TX handling code to all sign TXs
The existing code was almost entirely applicable. It just needed to be scoped
with an ID. While the handle function is now a bit convoluted, I don't see a
better option.
* Split FinalizedBlock into ExternalBlock and SeraiBlock
Also re-arranges their orders.
* Add support for multiple orderings in Provided
Necessary as our Tributary chains needed to agree when a Serai block has
occurred, and when a Monero block has occurred. Since those could happen at the
same time, some validators may put SeraiBlock before ExternalBlock and vice
versa, causing a chain halt. Now they can have distinct ordering queues.
* Slash on unrecognized ID
* ExternalBlock handler
* Add a SubstrateBlockAck message to the processor
When a Substrate block occurs, the coordinator is expected to emit
SubstrateBlock. This causes the processor to begin a variety of plans. The
processor now emits SubstrateBlockAck, explicitly listing all plan IDs, before
starting signing.
This lets the coordinator provide a SubstrateBlock transaction, and with it,
recognize all plan IDs as valid.
Prior, we would've had to have a spotty algorithm based upon the upcoming
Preprocess messages, or if we immediately provided the SubstrateBlock
transaction, then wait for the processor to inform us of the contained plans.
This creates an explicitly proper async flow not reliant on waiting for data
availability.
Alternatively, we could've replaced Preprocess with (Block, Vec<Preprocess>).
This would've been more efficient, yet also clunky due to the multiple usages
of the Preprocess message.
* Route the SubstrateBlock message, which is the last Tributary transaction type
* Add recent bloat checks added to signer to substrate_signer as well
* Add no_std support to transcript, dalek-ff-group, ed448, ciphersuite, multiexp, schnorr, and monero-generators
transcript, dalek-ff-group, ed449, and ciphersuite are all usable with no_std
alone. The rest additionally require alloc.
Part of #279.
* Add a test to the coordinator for running a Tributary
Impls a LocalP2p for testing.
Moves rebroadcasting into Tendermint, since it's what knows if a message is
fully valid + original.
Removes TributarySpec::validators() HashMap, as its non-determinism caused
different instances to have different round robin schedules. It was already
prior moved to a Vec for this issue, so I'm unsure why this remnant existed.
Also renames the GH no-std workflow from the prior commit.
* Add a test for Tributary
Further fleshes out the Tributary testing code.
* Test handling of DKG commitments transactions
* Add Transaction::sign.
While I don't love the introduction of empty_signed, it's practically fine.
* Tributary test wait_for_tx_inclusion function
* Additionally test DKGShares
* Handle adding new Tributaries
Removes last_block as an argument from Tendermint. It now loads from the DB as
needed. While slightly less performant, it's easiest and should be fine.
* Reload Tributaries
add_active_tributary writes the spec to disk before it returns, so even if the
VecDeque it pushes to isn't popped, the tributary will still be loaded on boot.
* Start handling P2P messages
This defines the tart of a very complex series of locks I'm really unhappy
with. At the same time, there's not immediately a better solution. This also
should work without issue.
* Clarify Arc RwLocks and sleeps in coordinator
* Send a heartbeat message when a Tributary falls behind
* cargo fmt
* cargo update
* Move json word lists to rs
Allows building the seed code without serde_json.
* Break coordinator main into multiple functions
Also moves from std::sync::RwLock to tokio::sync::RwLock to prevent wasting
cycles on spinning.
* Remove reliance on a blockchain read lock from block/commit
* Implement Tributary syncing
Also adds a forwards-lookup to the Tributary blockchain.
* Don't return from sync_block until the Tendermint machine returns if it's valid or not
We had a race condition where'd we be informed of blocks 1 .. 3, and
immediately add 1 .. 3. Because we immediately tried to add 2 after 1, it'd
fail since the tip was still the genesis, yet 2 needs the tip to be 1.
Adding a channel, while ugly, was the simplest way to accomplish this.
Also has any added block be broadcasted. Else there's a race condition where a
node which syncs up to the most recent block does so, yet fails to add the next
block when it's committed to.
* Test handle_p2p and Tributary syncing
Includes bug fixes.
* Tweak tests workflow
* Add a TributaryReader which doesn't require a borrow to operate
Reduces lock contention.
Additionally changes block_key to include the genesis. While not technically
needed, the lack of genesis introduced a side effect where any Tributary on the
the database could return the block of any other Tributary. While that wasn't a
security issue, returning it suggested it was on-chain when it wasn't. This may
have been usable to create issues.
* Document panic in FROST
* Document a pair of panics requiring 256 GB of RAM/4 GB of a context
* Add a UID function to messages
When we receive messages, we're provided with a message ID we can use to
prevent handling an item multiple times. That doesn't prevent us from *sending*
an item multiple times though. Thanks to the UID system, we can now not send if
already present.
Alternatively, we can remove the ordered message ID for just the UID, allowing
duplicates to be sent without issue, and handled on the receiving end.
* Initial code to handle messages from processors
* Document the processor/tributary/coordinator/serai flow
* Have Coordinator MainDb take a mutable borrow
* Update to substrate polkadot-v0.9.42
* Correct error message in ff-group-tests
* Update to May's nightly
Doesn't use the PR due to the needed changes.
* Support arbitrary RPC providers in monero-serai
Sets a clean path for no-std premised RPCs (buffers to an external RPC impl)/
Tor-based RPCs/client-side load balancing/...
* Correct processor's handling of the new Monero RPC code
* Correct Serai Dockerfile
* Publish ExternablBlock/SubstrateBlock, delay *Preprocess until ID acknowledged
Adds a channel for the Tributary scanner to communicate when an ID has been
acknowledged.
* Rename uid to intent
* Use U448 for Ed448 instead of U512
* Spawn a new async task for each block message
This probably should be done with n-long lived tasks, one per Tributary. While
this may not be suitably performant long-term (potential DoS vector), this at
least resolves the halting concerns.
* Move the coordinator to a n-processor design
* Ensure Tributary commits are minimal
* Properly get genesis for a Processor message
* Create a vote transaction upon GeneratedKeyPair
* Remove TODO about code de-duplication
It's infeasible to write a macro/function there. Does add a type alias which
makes things cleaner.
* Have coordinator publish batches to Substrate
* Implement MuSig key aggregation into DKG
Isn't spec compliant due to the lack of a spec to be compliant too.
Slight deviation from the paper by using a unique list instead of a multiset.
Closes#186, progresses #277.
* Correct 2/3rds definitions throughout the codebase
The prior formula failed for some values, such as 20.
20 / 3 = 6, * 2 = 12, + 1 = 13. 13 is 65%, not >= 67.
* cargo update
Resolves a yanked crate and removes some duplicated dependencies.
* Add a dedicated function to get a MuSig key
* Do the minimal amount of work for dkg to compile under no-std
The Substrate runtime requires access to the MuSig key aggregation function.
\#279 related.
* Use a MuSig signature to publish validator set key pairs to Serai
The processor/coordinator flow still has to be rewritten.
* Correct various no_std definitions
* Add a context to MuSig key aggregation
* Use proper messages for ValidatorSets/InInstructions pallet
Provides a DST, and associated metadata as beneficial.
Also utilizes MuSig's context to session-bind. Since set_keys_messages also
binds to set, this is semi-redundant, yet that's appreciated.
* Remove signed Substrate TXs from Coordinator
* Only scan v2 Monero TXs
* Fix for prior commit
* Ensure canonical points in the cross-group DLEq proof
* Fix incorrect sig_hash generation
sig_hash was used as a challenge. challenges should be of the form H(R, A, m).
These sig hashes were solely H(A, m), allowing trivial forgeries.
* cargo update
Resolves an openssl advisory and nets ~-8 crates.
* Build no-std tests with RISC-V 32 IMAC
Turns out wasm still has std, making it suboptimal to use here.
* Pin setup-protoc to v2.0.0
* Update to substrate polkadot-v0.9.43
* fix tributary sync test
* Slight terminology correction in sync test
Also correct a mistake from merging the most recent polkadot version.
* Update nightly
* Replace lazy_static with OnceLock inside monero-serai
lazy_static, if no_std environments were used, effectively required always
using spin locks. This resolves the ergonomics of that while adopting Rust std
code.
no_std does still use a spin based solution. Theoretically, we could use
atomics, yet writing our own Mutex wasn't a priority.
* no-std support for monero-serai (#311)
* Move monero-serai from std to std-shims, where possible
* no-std fixes
* Make the HttpRpc its own feature, thiserror only on std
* Drop monero-rs's epee for a homegrown one
We only need it for a single function. While I tried jeffro's, it didn't work
out of the box, had three unimplemented!s, and is no where near viable for
no_std.
Fixes#182, though should be further tested.
* no-std monero-serai
* Allow base58-monero via git
* cargo fmt
* Represent RCT amounts with None, not 0.
Fixes#282.
Does allow any v1 TXs which exist, and v2 miner-TXs, to specify Some(0). As far
as I can tell, both were/are theoreitcally possible.
* Add a message queue
This is intended to be a reliable transport between the processors and
coordinator. Since it'll be intranet only, it's written as never fail.
Primarily needs testing and a proper ID.
* cargo update
Resolves https://github.com/serai-dex/serai/security/dependabot/29
* Correct deny.toml with inclusion of message-queue
* Update nightly
* std-shims: six `Read` for &[u8]
* Use serai- prefixes on Serai-specific packages
Fixes deny.toml, also runs a minor cargo update shrinking the tree.
* Update monero-tests workflow to new name for the processor
* Correct depends for processor-messages
* Disable Rust caching
We hit the cache limit after just one or two builds, making it infeasible.
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
* Monero: support for legacy transactions (#308)
* add mlsag
* fix last commit
* fix miner v1 txs
* fix non-miner v1 txs
* add borromean + fix mlsag
* add block hash calculations
* fix for the jokester that added unreduced scalars
to the borromean signature of
2368d846e671bf79a1f84c6d3af9f0bfe296f043f50cf17ae5e485384a53707b
* Add Borromean range proof verifying functionality
* Add MLSAG verifying functionality
* fmt & clippy :)
* update MLSAG, ss2_elements will always be 2
* Add MgSig proving
* Tidy block.rs
* Tidy Borromean, fix bugs in last commit, replace todo! with unreachable!
* Mark legacy EcdhInfo amount decryption as experimental
* Correct comments
* Write a new impl of the merkle algorithm
This one tries to be understandable.
* Only pull in things only needed for experimental when experimental
* Stop caching the Monero block hash now in processor that we have Block::hash
* Corrections for recent processor commit
* Use a clearer algorithm for the merkle
Should also be more efficient due to not shifting as often.
* Tidy Mlsag
* Remove verify_rct_* from Mlsag
Both methods were ports from Monero, overtly specific without clear
documentation. They need to be added back in, with documentation, or included
in a node which provides the necessary further context for them to be naturally
understandable.
* Move mlsag/mod.rs to mlsag.rs
This should only be a folder if it has multiple files.
* Replace EcdhInfo terminology
The ECDH encrypted the amount, yet this struct contained the encrypted amount,
not some ECDH.
Also corrects the types on the original EcdhInfo struct.
* Correct handling of commitment masks when scanning
* Route read_array through read_raw_vec
* Misc lint
* Make a proper RctType enum
No longer caches RctType in the RctSignatures as well.
* Replace Vec<Bulletproofs> with Bulletproofs
Monero uses aggregated range proofs, so there's only ever one Bulletproof. This
is enforced with a consensus rule as well, making this safe.
As for why Monero uses a vec, it's probably due to the lack of variadic typing
used. Its effectively an Option for them, yet we don't need an Option since we
do have variadic typing (enums).
* Add necessary checks to Eventuality re: supported protocols
* Fix for block 202612 and fix merkel root calculations
* MLSAG (de)serialisation fix
ss_2_elements will not always be 2 as rct type 1 transactions are not enforced to have one input
* Revert "MLSAG (de)serialisation fix"
This reverts commit 5e710e0c96.
here it checks number of MGs == number of inputs:
0a1eaf26f9/src/cryptonote_core/tx_verification_utils.cpp (L60-59)
and here it checks for RctTypeFull number of MGs == 1:
0a1eaf26f9/src/ringct/rctSigs.cpp (L1325)
so number of inputs == 1
so ss_2_elements == 2
* update `MlsagAggregate` comment
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
* Fix the known issue with the DSA
I wrote it to only select TXs with a timelock, not only TXs which are unlocked.
This most likely explains why it so heavily selected coinbases.
Also moves an InternalError which would've never been hit on mainnet, yet
technically isn't an invariant, to only exist when cfg(test).
* Add a bin to download a chain, over RPC, reserializing and hashing every item
Parallelized. Doesn't check the deserialization is correct. Does use distinct,
persistent HTTP clients.
* Correct how Monero integration tests are run
* Support multiple RPCs in the reserialize_chain bin
* Don't call get_height every block
* Modify get_transactions to split requests as to not hit the restricted RPC limits
* Meaningful changes from aggressive-clippy
I do want to enable a few specific lints, yet aggressive-clippy as a whole
isn't worthwhile.
* Extend reserialize_chain with CLSAG/BP(+) verification
* Remove spammy println from reserialize_chain
* Update reserialize_chain for v1 and migration TXs
Also always marks 0-amount inputs as RCT due to impossibility of non-RCT
0-amount outputs.
* Only deserialize RctSignatures where's there at least one input
This is only enforced by the Monero protocol due to a single check the mixRing
isn't empty in get_pre_mlsag_hash. The value in ensuring there's a least one
input is to ensure the safety of our rct_type functions, which determines the
RctType based off structural analysis (specifically, input data if
MlsagBorromean).
rct_type was technically safe without this. A 0-input transaction would be
mis-classified as RctFull/MlsagAggregate, which would then make the
RctSignatures invalid for being RctFull (requiring exactly one input) yet not
having inputs, meaning an invalid RctSignatures would be mis-classified yet
still invalid.
This just removes the risk of mis-classification in the first place, tightening
the library's safety.
* docs/Getting Started.md: cargo build --release --all-features
* Fix the known instance of #295
* Bind RocksDB into serai-db
* Split up tests in CI to avoid node storage limits
* Corrections to prior commit
* Again
I called git commit --amend without calling git add . again :(
* Update the flow for completed signing processes
Now, an on-chain transaction exists. This resolves some ambiguities and
provides greater coordination.
* Clean Polyseed code
* Final tweaks
* Correct no-std builds for Polyseed
* Again correct no-std
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
Co-authored-by: GitHub Actions <unknown>
Co-authored-by: Boog900 <54e72d8a-345f-4599-bd90-c6b9bc7d0ec5@aleeas.com>
Co-authored-by: Boog900 <108027008+Boog900@users.noreply.github.com>
Co-authored-by: Steven Chang <stevenchang5000@gmail.com>
This is only enforced by the Monero protocol due to a single check the mixRing
isn't empty in get_pre_mlsag_hash. The value in ensuring there's a least one
input is to ensure the safety of our rct_type functions, which determines the
RctType based off structural analysis (specifically, input data if
MlsagBorromean).
rct_type was technically safe without this. A 0-input transaction would be
mis-classified as RctFull/MlsagAggregate, which would then make the
RctSignatures invalid for being RctFull (requiring exactly one input) yet not
having inputs, meaning an invalid RctSignatures would be mis-classified yet
still invalid.
This just removes the risk of mis-classification in the first place, tightening
the library's safety.
I wrote it to only select TXs with a timelock, not only TXs which are unlocked.
This most likely explains why it so heavily selected coinbases.
Also moves an InternalError which would've never been hit on mainnet, yet
technically isn't an invariant, to only exist when cfg(test).
* add mlsag
* fix last commit
* fix miner v1 txs
* fix non-miner v1 txs
* add borromean + fix mlsag
* add block hash calculations
* fix for the jokester that added unreduced scalars
to the borromean signature of
2368d846e671bf79a1f84c6d3af9f0bfe296f043f50cf17ae5e485384a53707b
* Add Borromean range proof verifying functionality
* Add MLSAG verifying functionality
* fmt & clippy :)
* update MLSAG, ss2_elements will always be 2
* Add MgSig proving
* Tidy block.rs
* Tidy Borromean, fix bugs in last commit, replace todo! with unreachable!
* Mark legacy EcdhInfo amount decryption as experimental
* Correct comments
* Write a new impl of the merkle algorithm
This one tries to be understandable.
* Only pull in things only needed for experimental when experimental
* Stop caching the Monero block hash now in processor that we have Block::hash
* Corrections for recent processor commit
* Use a clearer algorithm for the merkle
Should also be more efficient due to not shifting as often.
* Tidy Mlsag
* Remove verify_rct_* from Mlsag
Both methods were ports from Monero, overtly specific without clear
documentation. They need to be added back in, with documentation, or included
in a node which provides the necessary further context for them to be naturally
understandable.
* Move mlsag/mod.rs to mlsag.rs
This should only be a folder if it has multiple files.
* Replace EcdhInfo terminology
The ECDH encrypted the amount, yet this struct contained the encrypted amount,
not some ECDH.
Also corrects the types on the original EcdhInfo struct.
* Correct handling of commitment masks when scanning
* Route read_array through read_raw_vec
* Misc lint
* Make a proper RctType enum
No longer caches RctType in the RctSignatures as well.
* Replace Vec<Bulletproofs> with Bulletproofs
Monero uses aggregated range proofs, so there's only ever one Bulletproof. This
is enforced with a consensus rule as well, making this safe.
As for why Monero uses a vec, it's probably due to the lack of variadic typing
used. Its effectively an Option for them, yet we don't need an Option since we
do have variadic typing (enums).
* Add necessary checks to Eventuality re: supported protocols
* Fix for block 202612 and fix merkel root calculations
* MLSAG (de)serialisation fix
ss_2_elements will not always be 2 as rct type 1 transactions are not enforced to have one input
* Revert "MLSAG (de)serialisation fix"
This reverts commit 5e710e0c96.
here it checks number of MGs == number of inputs:
0a1eaf26f9/src/cryptonote_core/tx_verification_utils.cpp (L60-59)
and here it checks for RctTypeFull number of MGs == 1:
0a1eaf26f9/src/ringct/rctSigs.cpp (L1325)
so number of inputs == 1
so ss_2_elements == 2
* update `MlsagAggregate` comment
* cargo update
Resolves a yanked crate
* Move location of serai-client in Cargo.toml
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This is intended to be a reliable transport between the processors and
coordinator. Since it'll be intranet only, it's written as never fail.
Primarily needs testing and a proper ID.
* Move monero-serai from std to std-shims, where possible
* no-std fixes
* Make the HttpRpc its own feature, thiserror only on std
* Drop monero-rs's epee for a homegrown one
We only need it for a single function. While I tried jeffro's, it didn't work
out of the box, had three unimplemented!s, and is no where near viable for
no_std.
Fixes#182, though should be further tested.
* no-std monero-serai
* Allow base58-monero via git
* cargo fmt
lazy_static, if no_std environments were used, effectively required always
using spin locks. This resolves the ergonomics of that while adopting Rust std
code.
no_std does still use a spin based solution. Theoretically, we could use
atomics, yet writing our own Mutex wasn't a priority.
Provides a DST, and associated metadata as beneficial.
Also utilizes MuSig's context to session-bind. Since set_keys_messages also
binds to set, this is semi-redundant, yet that's appreciated.
Isn't spec compliant due to the lack of a spec to be compliant too.
Slight deviation from the paper by using a unique list instead of a multiset.
Closes#186, progresses #277.
This probably should be done with n-long lived tasks, one per Tributary. While
this may not be suitably performant long-term (potential DoS vector), this at
least resolves the halting concerns.
When we receive messages, we're provided with a message ID we can use to
prevent handling an item multiple times. That doesn't prevent us from *sending*
an item multiple times though. Thanks to the UID system, we can now not send if
already present.
Alternatively, we can remove the ordered message ID for just the UID, allowing
duplicates to be sent without issue, and handled on the receiving end.
Reduces lock contention.
Additionally changes block_key to include the genesis. While not technically
needed, the lack of genesis introduced a side effect where any Tributary on the
the database could return the block of any other Tributary. While that wasn't a
security issue, returning it suggested it was on-chain when it wasn't. This may
have been usable to create issues.
We had a race condition where'd we be informed of blocks 1 .. 3, and
immediately add 1 .. 3. Because we immediately tried to add 2 after 1, it'd
fail since the tip was still the genesis, yet 2 needs the tip to be 1.
Adding a channel, while ugly, was the simplest way to accomplish this.
Also has any added block be broadcasted. Else there's a race condition where a
node which syncs up to the most recent block does so, yet fails to add the next
block when it's committed to.
This defines the tart of a very complex series of locks I'm really unhappy
with. At the same time, there's not immediately a better solution. This also
should work without issue.
add_active_tributary writes the spec to disk before it returns, so even if the
VecDeque it pushes to isn't popped, the tributary will still be loaded on boot.
Removes last_block as an argument from Tendermint. It now loads from the DB as
needed. While slightly less performant, it's easiest and should be fine.
Impls a LocalP2p for testing.
Moves rebroadcasting into Tendermint, since it's what knows if a message is
fully valid + original.
Removes TributarySpec::validators() HashMap, as its non-determinism caused
different instances to have different round robin schedules. It was already
prior moved to a Vec for this issue, so I'm unsure why this remnant existed.
Also renames the GH no-std workflow from the prior commit.
When a Substrate block occurs, the coordinator is expected to emit
SubstrateBlock. This causes the processor to begin a variety of plans. The
processor now emits SubstrateBlockAck, explicitly listing all plan IDs, before
starting signing.
This lets the coordinator provide a SubstrateBlock transaction, and with it,
recognize all plan IDs as valid.
Prior, we would've had to have a spotty algorithm based upon the upcoming
Preprocess messages, or if we immediately provided the SubstrateBlock
transaction, then wait for the processor to inform us of the contained plans.
This creates an explicitly proper async flow not reliant on waiting for data
availability.
Alternatively, we could've replaced Preprocess with (Block, Vec<Preprocess>).
This would've been more efficient, yet also clunky due to the multiple usages
of the Preprocess message.
Necessary as our Tributary chains needed to agree when a Serai block has
occurred, and when a Monero block has occurred. Since those could happen at the
same time, some validators may put SeraiBlock before ExternalBlock and vice
versa, causing a chain halt. Now they can have distinct ordering queues.
The existing code was almost entirely applicable. It just needed to be scoped
with an ID. While the handle function is now a bit convoluted, I don't see a
better option.
There is the ability to cause state bloat by flooding Tributary.
KeyGen/Sign specifically shouldn't allow bloat since we check the
commitments/preprocesses/shares for validity. Accordingly, any invalid data
(such as bloat) should be detected.
It was posssible to place bloat after the valid data. Doing so would be
considered a valid KeyGen/Sign message, yet could add up to 50k kB per sign.
Achieves feasible performance in the ed448 which makes it potentially viable
for real world usage.
Accordingly prepares a new release, updating the README.
[0; 32] is a magic for no block has been set yet due to this being the first
key pair. If [0; 32] is the latest finalized block, the processor determines
an activation block based on timestamps.
This doesn't use an Option for ergonomic reasons.
It originally wasn't an enum so software which had yet to update before an
integration wouldn't error (as now enums are strictly typed). The strict typing
is preferable though.
SubstrateBlock's provision of the most recently acknowledged block has
equivalent information with the same latency. Accordingly, there's no need for
it.
Clearly establishes why consistency is guaranteed from a Rust borrow-checker
mindset. While there are plenty of... 'violations', they're clearly explained.
Hopefully, this method of thinking helps promote/ensure consistency in the
future.
The signing set should be the first group to submit preprocesses to Tributary.
Re-attempts shouldn't be once every 30s, yet n blocks since the last relevant
message.
Removes the use of an async task/channel in the signer (and Substrate signer).
Also removes the need to be able to get the time from a coin's block, which was
a fragile system marked with a TODO already.
Writes a custom unsigned extrinic creator due to subxt having an internal error
with the scale metadata. While the code in our scope increased, it's much more
ergonomic to our usage. We may end up rewriting most of subxt, eventually.
Step moved a step forward after an externally synced/added block. This created
a race condition to add the block between the sync process and the Tendermint
machine. Now that the block routes through Tendermint, there is no such race
condition.
Previously, Tendermint needed to be live more than it needed to be correct.
Under the original intention for it, correctness would fail if any coin
desynced, which would cause the node to fail entirely. By accepting a
supermajority's view of state, despite its own, a single coin's failure would
only lead to inability to participate with that single coin.
Now that Tendermint is solely for Tributary, nodes should halt a coin-specific
chain if their view of the chain differs. They are unable to meaningless
participate regardless.
This also means a supermajority of validators can no longer fake messages from
other validators, allowing the Tributary chain to use uniform weights with much
less impact. There is still enough impact they can't be used (ability to cause
a fork), yet they should allow uniform block production (as that's solely a DoS
concern).
While we prior could've simply additionally checked signatures, add_block's
lack of a failure case would've meant it had to panic. This would've been a DoS
possible a minority-weight *which affected the entire coordinator* and
therefore *the entire validator for all coins*.
While Bitcoin practically doesn't have long re-orgs, it is possible for a
single miner to build a long chain. Recently, a miner found 5 blocks in a row,
which would be enough to re-org a transaction Serai considered finalized.
Needed for the in-instructions pallet to verify in-instructions are
appropriately signed and continue developing that.
Fixes a bug in the validator-sets pallet, moves several items from the pallet
to primitives.
* Partial move to ff 0.13
It turns out the newly released k256 0.12 isn't on ff 0.13, preventing further
work at this time.
* Update all crates to work on ff 0.13
The provided curves still need to be expanded to fit the new API.
* Finish adding dalek-ff-group ff 0.13 constants
* Correct FieldElement::product definition
Also stops exporting macros.
* Test most new parts of ff 0.13
* Additionally test ff-group-tests with BLS12-381 and the pasta curves
We only tested curves from RustCrypto. Now we test a curve offered by zk-crypto,
the group behind ff/group, and the pasta curves, which is by Zcash (though
Zcash developers are also behind zk-crypto).
* Finish Ed448
Fully specifies all constants, passes all tests in ff-group-tests, and finishes moving to ff-0.13.
* Add RustCrypto/elliptic-curves to allowed git repos
Needed due to k256/p256 incorrectly defining product.
* Finish writing ff 0.13 tests
* Add additional comments to dalek
* Further comments
* Update ethereum-serai to ff 0.13
Updates to polkadot-v0.9.40, with a variety of dependency updates accordingly.
Substrate thankfully now uses k256 0.13, pathing the way for #256. We couldn't
upgrade to polkadot-v0.9.40 without this due to polkadot-v0.9.40 having
fundamental changes to syncing. While we could've updated tendermint, it's not
worth the continued development effort given its inability to work with
multiple validator sets.
Purges sc-tendermint. Keeps tendermint-machine for #163.
Closes#137, #148, #157, #171. #96 and #99 should be re-scoped/clarified. #134
and #159 also should be clarified. #169 is also no longer a priority since
we're only considering temporal deployments of tendermint. #170 also isn't
since we're looking at effectively sharded validator sets, so there should
be no singular large set needing high performance.
The original intent was to use inherent transactions to prevent needing to vote
on-chain, which would spam the chain with worthless votes. Inherent
transactions, and our Tendermint library, would use the BFT's processs voting
to also vote on all included transactions. This perfectly collapses integrity
voting creating *no additional on-chain costs*.
Unfortunately, this led to issues such as #6, along with questions of validator
scalability when all validators are expencted to participate in consensus (in
order to vote on if the included instructions are valid). This has been
summarized in #241.
With this change, we can remove Tendermint from Substrate. This greatly
decreases our complexity. While I'm unhappy with the amount of time spent on
it, just to reach this conclusion, thankfully tendermint-machine itself is
still usable for #163. This also has reached a tipping point recently as the
polkadot-v0.9.40 branch of substrate changed how syncing works, requiring
further changes to sc-tendermint. These have no value if we're just going to
get rid of it later, due to fundamental design issues, yet I would like to
keep Substrate updated.
This should be followed by moving back to GRANDPA, enabling closing most open
Tendermint issues.
Please note the current in-instructions-pallet does not actually verify the
included signature yet. It's marked TODO, despite this bing critical.
There already should only be one validator set operating per network. This
formalizes that. Then, validator sets used to be able to operate over multiple
networks. That is no longer possible.
This formalization increases validator set flexibility while also allowing the
ability to formalize the definiton of tokens (which is necessary to define a
gas asset).
Moves the processor to it. This ends up as a net-neutral LoC change to the
processor, unfortunately, yet this makes bitcoin-serai safer/easier to use, and
increases the processor's usage of bitcoin-serai.
Also re-organizes bitcoin-serai a bit.
I'm really unhappy with a cfg(test) within the codebase. The double checking of
it makes it tolerable though, especially when compared to dropping these tests.
* Initial work on a message box
* Finish message-box (untested)
* Expand documentation
* Embed the recipient in the signature challenge
Prevents a message from A -> B from being read as from A -> C.
* Update documentation by bifurcating sender/receiver
* Panic on receiving an invalid signature
If we've received an invalid signature in an authenticated system, a
service is malicious, critically faulty (equivalent to malicious), or
the message layer has been compromised (or is otherwise critically
faulty).
Please note a receiver who handles a message they shouldn't will trigger
this. That falls under being critically faulty.
* Documentation and helper methods
SecureMessage::new and SecureMessage::serialize.
Secure Debug for MessageBox.
* Have SecureMessage not be serialized by default
Allows passing around in-memory, if desired, and moves the error from
decrypt to new (which performs deserialization).
Decrypt no longer has an error since it panics if given an invalid
signature, due to this being intranet code.
* Explain and improve nonce handling
Includes a missing zeroize call.
* Rebase to latest develop
Updates to transcript 0.2.0.
* Add a test for the MessageBox
* Export PrivateKey and PublicKey
* Also test serialization
* Add a key_gen binary to message_box
* Have SecureMessage support Serde
* Add encrypt_to_bytes and decrypt_from_bytes
* Support String ser via base64
* Rename encrypt/decrypt to encrypt_bytes/decrypt_to_bytes
* Directly operate with values supporting Borsh
* Use bincode instead of Borsh
By staying inside of serde, we'll support many more structs. While
bincode isn't canonical, we don't need canonicity on an authenticated,
internal system.
* Turn PrivateKey, PublicKey into structs
Uses Zeroizing for the PrivateKey per #150.
* from_string functions intended for loading from an env
* Use &str for PublicKey from_string (now from_str)
The PrivateKey takes the String to take ownership of its memory and
zeroize it. That isn't needed with PublicKeys.
* Finish updating from develop
* Resolve warning
* Use ZeroizingAlloc on the key_gen binary
* Move message-box from crypto/ to common/
* Move key serialization functions to ser
* add/remove functions in MessageBox
* Implement Hash on dalek_ff_group Points
* Make MessageBox generic to its key
Exposes a &'static str variant for internal use and a RistrettoPoint
variant for external use.
* Add Private to_string as deprecated
Stub before more competent tooling is deployed.
* Private to_public
* Test both Internal and External MessageBox, only use PublicKey in the pub API
* Remove panics on invalid signatures
Leftover from when this was solely internal which is now unsafe.
* Chicken scratch a Scanner task
* Add a write function to the DKG library
Enables writing directly to a file.
Also modifies serialize to return Zeroizing<Vec<u8>> instead of just Vec<u8>.
* Make dkg::encryption pub
* Remove encryption from MessageBox
* Use a 64-bit block number in Substrate
We use a 64-bit block number in general since u32 only works for 120 years
(with a 1 second block time). As some chains even push the 1 second threshold,
especially ones based on DAG consensus, this becomes potentially as low as 60
years.
While that should still be plenty, it's not worth wondering/debating. Since
Serai uses 64-bit block numbers elsewhere, this ensures consistency.
* Misc crypto lints
* Get the scanner scratch to compile
* Initial scanner test
* First few lines of scheduler
* Further work on scheduler, solidify API
* Define Scheduler TX format
* Branch creation algorithm
* Document when the branch algorithm isn't perfect
* Only scanned confirmed blocks
* Document Coin
* Remove Canonical/ChainNumber from processor
The processor should be abstracted from canonical numbers thanks to the
coordinator, making this unnecessary.
* Add README documenting processor flow
* Use Zeroize on substrate primitives
* Define messages from/to the processor
* Correct over-specified versioning
* Correct build re: in_instructions::primitives
* Debug/some serde in crypto/
* Use a struct for ValidatorSetInstance
* Add a processor key_gen task
Redos DB handling code.
* Replace trait + impl with wrapper struct
* Add a key confirmation flow to the key gen task
* Document concerns on key_gen
* Start on a signer task
* Add Send to FROST traits
* Move processor lib.rs to main.rs
Adds a dummy main to reduce clippy dead_code warnings.
* Further flesh out main.rs
* Move the DB trait to AsRef<[u8]>
* Signer task
* Remove a panic in bitcoin when there's insufficient funds
Unchecked underflow.
* Have Monero's mine_block mine one block, not 10
It was initially a nicety to deal with the 10 block lock. C::CONFIRMATIONS
should be used for that instead.
* Test signer
* Replace channel expects with log statements
The expects weren't problematic and had nicer code. They just clutter test
output.
* Remove the old wallet file
It predates the coordinator design and shouldn't be used.
* Rename tests/scan.rs to tests/scanner.rs
* Add a wallet test
Complements the recently removed wallet file by adding a test for the scanner,
scheduler, and signer together.
* Work on a run function
Triggers a clippy ICE.
* Resolve clippy ICE
The issue was the non-fully specified lambda in signer.
* Add KeyGenEvent and KeyGenOrder
Needed so we get KeyConfirmed messages from the key gen task.
While we could've read the CoordinatorMessage to see that, routing through the
key gen tasks ensures we only handle it once it's been successfully saved to
disk.
* Expand scanner test
* Clarify processor documentation
* Have the Scanner load keys on boot/save outputs to disk
* Use Vec<u8> for Block ID
Much more flexible.
* Panic if we see the same output multiple times
* Have the Scanner DB mark itself as corrupt when doing a multi-put
This REALLY should be a TX. Since we don't have a TX API right now, this at
least offers detection.
* Have DST'd DB keys accept AsRef<[u8]>
* Restore polling all signers
Writes a custom future to do so.
Also loads signers on boot using what the scanner claims are active keys.
* Schedule OutInstructions
Adds a data field to Payment.
Also cleans some dead code.
* Panic if we create an invalid transaction
Saves the TX once it's successfully signed so if we do panic, we have a copy.
* Route coordinator messages to their respective signer
Requires adding key to the SignId.
* Send SignTransaction orders for all plans
* Add a timer to retry sign_plans when prepare_send fails
* Minor fmt'ing
* Basic Fee API
* Move the change key into Plan
* Properly route activation_number
* Remove ScannerEvent::Block
It's not used under current designs
* Nicen logs
* Add utilities to get a block's number
* Have main issue AckBlock
Also has a few misc lints.
* Parse instructions out of outputs
* Tweak TODOs and remove an unwrap
* Update Bitcoin max input/output quantity
* Only read one piece of data from Monero
Due to output randomization, it's infeasible.
* Embed plan IDs into the TXs they create
We need to stop attempting signing if we've already signed a protocol. Ideally,
any one of the participating signers should be able to provide a proof the TX
was successfully signed. We can't just run a second signing protocol though as
a single malicious signer could complete the TX signature, and publish it,
yet not complete the secondary signature.
The TX itself has to be sufficient to show that the TX matches the plan. This
is done by embedding the ID, so matching addresses/amounts plans are
distinguished, and by allowing verification a TX actually matches a set of
addresses/amounts.
For Monero, this will need augmenting with the ephemeral keys (or usage of a
static seed for them).
* Don't use OP_RETURN to encode the plan ID on Bitcoin
We can use the inputs to distinguih identical-output plans without issue.
* Update OP_RETURN data access
It's not required to be the last output.
* Add Eventualities to Monero
An Eventuality is an effective equivalent to a SignableTransaction. That is
declared not by the inputs it spends, yet the outputs it creates.
Eventualities are also bound to a 32-byte RNG seed, enabling usage of a
hash-based identifier in a SignableTransaction, allowing multiple
SignableTransactions with the same output set to have different Eventualities.
In order to prevent triggering the burning bug, the RNG seed is hashed with
the planned-to-be-used inputs' output keys. While this does bind to them, it's
only loosely bound. The TX actually created may use different inputs entirely
if a forgery is crafted (which requires no brute forcing).
Binding to the key images would provide a strong binding, yet would require
knowing the key images, which requires active communication with the spend
key.
The purpose of this is so a multisig can identify if a Transaction the entire
group planned has been executed by a subset of the group or not. Once a plan
is created, it can have an Eventuality made. The Eventuality's extra is able
to be inserted into a HashMap, so all new on-chain transactions can be
trivially checked as potential candidates. Once a potential candidate is found,
a check involving ECC ops can be performed.
While this is arguably a DoS vector, the underlying Monero blockchain would
need to be spammed with transactions to trigger it. Accordingly, it becomes
a Monero blockchain DoS vector, when this code is written on the premise
of the Monero blockchain functioning. Accordingly, it is considered handled.
If a forgery does match, it must have created the exact same outputs the
multisig would've. Accordingly, it's argued the multisig shouldn't mind.
This entire suite of code is only necessary due to the lack of outgoing
view keys, yet it's able to avoid an interactive protocol to communicate
key images on every single received output.
While this could be locked to the multisig feature, there's no practical
benefit to doing so.
* Add support for encoding Monero address to instructions
* Move Serai's Monero address encoding into serai-client
serai-client is meant to be a single library enabling using Serai. While it was
originally written as an RPC client for Serai, apps actually using Serai will
primarily be sending transactions on connected networks. Sending those
transactions require proper {In, Out}Instructions, including proper address
encoding.
Not only has address encoding been moved, yet the subxt client is now behind
a feature. coin integrations have their own features, which are on by default.
primitives are always exposed.
* Reorganize file layout a bit, add feature flags to processor
* Tidy up ETH Dockerfile
* Add Bitcoin address encoding
* Move Bitcoin::Address to serai-client's
* Comment where tweaking needs to happen
* Add an API to check if a plan was completed in a specific TX
This allows any participating signer to submit the TX ID to prevent further
signing attempts.
Also performs some API cleanup.
* Minimize FROST dependencies
* Use a seeded RNG for key gen
* Tweak keys from Key gen
* Test proper usage of Branch/Change addresses
Adds a more descriptive error to an error case in decoys, and pads Monero
payments as needed.
* Also test spending the change output
* Add queued_plans to the Scheduler
queued_plans is for payments to be issued when an amount appears, yet the
amount is currently pre-fee. One the output is actually created, the
Scheduler should be notified of the amount it was created with, moving from
queued_plans to plans under the actual amount.
Also tightens debug_asserts to asserts for invariants which may are at risk of
being exclusive to prod.
* Add missing tweak_keys call
* Correct decoy selection height handling
* Add a few log statements to the scheduler
* Simplify test's get_block_number
* Simplify, while making more robust, branch address handling in Scheduler
* Have fees deducted from payments
Corrects Monero's handling of fees when there's no change address.
Adds a DUST variable, as needed due to 1_00_000_000 not being enough to pay
its fee on Monero.
* Add comment to Monero
* Consolidate BTC/XMR prepare_send code
These aren't fully consolidated. We'd need a SignableTransaction trait for
that. This is a lot cleaner though.
* Ban integrated addresses
The reasoning why is accordingly documented.
* Tidy TODOs/dust handling
* Update README TODO
* Use a determinisitic protocol version in Monero
* Test rebuilt KeyGen machines function as expected
* Use a more robust KeyGen entropy system
* Add DB TXNs
Also load entropy from env
* Add a loop for processing messages from substrate
Allows detecting if we're behind, and if so, waiting to handle the message
* Set Monero MAX_INPUTS properly
The previous number was based on an old hard fork. With the ring size having
increased, transactions have since got larger.
* Distinguish TODOs into TODO and TODO2s
TODO2s are for after protonet
* Zeroize secret share repr in ThresholdCore write
* Work on Eventualities
Adds serialization and stops signing when an eventuality is proven.
* Use a more robust DB key schema
* Update to {k, p}256 0.12
* cargo +nightly clippy
* cargo update
* Slight message-box tweaks
* Update to recent Monero merge
* Add a Coordinator trait for communication with coordinator
* Remove KeyGenHandle for just KeyGen
While KeyGen previously accepted instructions over a channel, this breaks the
ack flow needed for coordinator communication. Now, KeyGen is the direct object
with a handle() function for messages.
Thankfully, this ended up being rather trivial for KeyGen as it has no
background tasks.
* Add a handle function to Signer
Enables determining when it's finished handling a CoordinatorMessage and
therefore creating an acknowledgement.
* Save transactions used to complete eventualities
* Use a more intelligent sleep in the signer
* Emit SignedTransaction with the first ID *we can still get from our node*
* Move Substrate message handling into the new coordinator recv loop
* Add handle function to Scanner
* Remove the plans timer
Enables ensuring the ordring on the handling of plans.
* Remove the outputs function which panicked if a precondition wasn't met
The new API only returns outputs upon satisfaction of the precondition.
* Convert SignerOrder::SignTransaction to a function
* Remove the key_gen object from sign_plans
* Refactor out get_fee/prepare_send into dedicated functions
* Save plans being signed to the DB
* Reload transactions being signed on boot
* Stop reloading TXs being signed (and report it to peers)
* Remove message-box from the processor branch
We don't use it here yet.
* cargo +nightly fmt
* Move back common/zalloc
* Update subxt to 0.27
* Zeroize ^1.5, not 1
* Update GitHub workflow
* Remove usage of SignId in completed
The current /crypto folder, as of this commit, is identical, except for the
years in the copyright statements. GitHub's CI also passed for the previous
commit, ensuring the repo's integrity during that commit. This now establishes
trust for /crypto, which will be used to update documentation and create
releases.
* add monero seed support
* fix some of the pr comments
* remove languages module and unnecessary error returns
* Clean classic seed impl
Fixes a few issues regarding Zeroize usage/API safety. Mainly a cleanup.
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit greatly expands the usage of black_box/zeroize on bits, as it
originally should have. It is likely overkill, leading to less efficient
code generation, yet does its best to be comprehensive where comprehensiveness
is extremely annoying to achieve.
In the future, this usage of black_box may be desirable to move to its own
crate.
Credit to @AaronFeickert for identifying the original commit was incomplete.
Unfortunately, G::from_bytes doesn't require canonicity so that still can't
be properly tested for. While we could try to detect SEC1, and write tests
on that, there's not a suitably stable/wide enough solution to be worth it.
This could still be gamed. For [1, 2, 3], the options were ([1], [2, 3]) or
([1, 2], [3]). This means 2 would always have the maximum round count, and
thus this is still game-able. There's no point to keeping its complexity
accordingly when the algorithm is as efficient as it is.
While a proper random could be used to satisfy 3.7.2, it'd break the
expected determinism.
Also moves the aggregator over to Digest. While a bit verbose for this context,
as all appended items were fixed length, it's length prefixing is solid and
the API is pleasant. The downside is the additional dependency which is
in tree and quite compact.
While the prior intent was to avoid zeroizing for vartime verification, which
is assumed to not have any private data, this simplifies the code and promotes
safety.
Offset signing is now tested. Multi-nonce algorithms are now tested.
Multi-generator nonce algorithms are now tested. More fault cases are now tested
as well.
This wasn't done prior to be 'leaderless', as now the participant with the
lowest ID has an extra step, yet this is still trivial. There's also notable
performance benefits to not taking the previous dividing approach, which
performed an exp.
There's two ways which this could be tested.
1) Preprocess not taking in an arbitrary RNG item, yet the relevant bytes
This would be an unsafe level of refactoring, in my opinion.
2) Test random_nonce and test the passed in RNG eventually ends up at
random_nonce.
This takes the latter route, both verifying random_nonce meets the vectors
and that the FROST machine calls random_nonce properly.
The audit recommends checking failure cases for from_bytes,
from_bytes_unechecked, and from_repr. This isn't feasible.
from_bytes is allowed to have non-canonical values. [0xff; 32] may accordingly
be a valid point for non-SEC1-encoded curves.
from_bytes_unchecked doesn't have a defined failure mode, and by name,
unchecked, shouldn't necessarily fail. The audit acknowledges the tests should
test for whatever result is 'appropriate', yet any result which isn't a failure
on a valid element is appropriate.
from_repr must be canonical, yet for a binary field of 2^n where n % 8 == 0, a
[0xff; n / 8] repr would be valid.
single function
3.4.3 actually describes getting rid of DLEqProof for a thin wrapper around
MultiDLEqProof. That can't be done due to DLEqProof not requiring the std
features, enabling Vecs, which MultiDLEqProof relies on.
Merging the verification statement does simplify the code a bit. While merging
the proof could also be, it has much less value due to the simplicity of
proving (nonce * G, scalar * G).
This will only be called with 0 if the code fails to do proper screening of its
arguments. If such a flaw is present, the DKG lib is critically broken (as this
function isn't public). If it was allowed to continue executing, it'd reveal
the secret share.
* serai Dockerfile & Makefile fixed
* added new bitcoin mod & bitcoinhram
* couple changes
* added odd&even check for bitcoin signing
* sign message updated
* print_keys commented out
* fixed signing process
* Added new bitcoin library & added most of bitcoin processor logic
* added new crate and refactored the bitcoin coin library
* added signing test function
* moved signature.rs
* publish set to false
* tests moved back to the root
* added new functions to rpc
* added utxo test
* added new rpc methods and refactored bitcoin processor
* added spendable output & fixed errors & added new logic for sighash & opened port 18443 for bitcoin docker
* changed tweak keys
* added tweak_keys & publish transaction and refactored bitcoin processor
* added new structs and fixed problems for testing purposes
* reverted dockerfile back its original
* reverted block generation of bitcoin to 5 seconds
* deleted unnecessary test function
* added new sighash & added new dbg messages & fixed couple errors
* fixed couple issue & removed unused functions
* fix for signing process
* crypto file for bitcoin refactored
* disabled test_send & removed some of the debug logs
* signing implemented & transaction weight calculation added & change address logic added
* refactored tweak_keys
* refactored mine_block & fixed change_address logic
* implemented new traits to bitcoin processor& refactored bitcoin processor
* added new line to tests file
* added new line to bitcoin's wallet.rs
* deleted Cargo.toml from coins folder
* edited bitcoin's Cargo.toml and added LICENSE
* added new line to bitcoin's Cargo.toml
* added spaces
* added spaces
* deleted unnecessary object
* added spaces
* deleted patch numbers
* updated sha256 parameter for message
* updated tag as const
* deleted unnecessary brackets and imports
* updated rpc.rs to 2 space indent
* deleted unnecessary brackers
* deleted unnecessary brackets
* changed it to explicit
* updated to explicit
* deleted unnecessary parsing
* added ? for easy return
* updated imports
* updated height to number
* deleted unnecessary brackets
* updated clsag to sig & to_vec to as_ref
* updated _sig to schnorr_signature
* deleted unnecessary variable
* updated Cargo.toml of processor and bitcoin
* updated imports of bitcoin processor
* updated MBlock to BBlock
* updated MSignable to BSignable
* updated imports
* deleted mask from Fee
* updated get_block function return
* updated comparison logic for scripts
* updated assert to debug_assert
* updated height to number
* updated txid logic
* updated tweak_keys definition
* updated imports
* deleted new line
* delete HashMap from monero
* deleted old test code parts
* updated test amount to a round number
* changed the test code part back to its original
* updated imports of rpc.rs
* deleted unnecessary return assignments
* deleted get_fee_per_byte
* deleted create_raw_transaction
* deleted fund_raw_transaction
* deleted sign transaction rpc
* delete verify_message rpc
* deleted get_balance
* deleted decode_raw_transaction rpc
* deleted list_transactions rpc
* changed test_send to p2wpkh
* updated imports of test_send
* fixed imports of test_send
* updated bitcoin's mine_block function
* updated bitcoin's test_send
* updated bitcoin's hram and test_signing
* deleted 2 rpc function (is_confirmed & get_transaction_block_number)
* deleted get_raw_transaction_hex
* deleted get_raw_transaction_info
* deleted new_address
* deleted test_mempool_accept
* updated remove(0) to remove(index)
* deleted ger_raw_transaction
* deleted RawTx trait and converted type to Transaction
* reverted raw_hex feature back
* added NotEnoughFunds to CoinError
* changed Sighash to all
* removed lifetime of RpcParams
* changed pub to pub(crate) & changed sig_hash line
* changed taproot_key_spend_signature_hash to internal
* added Clone to RpcError & deleted get_utxo_for
* changed to_hex to as_bytes for weight calculation
* updated SpendableOutput
* deleted unnecessary parentheses
* updated serialize of Output s id field
* deleted unused crate & added lazy_static
* updated RPC init function
* added lazy_static for TAG_HASH & updated imported crates
* changed get_block_index to get_block_number
* deleted get_block_info
* updated get_height to get_latest_block_number
* removed GetBlockWithDetailResult and get_block_with_transactions
* deleted unnecessary imports from rpc_helper
* removed lock and unlock_unspent
* deleted get_transactions and get_transaction and renamed get_raw_transaction to get_transaction
* updated opt_into_json
* changed payment_address and amount to output_script and amount for transcript
* refactored error logic for rpc & deleted anyhow crate
* added a dedicated file for json helper functions
* refactored imports and deleted unused code
* added clippy::non_snake_case
* removed unused Error items
* added new line to Cargo
* rekmoved Block and used bitcoin::Block direcetly
* removed added println and futures.len check
* removed HashMap from coin mod.rs
* updated Testnet to Regtest
* removed unnecessary variable
* updated as_str to &
* removed RawTx trait
* added newline
* changed test transaction to p2pkh
* updated test_send
* updated test_send
* updated test_send
* reformatted bitcoin processor
* moved sighash logic into signmachine
* removed generate_to_address
* added test_address function to bitcoin processor
* updated RpcResponse to enum and added Clone trait
* removed old RpcResponse
* updated shared_key to internal_key
* updated fee part
* updated test_send block logic
* added a test function for getting spendables
* updated tweaking keys logic
* updated calculate_weight logic
* added todo for BitcoinSchnorr Algorithm
* updated calculate_weight
* updated calculate_weight
* updated calculate_weight
* added a TODO for bitcoin's signing process
* removed unused code
* Finish merging develop
* cargo fmt
* cargo machete
* Handle most clippy lints on bitcoin
Doesn't handle the unused transcript due to pending cryptographic considerations.
* Rearrange imports and clippy tests
* Misc processor lint
* Update deny.toml
* Remove unnecessary RPC code
* updated test_send
* added bitcoin ci & updated test-dependencies yml
* fixed bitcoin ci
* updated bitcoin ci yml
* Remove mining from the bitcoin/monero docker files
The tests should control block production in order to test various
circumstances. The automatic mining disrupts assumptions made in testing. Since
we're now using the Bitcoin docker container for testing...
* Multiple fixes to the Bitcoin processor
Doesn't unwrap on RPC errors. Returns the expected connection error.
Fee calculation has a random - 1. This has been removed.
Supports the change address being an Option, as it is. This should not have
been blindly unwrapped.
* Remove unnecessary RPC code
* Further RPC simplifications
* Simplify Bitcoin action
It should not be mining.
* cargo fmt
* Finish RPC simplifications
* Run bitcoind as a daemon
* Remove the requirement on txindex
Saves tens of GB.
Also has attempt_send no longer return a list of outputs. That's incompatible
with this and only relevant to old scheduling designs.
* Remove number from Bitcoin SignableTransaction
Monero requires the current block number for decoy selection. Bitcoin doesn't
have a use.
* Ban coinbase transactions
These are burdened by maturity, so it's critically flawed to support them.
This causes the test_send function to fail as its working was premised on
a coinbase output. While it does make an actual output, it had insufficient
funds for the test's expectations due to regtest halving every 150 blocks.
In order to workaround this, the test will invalidate any existing chain,
offering a fresh start.
Also removes test_get_spendables and simplifies test_send.
* Various simplifications
Modifies SpendableOutput further to not require RPC calls at time of sign.
Removes the need to have get_transaction in the RPC.
* Clean prepare_send
* Update the Bitcoin TransactionMachine to output a Transaction
* Bitcoin TransactionMachine simplifications
* Update XOnly key handling
* Use a single sighash cache
* Move tweak_keys
* Remove unnecessary PSBT sets
* Restore removed newlines
* Other newlines
* Replace calculate_weight's custom math with a dummy TX serialize
* Move BTC TX construction code from processor to bitcoin
* Rename transactions.rs to wallet.rs
* Remove unused crate
* Note TODO
* Clean bitcoin signature test
* Make unit test out of BTC FROST signing test
* Final lint
* Remove usage of PartiallySignedTransaction
---------
Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
There's a failing CI run on a node which booted, yet didn't create a genesis
yet. Apparently, the RPC is potentially accessible before the chain is in.
This attempts to resolve that.
* Use Monero-compatible additional TX keys
This still sends a fingerprinting flare up if you send to a subaddress which
needs to be fixed. Despite that, Monero no should no longer fail to scan TXs
from monero-serai regarding additional keys.
Previously it failed becuase we supplied one key as THE key, and n-1 as
additional. Monero expects n for additional.
This does correctly select when to use THE key versus when to use the additional
key when sending. That removes the ability for recipients to fingerprint
monero-serai by receiving to a standard address yet needing to use an additional
key.
* Add tokens_primitives
Moves OutInstruction from in-instructions.
Turns Destination into OutInstruction.
* Correct in-instructions DispatchClass
* Add initial tokens pallet
* Don't allow pallet addresses to equal identity
* Add support for InInstruction::transfer
Requires a cargo update due to modifications made to serai-dex/substrate.
Successfully mints a token to a SeraiAddress.
* Bind InInstructions to an amount
* Add a call filter to the runtime
Prevents worrying about calls to the assets pallet/generally tightens things
up.
* Restore Destination
It was meged into OutInstruction, yet it didn't make sense for OutInstruction
to contain a SeraiAddress.
Also deletes the excessively dated Scenarios doc.
* Split PublicKey/SeraiAddress
Lets us define a custom Display/ToString for SeraiAddress.
Also resolves an oddity where PublicKey would be encoded as String, not
[u8; 32].
* Test burning tokens/retrieving OutInstructions
Modularizes processor_coinUpdates into a shared testing utility.
* Misc lint
* Don't use PolkadotExtrinsicParams
This still sends a fingerprinting flare up if you send to a subaddress which
needs to be fixed. Despite that, Monero no should no longer fail to scan TXs
from monero-serai regarding additional keys.
Previously it failed becuase we supplied one key as THE key, and n-1 as
additional. Monero expects n for additional.
This does correctly select when to use THE key versus when to use the additional
key when sending. That removes the ability for recipients to fingerprint
monero-serai by receiving to a standard address yet needing to use an additional
key.
* Initial work on an In Inherents pallet
* Add an event for when a batch is executed
* Add a dummy provider for InInstructions
* Add in-instructions to the node
* Add the Serai runtime API to the processor
* Move processor tests around
* Build a subxt Client around Serai
* Successfully get Batch events from Serai
Renamed processor/substrate to processor/serai.
* Much more robust InInstruction pallet
* Implement the workaround from https://github.com/paritytech/subxt/issues/602
* Initial prototype of processor generated InInstructions
* Correct PendingCoins data flow for InInstructions
* Minor lint to in-instructions
* Remove the global Serai connection for a partial re-impl
* Correct ID handling of the processor test
* Workaround the delay in the subscription
* Make an unwrap an if let Some, remove old comments
* Lint the processor toml
* Rebase and update
* Move substrate/in-instructions to substrate/in-instructions/pallet
* Start an in-instructions primitives lib
* Properly update processor to subxt 0.24
Also corrects failures from the rebase.
* in-instructions cargo update
* Implement IsFatalError
* is_inherent -> true
* Rename in-instructions crates and misc cleanup
* Update documentation
* cargo update
* Misc update fixes
* Replace height with block_number
* Update processor src to latest subxt
* Correct pipeline for InInstructions testing
* Remove runtime::AccountId for serai_primitives::NativeAddress
* Rewrite the in-instructions pallet
Complete with respect to the currently written docs.
Drops the custom serializer for just using SCALE.
Makes slight tweaks as relevant.
* Move instructions' InherentDataProvider to a client crate
* Correct doc gen
* Add serde to in-instructions-primitives
* Add in-instructions-primitives to pallet
* Heights -> BlockNumbers
* Get batch pub test loop working
* Update in instructions pallet terminology
Removes the ambiguous Coin for Update.
Removes pending/artificial latency for furture client work.
Also moves to using serai_primitives::Coin.
* Add a BlockNumber primitive
* Belated cargo fmt
* Further document why DifferentBatch isn't fatal
* Correct processor sleeps
* Remove metadata at compile time, add test framework for Serai nodes
* Remove manual RPC client
* Simplify update test
* Improve re-exporting behavior of serai-runtime
It now re-exports all pallets underneath it.
* Add a function to get storage values to the Serai RPC
* Update substrate/ to latest substrate
* Create a dedicated crate for the Serai RPC
* Remove unused dependencies in substrate/
* Remove unused dependencies in coins/
Out of scope for this branch, just minor and path of least resistance.
* Use substrate/serai/client for the Serai RPC lib
It's a bit out of place, since these client folders are intended for the node to
access pallets and so on. This is for end-users to access Serai as a whole.
In that sense, it made more sense as a top level folder, yet that also felt
out of place.
* Move InInstructions test to serai-client for now
* Final cleanup
* Update deny.toml
* Cargo.lock update from merging develop
* Update nightly
Attempt to work around the current CI failure, which is a Rust ICE.
We previously didn't upgrade due to clippy 10134, yet that's been reverted.
* clippy
* clippy
* fmt
* NativeAddress -> SeraiAddress
* Sec fix on non-provided updates and doc fixes
* Add Serai as a Coin
Necessary in order to swap to Serai.
* Add a BlockHash type, used for batch IDs
* Remove origin from InInstruction
Makes InInstructionTarget. Adds RefundableInInstruction with origin.
* Document storage items in in-instructions
* Rename serai/client/tests/serai.rs to updates.rs
It only tested publishing updates and their successful acceptance.
2023-01-20 11:00:18 -05:00
1036 changed files with 106250 additions and 21287 deletions
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.