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

Add skeleton for Noto/Zeto domainapi tests #73

Merged
merged 78 commits into from
Aug 29, 2024
Merged

Conversation

awrichar
Copy link
Contributor

@awrichar awrichar commented Aug 8, 2024

Builds on #59, #67, #78, #83 to wire up basic Noto and Zeto contracts to the domainapi testbed.

Test infra

Starts an instance of the kata testbed and loads a domain into it. Relies on the Besu Docker from testinfra.

Noto

  • Loads a Noto domain implementation into the domainapi testbed
  • Exercises the domain by pushing JSON-RPC commands through the domainapi testbed
    • Deploy bytecode for factory contract
    • Initialize domain
    • Use factory to deploy an instance of a Noto contract
    • Invoke various "mint" and "transfer" methods of Noto

Includes two variants of Noto to illustrate domain customizability:

  • The normal "Noto" variant
    • Any party can initiate a transfer
    • Transaction sender provides an EIP-712 signature on the transaction inputs
    • Notary verifies the signature, and notary submits all transactions to the base ledger
  • A variant called "NotoSelfSubmit"
    • Any party can initiate a transfer
    • Notary provides an EIP-712 signature on the assembled transaction
    • Transaction sender submits the transaction to the base ledger themself (including the notary's signature)
    • Base ledger verifies the notary signature

Zeto

  • Loads a Zeto domain implementation into the domainapi testbed
  • Exercises the domain by pushing JSON-RPC commands through the domainapi testbed
    • Deploy bytecode for factory contract
    • Initialize domain
    • Use factory to deploy an instance of a Zeto contract
    • Invoke "mint" method of Zeto
    • Generate ZKPs and invoke "transfer" method of Zeto

Currently uses the zeto_anon contract only, as the simplest available example for Zeto.

@awrichar awrichar self-assigned this Aug 9, 2024
@awrichar awrichar force-pushed the domainapi-noto branch 5 times, most recently from 7272a76 to 7d86e5a Compare August 14, 2024 17:43
@awrichar awrichar mentioned this pull request Aug 14, 2024
@awrichar awrichar force-pushed the domainapi-noto branch 2 times, most recently from 1d412f2 to bcf14e0 Compare August 16, 2024 20:40
Base automatically changed from domainapi to main August 16, 2024 20:44
@awrichar awrichar force-pushed the domainapi-noto branch 10 times, most recently from 4c46096 to 2cca8ee Compare August 19, 2024 19:43
Comment on lines +138 to +172
// This should have been spent
// TODO: why does it still exist?
assert.Equal(t, int64(100), coins[0].Amount.Int64())
assert.Equal(t, notaryName, coins[0].Owner)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

One of the more significant TODOs - I haven't figured out how to reliably test spending of coins.

Copy link
Contributor

Choose a reason for hiding this comment

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

yes 👍 - I've deferred this, and hopefully will have got back to it and sorted it for Pente before you're back from vacation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Finally closed the loop on this in #183

domains/noto/build.gradle Outdated Show resolved Hide resolved
@awrichar awrichar force-pushed the domainapi-noto branch 2 times, most recently from 3f77f2d to 95118f6 Compare August 21, 2024 19:57
for {
// Simple oldest coin first algorithm
// TODO: make this configurable
// TODO: why is filters.QueryJSON not a public interface?
Copy link
Contributor

Choose a reason for hiding this comment

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

It certainly should be. I've done some work to try and make it more friendly than it was in the past.

Copy link
Contributor

Choose a reason for hiding this comment

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

It should be in toolkit_go (not kata)

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 is in flight in #115 - I'll follow and integrate when ready.

}, nil
}

