-
Notifications
You must be signed in to change notification settings - Fork 116
Add describe-guard primitive #851
base: master
Are you sure you want to change the base?
Changes from 1 commit
767b7d0
c305913
1e7acdf
48539c9
9feea04
7051b5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| {-# LANGUAGE OverloadedStrings #-} | ||
| {-# LANGUAGE ScopedTypeVariables #-} | ||
|
|
||
| -- | | ||
| -- Module : Pact.Native.Keysets | ||
|
|
@@ -13,10 +14,12 @@ module Pact.Native.Keysets where | |
|
|
||
| import Control.Lens | ||
|
|
||
| import Data.Default | ||
| import Data.Text (Text) | ||
|
|
||
| import Pact.Eval | ||
| import Pact.Native.Internal | ||
| import Pact.Types.Pretty | ||
| import Pact.Types.Purity | ||
| import Pact.Types.Runtime | ||
|
|
||
|
|
@@ -49,6 +52,10 @@ keyDefs = | |
| "Define keyset as NAME with KEYSET, or if unspecified, read NAME from message payload as keyset, \ | ||
| \similarly to 'read-keyset'. \ | ||
| \If keyset NAME already exists, keyset will be enforced before updating to new value." | ||
| ,setTopLevelOnly $ defGasRNative "describe-keyset" descKeySet | ||
| (funType tTyObjectAny [("keyset",tTyString)]) [] "Get metadata for KEYSET." | ||
| ,setTopLevelOnly $ defGasRNative "describe-guard" descGuard | ||
| (funType tTyObjectAny [("keyset",tTyString)]) [] "Get metadata for KEYSET." | ||
|
mightybyte marked this conversation as resolved.
Outdated
|
||
| ,enforceGuardDef "enforce-keyset" | ||
| ,defKeyPred KeysAll (==) | ||
| ["(keys-all 3 3)"] "Keyset predicate function to match all keys in keyset." | ||
|
|
@@ -82,6 +89,43 @@ defineKeyset g0 fi as = case as of | |
| runSysOnly $ enforceKeySet i (Just ksn) oldKs | ||
| writeRow i Write KeySets ksn ks & success "Keyset defined" | ||
|
|
||
| descKeySet :: GasRNativeFun e | ||
| descKeySet g i [TLitString t] = do | ||
| r <- readRow (_faInfo i) KeySets (KeySetName t) | ||
| case r of | ||
| Just v -> computeGas' g i (GPostRead (ReadKeySet (KeySetName t) v)) $ | ||
| return $ toTerm v | ||
| Nothing -> evalError' i $ "Keyset not found: " <> pretty t | ||
| descKeySet _ i as = argsError i as | ||
|
|
||
| descGuard :: GasRNativeFun e | ||
| descGuard gas i [TGuard g _] = do | ||
| case g of | ||
| GKeySet ks -> | ||
| computeGas' gas i (GUserApp Defun) $ | ||
| return $ toTObject TyAny def | ||
| [ ("type", tStr "KeySet") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How should we handle type-specific metadata? I'm guessing we should only have
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The main motivating purpose for this was providing information to apps / wallets / etc about what keys they should sign with. So the big thing my immediate use case wants from this is public keys. Beyond that I really don't know. Probably the most important criteria is that any changes we make down the road can be done in a backwards-compatible manner.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess one other high level question is whether we should put the case-specific data at the same level or if we should make some kind of generic object wrapper to make it easier to decode.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That was what I was trying to suggest with |
||
| , ("keyset", toTerm ks) | ||
| ] | ||
| GKeySetRef (KeySetName t) -> do | ||
| r <- readRow (_faInfo i) KeySets (KeySetName t) | ||
| case r of | ||
| Just v -> computeGas' gas i (GPostRead (ReadKeySet (KeySetName t) v)) $ | ||
| return $ toTObject TyAny def | ||
| [ ("type", tStr "KeySetRef") | ||
| , ("keyset", toTerm v) | ||
|
mightybyte marked this conversation as resolved.
Outdated
|
||
| ] | ||
| Nothing -> evalError' i $ "Keyset not found: " <> pretty t | ||
|
|
||
| --descKeySet gas i [TLiteral (LString t) info] | ||
| GPact _ -> computeGas' gas i (GUserApp Defun) $ | ||
| return $ toTObject TyAny def [ ("type", tStr "Pact") ] | ||
|
mightybyte marked this conversation as resolved.
Outdated
|
||
| GModule _ -> computeGas' gas i (GUserApp Defun) $ | ||
| return $ toTObject TyAny def [ ("type", tStr "Module") ] | ||
|
mightybyte marked this conversation as resolved.
Outdated
|
||
| GUser _ -> computeGas' gas i (GUserApp Defun) $ | ||
| return $ toTObject TyAny def [ ("type", tStr "User") ] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK this is where it gets interesting. First, it should have (Note that all of these (including other types) should probably try to stay consistent with JSON field names. This is maybe why a Second: wasn't it a motivation to show all keysets? This is where we might be able to traverse the guard structure. Let's look at the JSON of a gas station with a key: So, first, it might be nice to try to pretty-print in a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sounds promising! I'm also thinking about the scenario where maybe you have a smart wallet that allows different keysets in different situations. Is there a way the smart wallet module could somehow expose what keys it's accepting? I'm imagining situations where it's not necessarily static. For instance, maybe you have a smart wallet designed to make funds available to beneficiaries on the event of death or loss of owner's keys. In this situation you might have a time delay. If it's been less than a year since the last transaction, only allow the owner's key. Otherwise allow some multi-sig of social recovery with maybe a family member plus an attorney or something. |
||
| descGuard _ i as = argsError i as | ||
|
|
||
| keyPred :: (Integer -> Integer -> Bool) -> RNativeFun e | ||
| keyPred predfun _ [TLitInteger count,TLitInteger matched] = | ||
| return $ toTerm (predfun count matched) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.