Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Executing 'wallet2' objects in a "box" under control of the Seraphis wallet #48

Open
rbrunner7 opened this issue Feb 28, 2023 · 1 comment

Comments

@rbrunner7
Copy link
Member

Background

With past hardforks Monero released hardfork-ready software about 1 month before the time of the hardfork. If the format of the transactions changed, that software was able to create transaction in the old i.e. pre-hardfork format as well as in the new i.e. post-hardfork format. It had to: Otherwise you could have used that software version only from the time of the hardfork onwards, not earlier. While in theory such an approach might work, it's pretty inconvenient for users, and moreover it makes testing of the software and getting acquanted with it before the hardfork very difficult, which is bad: You really don't want to find bugs only after the hardfork happened already.

Until now usually this never was too much of a challenge, old and new transaction formats being quite similar after all: No big deal for the software to create transactions in two different formats, depending on the current blockheight.

With Seraphis this will probably turn out to be a major challenge however.

For Seraphis support there will be two brand-new internal modules of the software, called the Seraphis library and the Seraphis wallet. They can read old transactions, but cannot create them.

It looks like support for those will have to come, like for many years already, from the wallet2 class. wallet2 is a big, complicated, hard-to-understand and even harder-to-modify mass of code. The plan is to get rid of it completely as soon as possible, and put as little work as possible into it to make it ready for the Seraphis hardfork.

We could, in theory, omit wallet2 already in the very first Seraphis-capable release by extending the Seraphis library and the Seraphis wallet with code that can create old transactions. This is not a good idea however for at least two reasons: It would take time to write that code because it's not exactly trivial, and there would probably be little differences in the created transactions that would allow to "fingerprint" them. With some clever checks you would probably be able to see in the blockchain which code has produced which transactions, which is bad for privacy.

Thus we need a good approach to build a software that somehow "marries" the Seraphis modules and wallet2 in a way that is not too complicated, does not need too many modifications to the old code, and doesn't take large amounts of work hours to develop.

The idea: 'wallet2' objects in a "box"

That Seraphis wallet plus wallet2 combo that we need works like this:

The Seraphis wallet is in control of almost everything. Wallet files in the old wallet2 format are subjected to an automatic one-time conversion into the new Seraphis wallet format and are not needed nor touched anymore from that moment on: The Seraphis wallet will read and write all wallet files in its own new format.

Being able to "read", to interpret the old transaction format, it scans the pre-hardfork blockchain for incoming old transactions, or more exactly enotes, which it stores into its own wallet files.

Now, if you tell it to create an old transaction, it gets interesting. For doing so, in a first step, the Seraphis wallet creates a wallet2 object in RAM and executes it in something like a isolated "box". It wwould not instruct the object to load any wallet file - no such file is around anymore - but to basically execute a wallet restore from private keys purely in RAM. The Seraphis wallet will hand it those keys that it stores in its wallet file.

Where would the owned enotes come from that wallet2 needs to construct a transaction? Not from an old wallet file, and of course not from a full scan of the blockchain done by wallet2 either. Easy: The Seraphis wallet which manages the list of owned enotes would hand it over to the wallet2 object to populate its m_transfers vector object. That needs a new method, but only a trivial one.

Maybe a detailed investigation will turn up a few more things to configure in the wallet2 object or to hand over in this way, but that won't make a big difference: The object is now ready to create a transaction. The Seraphis wallet will take that, together with a list of enotes that will be spent if the transaction gets confirmed, to update its enote store accordingly, and submit it to the daemon it is connected to. This only neads a reasonable extension to an already existing method.

For building a transaction, enotes are needed as decoys for forming the rings. Executing inside its "box", will the wallet2 object fetch those enotes itself from the daemon, as it always did so far? Maybe, maybe not. Maybe the Seraphis wallet will "inject" a Daemon connection object to use into wallet2 that is based on its own daemon connection infrastructure.

The idea is, to keep things simple and crystall-clear, to use an only slightly modified wallet2 for nothing else than working inside such transaction creation "boxes" by the Seraphis wallet. All wallet apps like the CLI wallet or the GUI wallet, third-party wallet apps, and software like the RPC server, would already use the Seraphis wallet API exclusively.

Some details are still to be worked out. For example maybe it's too slow to construct a new wallet2 wallet object for each new transaction, and the Seraphis wallet will have to "recycle" a single one.

But all in all I claim that this idea could work and hopefully only needs a reasonable amount of work to realize.

@j-berman
Copy link

j-berman commented Mar 1, 2023

The Seraphis wallet which manages the list of owned enotes would hand it over to the wallet2 object to populate its m_transfers vector object. That needs a new method, but only a trivial one.

I think something along these lines would be doable too. I like this idea.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants