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

Privacy Precompile: enables private transactions with extended obfuscated fields #1234

Conversation

SatpalSandhu61
Copy link
Contributor

Introduction

Add support for privacy precompiled contract to orchestrate the execution of private transactions. This new approach allows extending the obfuscated fields of a private transaction.

So far data field was the only obfuscated field of a private transaction, other fields were visible from non-participants node. This new precompiled contract approach allows to obfuscate data, to, and gasLimit. In some future enhancement, we could use this same approach to obfuscate the sender address.

This introduces the concept of Privacy Marker Transactions (PMT), which is a standard public transaction sent to the privacy precompiled contract to get private transactions executed

  • to field is always be set to privacy precompiled at address 0x000000000000000000000000000000000000007a
  • data field is set to the Tessera key of the extended private transaction

When processing a PMT the privacy precompile of participant nodes executes the extended private transaction corresponding to the Tessera key in PMT data. The final execution of the private transaction is identical to the usual private transaction in particular it is the private state of participants that is mutated.

New JSON-RPC methods

  • eth_distributePrivateTransaction enables to push a private transaction payload to Tessera
  • eth_getPrivacyPrecompileAddress that returns the precompile address (so far this is fixed to 0x000000000000000000000000000000000000007a)

Configuration

  1. Add genesis field "privacyPrecompileBlock": 0, under config section which defines block number, after which privacy precompiled contract is enabled
  2. Pass CLI --privacymarker.enable flag when starting node

Transaction flow details

Private Transaction Submission

Node signing

  1. User sends the transaction to GoQuorum using eth_sendTransaction as normal in particular passing privateFor and to field set to the private contract address (or nil for contract deployment)
  2. GoQuorum prepare and signs the private transaction containing all fields
  3. GoQuorum sends signed private transaction to Tessera, which distributes the private transaction to other participants and returns the private hash
  4. GoQuorum creates the ‘Privacy Marker Transaction’ (PMT), where:
    • data is the private hash of the transaction stored in Tessera.
    • to is the privacy precompile address 0x000000000000000000000000000000000000007a
    • PMT is signed using the same account as the one used for the private transaction
  5. GoQuorum submits the PMT to the tx pool as any standard public transaction

External signing

  1. User creates and externally sign private tx as normal (with signature v modified value) particular setting privateFor and to field set to the private contract address (or nil for contract deployment)
  2. User calls eth_distributePrivateTransaction with the externally signed private transaction. On this call, GoQuorum pushes the private transaction payload to Tessera that encrypts it and returns private tx manager hash
  3. User creates and externally signs the PMT
    • data should be the private tx manager hash got on previous call to eth_distributePrivateTransaction
    • to should be the privacy precompile address 0x000000000000000000000000000000000000007a
  4. User sends the signed PMT with eth_sendRawTransaction

Transaction Processing

When executing the PMT

  1. Transaction is dispatch to the privacy precompiled contract for execution
  2. Privacy precompile reads private transaction hash from PMT data field as private hash
  3. Privacy precompile queries Tessera with private hash, if no data is found, then this node is not a participant so no further processing is needed
  4. Privacy precompile triggers the EVM execution of the private transaction using the private state as per normal private transaction

chris-j-h and others added 2 commits August 9, 2021 11:11
… extended obfuscated fields""

This reverts commit cd945b0
…xn gas value (#4)

Use intrinsicGas on privacy marker transaction, rather than private txn gas value
Copy link
Contributor

@baptiste-b-pegasys baptiste-b-pegasys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it may have an issue with mps ATs, checking that locally.

[ {
  "file" : "src/specs/01_basic/extend_private_contract.spec",
  "line" : 1,
  "col" : 1,
  "message" : "Scenario: Extend contract to a new party, creator cancels extension 1%0AStep: <fromNode> cancels <contractName>%0AConcept Execution Failure: 'org.opentest4j.AssertionFailedError: %0AExpecting:%0A <org.web3j.protocol.core.Response$Error@237a1875>%0Ato be equal to:%0A <null>%0Abut was not.'"
} ]

return tx, nil
}

type mockTransactor struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we generate that mock with an interface?

@@ -581,6 +581,10 @@ func (tx *Transaction) SetPrivate() {
}
}

func (tx *Transaction) IsPrivacyMarker() bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func (tx *Transaction) IsPrivacyMarker() bool {
func (tx *Transaction) HasPrivacyMarker() bool {

many "is privacy marker" changes, I prefer with has, or use

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't changed since the PR was originally reviewed. We don't want to make further changes at this late stage now.

return tx, nil
}

type mockTransactor struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can it be generated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't changed since the PR was originally reviewed. We don't want to make changes at this late stage.

@@ -533,7 +533,7 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth
result SignTxResponse
msgs *ValidationMessages
)
if args.IsPrivate {
if args.IsPrivate || args.isPrivacyMarker() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if args.IsPrivate || args.isPrivacyMarker() {
if args.IsPrivate || args.hasPrivacyMarker() {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't changed since the PR was originally reviewed, so we'd prefer not to make changes now.

extension/api.go Outdated Show resolved Hide resolved
internal/ethapi/api.go Show resolved Hide resolved
accounts/abi/bind/base.go Outdated Show resolved Hide resolved
@chris-j-h
Copy link
Collaborator

it may have an issue with mps ATs, checking that locally.

[ {
  "file" : "src/specs/01_basic/extend_private_contract.spec",
  "line" : 1,
  "col" : 1,
  "message" : "Scenario: Extend contract to a new party, creator cancels extension 1%0AStep: <fromNode> cancels <contractName>%0AConcept Execution Failure: 'org.opentest4j.AssertionFailedError: %0AExpecting:%0A <org.web3j.protocol.core.Response$Error@237a1875>%0Ato be equal to:%0A <null>%0Abut was not.'"
} ]

@baptiste-b-pegasys this PR requires a change to the atests - I am in the process of preparing that PR

Copy link
Contributor

@ricardolyn ricardolyn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

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

Successfully merging this pull request may close these issues.

None yet

6 participants