func (n *Noto) prepareInputs(ctx context.Context, owner string, amount *ethtypes.HexInteger) ([]*NotoCoin, []*pb.StateRef, *big.Int, error) {
Copy link
Contributor

@peterbroadhurst peterbroadhurst Aug 29, 2024

Choose a reason for hiding this comment

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

A bit of an aside - I think this is where the "domain configuration" really makes sense to have detailed options, vs. the on-chain configuration that's recorded into the smart contract.

How "I" do coin selection, is my configuration, for my node, on how I want to use my coins. Optimize for fewer coins, optimize for parallelism etc... that's my business. If I have different configuration to other nodes in the decentralized network, cool.

Whereas elsewhere in the Noto code right now, I see it (domain configuration) used more for the "how do I configure my off-chain stack, to correctly work with the on-chain instance of the smart contract". As I've gone through this PR, I'm feeling more and more convinced everything needed to know that should be baked into config (bit flags, strings, numbers, whatever) in the on-chain smart contract deployment event.

Copy link
Contributor

Choose a reason for hiding this comment

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

Proposal in code in #110 for Pente


func (n *Noto) prepareOutputs(owner string, amount *ethtypes.HexInteger) ([]*NotoCoin, []*pb.NewState, error) {
// Always produce a single coin for the entire output amount
// TODO: make this configurable
Copy link
Contributor

Choose a reason for hiding this comment

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

😄 - guess my above comment would have made more sense on this line

Copy link
Contributor

Choose a reason for hiding this comment

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

Again need to get rid of all these copies of this

Copy link
Contributor

@peterbroadhurst peterbroadhurst Aug 29, 2024

Choose a reason for hiding this comment

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

going to raise a specific issue for this

Realize I need to get further with Pente before I really have a strong enough opinion on what right looks like, to write it as an issue

kata/build.gradle Outdated Show resolved Hide resolved
Signed-off-by: Peter Broadhurst <[email protected]>
…into domainapi-noto

Signed-off-by: Peter Broadhurst <[email protected]>
@@ -18,6 +18,6 @@ interface IPaladinContract_V0 {

// TODO: Reconcile if we need this standard function or not - or if domain off-chain code
// can simply construct the transactions directly
function paladinExecute_V0(bytes32 txId, bytes32 fnSelector, bytes calldata payload) external;
// function paladinExecute_V0(bytes32 txId, bytes32 fnSelector, bytes calldata payload) external;
Copy link
Contributor

Choose a reason for hiding this comment

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

We really need to come back to this as a group - hopefully before the end of next week

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_unspent[outputs[i]] = true;
}

emit UTXOTransfer(inputs, outputs, data);
Copy link
Contributor

Choose a reason for hiding this comment

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

To your earlier point @awrichar we need to work through if this is a standardized thing, or a Domain responsibility.

I'm currently of the mind it's the former. However, as mentioned earlier that needs me to do more thinking in Pente.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

* @param inputs Array of zero or more outputs of a previous function call against this
* contract that have not yet been spent, and the signer is authorized to spend.
* @param outputs Array of zero or more new outputs to generate, for future transactions to spend.
* @param data Any additional transaction data (opaque to the blockchain)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to be clear on the importance of this field. The optimistic model for security is that the format of this data should be such, that anyone with a copy of the unmasked inputs/outputs and a copy of the Noto Go code for reference can validate:

  • Someone with authority to request this transaction (the "sender", but definitely not the msg.sender) has signed on the exact coins that will be spent, and the exact coins that will be produced
  • The notary (by submitting this transaction, or through this data field) provided an endorsement that the rules of the token were fully adhered to in the transaction

There is a special case (maybe some mint scenarios as demonstrated in the current state of Noto) where the "notary" and the "sender" roles might be signing using the same key, but I don't think that special case is something we need to optimize for as it's not the high throughput case (and it's a confusing case)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tweaked Noto slightly in #129 to include signature in more of the inputs and events - in order to satisfy "Someone with authority to request this transaction has signed on the exact coins that will be spent, and the exact coins that will be produced".

There's an unanswered question about how "standard" the spending events are across Paladin domains, and the split between specific things like signature vs a generic data payload. Need to come back to this in follow-ups.

Signed-off-by: Jim Zhang <[email protected]>
Copy link
Contributor

@peterbroadhurst peterbroadhurst left a comment

Choose a reason for hiding this comment

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

This PR is a great step forwards @awrichar

I have made many comments, all of which I think are important for consideration as the work on Noto and Zeto continues.

I have spent much more time in Noto than Zeto, as @jimthematrix is actively working on the Zeto codebase on top of this branch, as is the specialist there.

I've also spent more time in the off-chain code, than the on-chain code - again deferring to @jimthematrix on the semantics, but there are a couple of architectural comments I've made on the relationship between the on-chain and off-chain.

None of my comments block the merging of this PR though, so definitely ✅ from me!

@jimthematrix is working on a build issue around circom to let this merge.

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.

3 participants