Fixes several bugs:
1. Gold list upgrades were getting blocked since it required the
following state change that was not permitted: Connected() -> Move
We have fixed this by enabling this state change and making Move
take an Option<ChannelPtr> so that we can immediately reset Gold
upgrades to Connected(ChannelPtr) once the upgrade has successfully
completed.
2. Previously we were not downgrading peers when they disconnect, this
has now been fixed.
3. Previously move_host() was not properly atomic. While HostState
protects single host from being misused (like being Refined and Moved
at the same time), HostState does not protect the hostlists
themselves from being written to, creating race conditions when hosts
are being removed from hostlists, like so:
thread1: assert!(get_index(host_a) == 0)
thread2: assert!(get_index(host_b) == 1)
thread1: remove(0)
thread2: remove(1) -> panic!
We resolve this by moving write locks higher up in the code so that
the entire sequence of looking up an index and removing it is
atomic.
4. Manual session had a bug in which we proceeded to establish a
Connector with an address even if try_register() failed. This has
been fixed. We now only try to connect to address that are valid,
otherwise we wait outbound_connect_timeout and retry
manual_attempt_limit tries.
* EMPTY_NODES_FP in sdk/crypto/smt/empty.rs since computing 256 hashes uses up all the gas
* Create SmtWasmFp backend for SMT in sdk/crypto/smt/wasmdb.rs
* add sparse_merkle_insert_batch() into runtime/import/smt.rs
* Update money contract nullifiers to use the SMT
implement the upgrade specified at: https://darkrenaissance.github.io/darkfi/dep/0001.html
The `(services, version)` field is only partially implemented- we simply
send an empty vector in the Version message. Later this can be used to
enable features in protocols.
This paves the way for DEP 0001: https://darkrenaissance.github.io/darkfi/dep/0001.html
We retain the same method for returning the channel's address, channel.address() but modify it so that it adapts depending on whether this channel is inbound or outbound. The usage remains the same and the return value is equivalent.
Before we were simply relying on channels() returning an empty
vector to determine our connection status, however this does not
work for e.g. Lilith that frequently has no active connections in
channels(), but may have received a connection more recently than the
time_with_no_connections refinery timeout.
This commit introduces the following changes that enable offline reconnect:
1. When we have no connections for longer than the period set in
settings.time_with_no_connections, disable the refinery. This stops
the refinery from deleting hosts from the hostlist when we are not
connected.
2. Introduce a new HostState called Suspend, which replaces
"quarantine". When we fail to connect to a host in OutboundSession we
downgrade the peer to greylist and mark its state as "Suspend". This
prevents us from making connections with this peer before the peer
passes through the refinery.
Essentially, setting the state to "Suspend" means the refinery is
tasked with filtering this peer and ensuring whether it should stay
on the hostlist or be deleted.
3. When we pause the refinery, we also free up all peers marked as
"Suspend", so that we can immediately reconnect to such peers when
we regain connectivity.
At present, time_with_no_connections is set to 30s by default, while the
refinery interval is 15s. This means that we could delete a maximum of 2
healthy hosts before the refinery is disabled. We need to consider this
carefully and test different outcomes.