HN user

hecturchi

141 karma
Posts4
Comments60
View on HN

As a child I was walking down the street and kicked something by chance that sounded metallic. 150 year old coin, irrc. Just there on the asphalt next to the sidewalk.

Unfortunately bronze, with trimmed edges, common mint and worth very little. But if you tell me someone just stumbles onto and old coin in the street just lime that, I pretty much believe it.

It must be great to live in a country where you can change your company address without any paper trail whatsoever: no rental contract, no utilities, no entry in the business registry, no acknowledgement from the tax office and nothing you can provide as proof or anything.

I guess the downside is, well, this, specially having thought it is a good idea to rely on Wise as first and only option for business banking, with their reputation...

Use Molly but be concious about relying on an unofficial fork controlled by one guy that can update itself anytime and has access to everything Signal does.

Also, don't talk about Molly. It's the best you can do for Molly.

I used Sailfish.

Then I discovered that "encryption" for them was using Luks with the numeric unlock pin as encryption key (which most people sets to 4 digits). They marketed themselves as a secure OS.

No passphrase option. I brought up that it was trivially brute-forceable in the forums and they vehemently fought the idea. My post eventually disappeared.

They were doing government contracts in Russia etc. Iirc. I put some dots together and phone rests in a drawer ever since. I have no idea how things are now though.

I have Valetudo on a Dreame X40 Ultra and very happy.

My recommendation is to flash and GTFO forever. Never upgrade, never ask anything, never read anything other than the install docs. Disregard pointers to join Telegram. Do not read release notes. And donate some money for the trouble if things work. That's your path to maximum happiness with Valetudo, blissful ignorance.

One day perhaps there will be a fork and things can be normal.

The American-European disparity along this latter dimension could hardly be greater: nearly 90 percent of U.S. households have air conditioning, whereas less than 10 percent of European homes do. The productivity gap between the U.S. and Europe helps explain this disparity.

Yeah, it must be that since US and EU are identical otherwise.

The main use of Pixel phones is that you can put GrapheneOS on them and regain full ownership of your hardware in a completely painless way. Plus adding a huge device security bonus on top.

You can have a profile completely de-googled and another one with Google Services for apps that need compatibility but remains off most of the time. You can uninstall Google too.

Owning your devices is a superpower that 99.9% of people don't have, but you can have it. The irony is that it's thanks to Google devices. Let's see how long it lasts.

Localhost benchmarks are pretty meaningless on code that is expected to deal with network latencies orders of magnitude larger.

It's ok that it runs faster, but much better if it's easier, safer, or more painless than the alternatives. The amount of code for a hello-world doesn't seem to indicate so, but maybe it pays off on more complex usecases.

Yubikey 5.7 2 years ago

Yubico has developed a library in-house that performs the underlying cryptographic operations (decryption, signing, etc.) for RSA and ECC.

No mention of why

I worked on IPFS Cluster and people like my co-authors had been experimenting with this already, but didn't have a name nor was formalized. I needed a way to sync state and decided to write it down "properly" as a paper along the way.

I think it's very valuable to bring people into the topic which is very cool (that's why I added a very long intro to try to provide all the background).

I forgot: key-value store using MD-CRDTs was implemented here: https://github.com/ipfs/go-ds-crdt

The trickiest part was not the CRDT, but the DAG traversal with multiple workers processing parallel updates on multiple branches and switching CRDT-DAG roots as they finish branches.

I'm the main author of the Merkle-DAGs CRDTs and I'm very happy to see this here. I'm a bit sorry now that I used the "Merkle-CRDT" name all over the paper because Merkle-Search-Trees CRDTs also deserve that tag.

I think it is good to explain Merkle-DAG CRDTs (MD-CRDTs) as "merklerized "op-based CRDTs", and I would add that Merkle-Search-Tree CRDTs (MST-CRDTs) are akin to "state-based" CRDTs, to complete the analogy. This helps to bridge traditional and Merkle CRDTs and I would probably introduce it the same way, but it is also not quite right when going into some more depth. I will try to explain why.

In MD-CRDTs we have a growing-DAG that works like a chain of operations that are applied in the order that the DAG is traversed. It looks a lot like an operation log, except it can have multiple branches and, if we follow my paper, operations do not need to have any total order (unlike op-based crdts). We know the latest operation in the DAG (the root node) happened AFTER its children, so there is an embedded notion of order. However, if it has multiple children, we don't know how to order the operations in their respective branches, and we don't need to because they should be commutative etc. For that to work, the paper explains that DAG-nodes embed not operations, but "state deltas". So in reality, MD-CRDTs are delta-based crdts where the merkle-dag structure stores the deltas as they are broadcasted from replicas. It's just that deltas look a lot like operations.

