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

Design and API proposal for accountless operation #574

Closed
jrick opened this issue Dec 11, 2019 · 5 comments
Closed

Design and API proposal for accountless operation #574

jrick opened this issue Dec 11, 2019 · 5 comments

Comments

@jrick
Copy link
Member

jrick commented Dec 11, 2019

This issue describes at a high level an alternate design to #568 to solve the privacy issues associated with VSP accounts, while simultaneously removing the VSP fees from tickets themselves, making it possible for both solo and VSP stakers to purchase mixed tickets in the same anonymity set.

As a reminder, BIP0044 with Decred's coin types uses the following HD paths:

m/44'/{20,42}'/<account>'/<branch>/<child>

For this design, a new purpose key should be used, since these keys are used differently from normal wallet accounts, and handling should be logically and hierarchically separated. A new purpose key of 565350 is chosen (565350 is the UTF-8 encoding of "VSP", as hex).

For each bought ticket, a hardened key is derived. Non-hardened children are derived off this ticket key. The 0th hardened child is used as a key for voting rights in the ticket purchase, and more child keys may be derived for future uses as we need them.

Tickets will be purchased with voting rights assigned to a P2PKH address derived from the key:

m/565350'/<ticket index>'/0'

and a commitment address from one of the wallet's BIP0044 accounts.

There will be only one pair of commitment/change outputs for the ticket. Currently, VSP-bought tickets include two pairs of these outputs: one for the buyer's reward and a second to pay the VSP a fee for voting on behalf of the user. Removing these two separate outputs, and switching voting rights from a (multisig) P2SH to P2PKH has the desired effect of making these tickets have identical form as those bought by solo stakers, and VSP users will be able to participate in the same anonymity set as solo buyers when using CoinShuffle++ to create CoinJoin mixed ticket split transactions, from which tickets are bought.

Between the ticket being mined and becoming live, the user (or their client) must inform the VSP of the ticket to vote on, the private key necessary to vote, voting preferences, and pay the VSP fee. The VSP fee can be obtained via an API and should be checked prior to buying the ticket, so that an appropriate UTXO can be reserved by the wallet to pay the fee, without that output being double spent by the created split tx.

(These mock APIs loosely resemble JSON-RPC, but HTTP REST is probably more appropriate, and is already used by the existing API.)

client request:
{
	"request": "getfee"
}
server response:
{
	"fee": number
}

Once the fee rate is known and the ticket has been mined, the client must obtain an address to pay the VSP fee. For spam and DoS prevention, obtaining this address will require the client to prove they are owner of the private key to pay the output described in the ticket commitment. This requires signing a message (which should be constructed in a way that prevents the signature from being used for unintended purposes) with the commitment address' key. The VSP must check that the ticket exists and is mined in an approved block, fish the commitment address from the ticket, and verify that the signature was created from the same keypair. A fee address is only then derived and provided to the client

client request:
{
	"request": "getfeeaddress",
	"ticket": "ticket hash",
	"commitment": "signature using commitment key"
}
server response:
{
	"address": "DsExampleFeeAddress"
}

The client then creates the transaction paying the VSP fee and submits the transaction and voting private key to the server, along with voting preferences for the ticket. A timestamped receipt is returned by the server that commits to the ticket and the voting preferences. The precise details of these receipts must still be designed, but the goal is to provide cryptographic attribution that voting preferences were sent by clients and received by VSPs, in order that blame may be assigned to the VSP if voting preferences were not honored.

client: 
{
	"request": "payfee",
	"fee_tx": "serialized transaction paying fee",
	"voting_key": "...",
	"agenda_preferences": "..."
}
server:
{
	"receipt": "..."
}

One last API is needed to update voting preferences, if the user's preference changes, or new agendas become available.

client:
{
        "request": "setpreferences",
	"ticket": "ticket hash",
	"commitment": "signature using commitment key",
        "agenda_preferences": "..."
}
server:
{
        "receipt": "..."
}

Finally, to protect VSPs, clients should be accountable for each set preference. Without this accountability, malicious clients could update their voting preferences, with the VSP honoring the new changes, with malicious clients using an old receipt to accuse the VSP of voting with the wrong preferences. The most obvious solution to this problem is to use a timestamped and ordered transparent log (with either VSPs running one themselves, or publishing to a pi instance) of commitments to each client's request to set the voting preferences, and the receipt should staple this commitment so it (and its position) can be looked up.

@jrick
Copy link
Member Author

jrick commented Dec 16, 2019

I'm considering including the BIP0044 account index in the derivation path for ticket keys as well, so there is a 1:1 relation between the ticket keys and wallet accounts, for accounting purposes. Otherwise, on a seed restore, it would not be clear what tickets are for what accounts.

@raedah
Copy link

raedah commented Jan 15, 2020

also related to decred/dcrwallet#1613

@xaur
Copy link

xaur commented Feb 5, 2020

Love the introduction of receipts and timestamping to protect both clients and VSPs, it will significantly strengthen the incentives that we have now.

A few questions:

  • Is it correct that fees will be paid with regular transactions that can also be mixed?
  • Is it true that while this makes on-chain VSP and solo tickets indistinguishable, there remains an opportunity for VSPs to link users' tickets together based on IP address and HTTP headers? If so, are there any ways to remove this, besides using Tor?
  • Would it make sense to encrypt client-VSP traffic with custom encryption, or at least use self-signed certificates to not rely on CAs?
  • What shall the client do if the VSP takes the fee_tx and voting_key but does not respond with receipt, or crafts a bad receipt?

@itswisdomagain
Copy link
Member

To enable using the same seed for deriving different ticket addresses on testnet and mainnet, I'd recommend including the BIP0044 coinType, resulting in m/565350'/{20,42}'/<ticket index>'/0'.

Including the account index as suggested earlier in this thread would produce m/565350'/{20,42}'/<account>'/<ticket index>'/0'.

@jholdstock
Copy link
Member

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

5 participants