-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Add design proposal for generalized ownership #3216
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't give much feedback on this yet. Need more context on the problem being solved. If it's solving the problem that I think it's solving, I'm surprised not to see monoids mentioned in the proposed solution. Seems like this should be a debate between monoids and semigroups and how a program should expose that functionality to accounts that it is the owner of.
I'd think this proposal can take the form:
Runtime doesn't allow parallel access to "credits" on userdata, because it doesn't know what it means to be a credit on an otherwise opaque data type. To define a credit, we propose programs optionally implement a semigroup interface for accounts it owns. Going one step further, the runtime can also create and initialize these accounts if an identity operation is defined. When used in conjunction, the identity and semigroup operations form a monoid, opening the door for additional runtime optimizations such as the popular MapReduce.
book/src/generalized-ownership.md
Outdated
This design describes generalized ownership of countable items on the Solana | ||
blockchain. The goal of this design is to propose a single general-purpose | ||
program whose state can be used across many different programs to implement | ||
ownership, transfer and programmatic assignment. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
programmatic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assignment based on the output of a program? What should you call it?
book/src/generalized-ownership.md
Outdated
program whose state can be used across many different programs to implement | ||
ownership, transfer and programmatic assignment. | ||
|
||
Many programs in Solana should be able to use a common program similar to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"use a common program" -> "define an instruction"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@garious not really define, how about: "reuse the same code and state machine"
enum OwnerState { | ||
// the owner identity must provide a valid signature for this pubkey | ||
Unique { | ||
// The actual owner key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"actual owner" is a strange thing to say. Smells of a terminology problem. Is there a "not-actual owner" that's hijacked the term "owner"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Account has an owner, which is the program. Signer, which is the thing that owns the some keypair. The owner of the state which stores these bits, which is irrelevant here. How about token_owner
, or unit_owner
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't help specialize vague terminology. I asked because I can't tell what you're referring to. I need you to spend some time either thinking on the terminology and defining it earlier in this document, or spend more time clarifying the problem statement and have others propose solutions.
### OwnerState::Transfer | ||
|
||
* account[0] - RW - The OwnerState. | ||
* account[1] - R - Current owner Pubkey, needs a signature. Doesn’t need an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A credit-only account needs a signature?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, it just needs to show proof of owning the identity. Kind of interesting, since this account doesn’t need an actual balance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I'd accept tokens from anybody giving tokens out - my signature is not required.
@garious, want to work on this together? It would be nice to split this up into a semi group and a monoid. |
@aeyakovenko, I'd prefer not to work on this until you create an GitHub issue that describes the problem in detail, such that we can prioritize it. It's likely that I'll want to write a design proposal of my own and maybe implement it too. The MapReduce possibility is something that we've been talking about since the earliest days of the project. |
093730f
to
983215b
Compare
983215b
to
a7c3a51
Compare
@garious let’s move this forward. Dealing with external settlement depends on this. |
@aeyakovenko, can you explain how dealing with external settlement depends on this? |
@garious the example in the doc discusses how two external assets get traded by an exchange program. The alternative is a single non-generalized exchange that only understands the tokens and external assets it was initially programmed with. |
@aeyakovenko, I wonder if the fundamental problem here is in the Token program. It decides what to do based on data in let transfer_ix = token::transfer(42, &carol_id, &dan_id);
let message = Message::new(vec![
ttt_instruction::move(&alice_id, &game_id, 2, 2),
system_instruction::create_account(&gambling_greg_id, size_of(transfer_tx)),
tttanalyst_instruction::when_winner(&gambling_greg_id, &game_id, IS_X, transfer_ix),
token_instruction::load_instruction_from_account(&gambling_greg_id),
]);
client.send_message(&[&alice_keypair, &gambling_greg_keypair, &carol_keypair]); |
@garious, it needs to lock the tokens from transfer while their are in play. In the design it’s covered as OwnerState::Escrow |
In fact, that last instruction can be generalized for all programs if recognized by the runtime: system_instruction::load_instruction_from_account(TOKEN_PROGRAM_ID, &gambling_greg_id) |
@garious, ah I see. You are looking at the output of the previous instruction. You can do that with atomics. Configure the token program to payout the result based if an instruction is called with the right keys in the same TX. it doesn’t even need to look at the state, just Succeed. That doesn’t compose. The token program needs to have those hooks. Everyone implementing a token must add them, since it’s sync for that state transition. I can’t add additional tokens and gamble them in tic-tac-toe against other token programs. |
@garious I don’t see where the chain enforces that the transfer occurs if and only if the winner won |
@aeyakovenko, yes, that's not obvious. It'd be implemented by this line: tttanalyst_instruction::when_winner(&gambling_greg_id, &game_id, IS_X, transfer_ix) What it's saying is that the analyst is analyzing the |
The big limitation in my example is the lack of an escrow account. What's awkward there is that the escrow account would be owned by the Your suggestion of a predicate language in |
@garious think there are two ways,
or
|
I don't understand what you're saying there ^^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not optimistic that I'm going to grok this proposal if only incrementally moved forward in response to my review comments. I think this will either require another brain or a rewrite. If a rewrite, I'd suggest way more content in the problem description and less code in the proposed solution.
The goal of this design is to make the following possible: | ||
|
||
In a single program, it should be possible to change and update ownership of | ||
arbitrary units of tokens implemented by other programs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sentence is unclear - specifically "ownership" and "arbitrary units".
|
||
## General idea | ||
|
||
For items to have externally countable ownership, they must rely on the external |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like the first use of "externally countable ownership". What does it mean?
|
||
## General idea | ||
|
||
For items to have externally countable ownership, they must rely on the external |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by "items" and "units" exactly?
## Generalized owner identity | ||
|
||
Using the account's pubkey identity as the asset owner identity means that all | ||
the asset transfer APIs must be re-implemented by the program code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks like an overreaching assertion.
Using the account's pubkey identity as the asset owner identity means that all | ||
the asset transfer APIs must be re-implemented by the program code. | ||
|
||
The proposed solution is to use a pointer to an owner identity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is using ambiguous terminology.
```rust,ignore | ||
// This state is owned by the MyTokenState | ||
struct MyTokenState { | ||
// This points to an OwnerState structure that identifies the actual owner |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actual owner
|
||
## Programmatic Transfer of Ownership | ||
|
||
Currently, programs have no way to trigger a transfer of ownership. A game of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trigger?
## Programmatic Transfer of Ownership | ||
|
||
Currently, programs have no way to trigger a transfer of ownership. A game of | ||
TicTacToe has no way to assign a prize to the winner. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assign or award?
|
||
```rust,ignore | ||
// This state is owned by the Owner program | ||
enum OwnerState { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another definition of OwnerState? Are these progressively more advanced definitions? Perhaps this was all the same OwnerState definition and each field was introduced as a full OwnerState definition?
An offer to trade: | ||
|
||
```rust,ignore | ||
Trade { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is Trade defined?
// This state is owned by the MyTokenState | ||
struct MyTokenState { | ||
// This points to an OwnerState structure that identifies the actual owner | ||
owner: Pubkey, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is a pointer to the OwnerState needed in this struct?
I am going to split this out into two problems.
|
@aeyakovenko, can this be closed in favor of #4603? |
@garious want to file another Issue that captures the problem of delegating scarcity to a Token program? And a way to delegate transfer of ownership to other programs from within the Token program? |
@aeyakovenko, in that model, you don't delegate. It's permissionless. You'd spin up a token to represent some other set of tokens, and then stake and trade with the new token. How about tickets for demos of various usecases you propose? I'm working towards betting on tic-tac-toe outcome with a Token. After that, the other example you give here, of swapping two Tokens. Looking for others? |
@aeyakovenko, sounds like your solution must be addressing more problems than what you've provided. You mentioned splitting this proposal into two earlier. Sounds like we'll need that sooner than later. If so, can you do that with issues instead of PRs? |
@aeyakovenko, this PR is very old and hasn't gotten traction. Can we close it for now? |
@garious closed. We are moving too slowly for general purpose tokens. Maybe stakes will be the first consumer. |
* SVM: use lps from `FeeStructure` directly * SVM: rename `lamports_per_signature` to `blockhash_lamports_per_signature` * program-runtime: rename `lamports_per_signature` to `blockhash_lamports_per_signature`
Problem
Current implementations of ownership rely on account pubkeys, which cannot be composed across programs.
How these problems manifest in Ethereum. https://medium.com/@kelvinfichter/looking-at-ownership-in-the-evm-6e6914d341d
Summary of Changes
Propose a design for general ownership of countable things, with a mechanism to programatically transfer the ownership based on output from other programs.
CC #3266