In MST-CRDTs, if my understanding is correct, replicas will be broadcasting the roots of the DAG pointing the full state (similar to state-based CRDTs broadcasting the full state). However, thanks to Merklelization etc., changes to the state only update sections of the full DAG, and diffing, retrieving or broadcasting only the changed parts is super easy and very compact. Since the nodes values will be CRDTs themselves, they can be merged on conflict just fine. In practice, it is sort of also dealing with delta-crdts.

The main thing in both is that reconstructing the full state from deltas is easy and efficient because everything is linked, so you just follow links and drop branches that you already have. Deltas without headaches.

Perhaps another way to conceptually understand both is that in MD-CRDTs, you add DAG-nodes to the top of the DAG as root DAG nodes, leaving the bottom of the DAG untouched. In MST-CRDTs, you add dag nodes to the bottom (the leaves) of the DAG, which cascades into having new root DAG nodes. In both cases you broadcast new root DAG nodes and the rest of people traverse and sync.

Now, what are the practical consequences for implementations:

- The main problem in pure MD-CRDTs (with no caveats) is the unbounded growth (ala blockchain) even when the state becomes smaller. This only matters if you plan to delete or overwrite things from the state. In MST-CRDTs it is "easy" to discard orphaned data. However, one of the main advantages in MD-CRDTs is that "syncing" happens from the last operation/delta. This can be important if you care about having certain notion of order, i.e. that "elements added last" are the first ones to be synced into an empty replica. Another advantage may be to be able to reconstruct multiple views of the same state by re-traversing the DAG, which has "everything".

- MST-CRDTs are very good for database tables, syncing is very efficient, things are compact. I haven't implemented them myself but they seem quite adequate for that use-case. When thinking of downsides, I wonder if they suffer from the cost of re-hashing operations as they grow with a very large number of keys and with heavy usage (larger blocks to hash or more levels to update). One very important advantage of MST-CRDTs is that they are more resilient if a leave-DAG-node is unretrivable. In MD-CRDTs an unretrievable DAG node can break DAG-traversal and with it a large portion of the state while in MST-CRDTs, this will affect only a key or a set of keys related to the missing DAG node.

In the end, for both the devil will be in implementation details: how good is your pubsub code? How good and parallelizable is your update-processing code? How good is your GC process? How good is your blockstore? All those things become performance bottlenecks even when the theoretical properties work perfectly.

I think the point is not to force decentralization, but to allow it. When the protocol is open, there are more chances to break the monopolies through innovation, quality of service etc. and avoid lock-in.

In this case, IPFS breaks the monopoly of trust (only obtaining content from a single source because that source is the reputable source for it). Content addressed data makes the source irrelevant. Many possibilities open from there (i.e. breaking the monopoly of storage).

Any chance that, by limiting RAM usage, you forced your application to heavily swap, clogging the disk and making your machine slow?

I have run a public gateway on 2GB of RAM. Later 4GB because it was subject to very heavy abuse, but it was perfectly possible. Perhaps it is a matter of knowing how to configure things and how to not inflict self-pain with wrong settings.

The content ID is not the hash of the content, it is the hash of the root of the Merkle DAG that carries the content.

Doing it like that has many advantages, like being able to verify hashes as small blocks are downloaded and not after downloading a huge file. Being able to de-duplicate data, being able to represent files, folders and any type of linked content-addressed data structure.

As long as your content is under 4MiB you can opt out of all this and have a content ID that is exactly the hash of the content.

In https://github.com/ipfs/go-ds-crdt, every node in the Merkle DAG has a "Priority" field. When adding a new head, this is set to (maximum of the priorities of the children)+1.

Thus, this priority represents the current depth (or height) of the DAG at each node. It is sort of a timestamp and you could use a timestamp, or whatever helps you sort. In the case of concurrent writes, the write with highest priority wins. If we have concurrent writes of same priority, then things are sorted by CID.

The idea here is that in general, a node that is lagging behind or not syncing would have a dag with less depth, therefore its writes would have less priority when they conflict with writes from others that have built deeper DAGs. But this is after all an implementation choice, and the fact that a DAG is deeper does not mean that the last write on a key happened "later".

DAG size gets out of hand when many operations happen (akin to how a blockchain grows indefinitely).

Nodes could however rely on some form of "consensus" to compact/reset the graph at intervals. But then you have invited a consensus into the party which is the opposite of what CRDTs want to have.