Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

facade/v0 package

Overview

untrusted-render: every string Render echoes is either a verb name validated by parseSchema against [a-z0-9_] at accept time, or a package path read off a crossing frame. No caller-typed payload is ever rendered.

Package facade is the permanent entry point of the "API as data" upgrade pattern (pattern G of the exploration; see ../../README.md).

Patterns E and F put a Go interface at the permanent path, which fixes the method set at deploy: adding an operation later needs a whole extra realm. This one puts a single entry point there instead,

Example
1Call(cur realm, verb, payload string) string

and moves the API into DATA that each implementation declares. The signature that can never change is that one line; everything the application does can still grow.

Three things fall out of the API being data, and they are the reason to pay the price below:

  1. Callers can ENUMERATE it. Verbs, Signature and SchemaText answer without a transaction, so a client discovers the API instead of being compiled against it.
  2. Payloads are CHECKED before the handler runs, so an arity mistake is one abort with a readable message rather than whatever the handler does with the wrong number of arguments.
  3. Upgrades can be DIFFED. Accept refuses a handler whose schema would drop or reshape a verb some existing caller depends on, which no amount of Go interface satisfaction can catch: a handler is free to satisfy Handler and answer nothing.

The price is the type system. Arguments are strings a caller encodes, and a misspelled verb is an abort at runtime rather than a compile error. Pattern F is the other side of that trade and both ship here on purpose.

State is deliberately out of scope. These handlers are pure; where an application's data should live is pattern C's question, and the answer does not change because the entry point became a string.

Functions

Accept

func Accept(cur realm, pkgPath string)

Accept promotes a candidate, and refuses one that would break an existing caller. This is the check a Go interface cannot express.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Accept" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Accept" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

AcceptBreaking

func AcceptBreaking(cur realm, pkgPath string)

AcceptBreaking promotes a candidate that Accept refuses.

It exists because the diff is SYMMETRIC, which is not obvious until it bites: once v1 has added a verb, rolling back to v0 drops that verb and is a regression by exactly the same rule that protects callers going forward. A pattern that can only move forward is worse than one with no diff at all, so the escape hatch is required, and making it a separate function is the point: the owner has to type a different word, and the audit log shows which one.

Use it to roll back, and to retire a verb nobody calls any more. Not to make an upgrade go through.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "AcceptBreaking" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "AcceptBreaking" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Call

func Call(cur realm, verbName, payload string) string

Call is the one signature this realm is committed to forever.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Call" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Call" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Candidates

func Candidates() []string

Candidates lists every path that has nominated itself, in order.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.Candidates()"

Result

Live

func Live() string

Live is the package path currently serving, or "" before the first Accept.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.Live()"

Result

Propose

func Propose(cur realm, h Handler)

Propose nominates the calling realm, exactly as in pattern F. Its schema is parsed here so a malformed one is rejected at proposal rather than at accept.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Propose" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "gnoland-1" -remote "https://rpc.gno.land" ADDRESSgnokey query -remote "https://rpc.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/moul/x/upgrade/schema/facade/v0" -func "Propose" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "gnoland-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.gno.land" call.tx
  

Render

func Render(_ string) string

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.Render()"

Result

SchemaText

func SchemaText() string

SchemaText is the whole accepted API in the declaration format, so a client can read back exactly what the handler declared.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.SchemaText()"

Result

Signature

func Signature(name string) string

Signature is one verb's shape, as a caller would write it.

Param

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.Signature()"

Result

Verbs

func Verbs() []string

Verbs lists the accepted API in DECLARATION order, which is the order the handler wrote it in and the order a reader of the schema expects. Iterating the avl tree instead would list them alphabetically, silently: caught by a test, not by a compiler.

Command

gnokey query vm/qeval -remote "https://rpc.gno.land" -data "gno.land/r/moul/x/upgrade/schema/facade/v0.Verbs()"

Result