oasisprotocol / oasis-core

Performant and Confidentiality-Preserving Smart Contracts + Blockchains
https://oasisprotocol.org
Apache License 2.0
332 stars 109 forks source link

Transaction Fee Schedule For Workers #1468

Open bennetyee opened 5 years ago

bennetyee commented 5 years ago

We need to establish mechanisms and a fee schedule to split up the gas earned from processing transactions among the compute committee nodes, storage committee nodes, root hash committee, etc, including a tax for common infrastructure (merkle tree maintenance, etc).

Details

We need to design & implement mechanisms to (flexibly) have a fee schedule. The EVM compute nodes have the gas fee schedule for EVM operations, and this could be similar; this could also be maintained as (read-mostly) data in a contract changes to which would be decided by vote by the community/foundation, though compiling in the fee schedule is more efficient. Design decisions need to be made regarding:

Linked Issues

kostko commented 5 years ago

The compute committee already has to know about the account balance location in the merkle tree

I assume you mean that it needs to know this to be able to reduce conflicts and implement CRDT semantics for certain subtrees? This is true for scalability reasons, but I don't think this is the only way to implement fee disbursement.

One other way is to update what is returned by the runtime as the "computed batch" which currently just contains the outputs, new state root and write log (this will change slightly when we implement merging but that is orthogonal).

We could add another item, signalling the amount that should be disbursed to the workers (this would of course be part of state that is checked via DD). I think this would be more explicit than extracting this information from the state data structure and assuming certain state semantics from all runtimes (again, we must design this to be more general and work with runtimes that are not runtime-ethereum).

bennetyee commented 5 years ago

Yes, I think that would work. I am worried about having to put txns into batches when they might otherwise be independent because we are not taking advantage of the commutivity of additions/subtractions -- txns that do subtractions from account balances may have to be colocated in the same batch, unless we trust the pre-execution to get the amounts to be deducted and can prove that there is never a negative excursion (or allow "temporary loans" for that).

So if disbursement -- which are purely additive and thus safe wrt negative excursions, esp since they are paid to EOAs which cannot run code on receipt -- is a separate txn output to be handled during merge fix-up, but subtraction is immediate, then all txns with the same txn.origin has to be placed into the same batch within a schedule, or be in different schedules. This might be okay -- as long as disbursements do not force batch consolidation, this could be good enough.

It would be nice to generalize this for other balance-changing operations, like send, transfer, etc. (are these all implemented via the CALL evm opcode?) This might be more complicated, since the target of the call can do BALANCE which forces the serial order to be consistent with the returned value. I need to think more about how this might work.

If no txn invokes BALANCE and we take advantage of commutivity, we still have the follow potential drawback. Users might be used to being able to put in a bunch of transactions into the pool, some of which result in their balance increasing and some in it decreasing, and expect that (most of the time) they would all go through because the additive txns are interspersed among the subtractive txns. If we separate and delay additions until the end of the schedule, however, such a mix of txns will almost surely not all complete -- the last N will revert -- due to running out of funds. If we do disbursements only for gas -- and not generalize for CALL -- then running out of funds should be less likely, but txns that result in value transfers w/ overlaps among src/dest accounts would definitely force those txns to colocate.

kostko commented 5 years ago

So one major question is - where are the accounts of the entities running the compute nodes? One possible way is to have them inside the runtime. But since compute nodes may run multiple runtimes, does this mean that they need to have accounts with each runtime in addition to being registered in our registry?

We will already have staking and staking accounts for entities/compute nodes. Can we also disburse fees that way, independent of any runtime?

kostko commented 5 years ago

Replying to myself, could we have a combination of both? (In the following text, the participants are the staked nodes.)

Care needs to be taken to prevent parallel withdrawal (conflict detection at merge and BFT committees).

kostko commented 5 years ago

An alternative design is to keep participants' gas accounts entirely within the runtime, but for that we need to introduce special semantics for updating storage state without introducing conflicts (e.g., increment and subtract operations).

lostnfound commented 5 years ago

Another alternative is

In other words, only the consensus/BFT committee updates the stake accounts, and only the Storage committee updates the runtime accounts.