Skip to content

Commit

Permalink
Persistence (gnolang#36)
Browse files Browse the repository at this point in the history
Object Value and Type Persistence.
Node persistence is simulated with the preprocessing of all files upon app restart.
  • Loading branch information
jaekwon authored Nov 16, 2021
1 parent c0fcd1d commit 9cc61b0
Show file tree
Hide file tree
Showing 63 changed files with 4,327 additions and 2,075 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ test:
go test
go test tests/*.go -v -test.short

testrealm:
echo "Running tests"
go test
go test tests/*.go -v -run "TestFiles/^zrealm"

test2:
# -p 1 shows test failures as they come
# maybe another way to do this?
Expand Down
37 changes: 4 additions & 33 deletions cmd/gnokey/gnokeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"

"github.com/gnolang/gno"
"github.com/gnolang/gno/pkgs/amino"
"github.com/gnolang/gno/pkgs/command"
"github.com/gnolang/gno/pkgs/crypto/keys"
Expand Down Expand Up @@ -125,35 +124,8 @@ func makeAddPackageTxApp(cmd *command.Command, args []string, iopts interface{})
panic(err)
}

// read all files.
dir, err := os.Open(opts.PkgDir)
if err != nil {
panic(err)
}
defer dir.Close()
entries, err := dir.Readdir(0)
if err != nil {
panic(err)
}

// For each file in the directory, filter by pattern
namedfiles := []vm.NamedFile{}
for _, entry := range entries {
name := entry.Name()
if strings.HasSuffix(name, ".go") {
fpath := filepath.Join(
opts.PkgDir, name)
body, err := os.ReadFile(fpath)
if err != nil {
return errors.Wrap(err, "reading gno file")
}
namedfiles = append(namedfiles,
vm.NamedFile{
Name: name,
Body: string(body),
})
}
}
// open files in directory as MemPackage.
memPkg := gno.ReadMemPackage(opts.PkgDir, opts.PkgPath)

// parse gas wanted & fee.
gaswanted := opts.GasWanted
Expand All @@ -164,8 +136,7 @@ func makeAddPackageTxApp(cmd *command.Command, args []string, iopts interface{})
// construct msg & tx and marshal.
msg := vm.MsgAddPackage{
Creator: creator,
PkgPath: opts.PkgPath,
Files: namedfiles,
Package: memPkg,
Deposit: deposit,
}
tx := std.Tx{
Expand Down
3 changes: 1 addition & 2 deletions cmd/gnoland/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ func makeGenesisDoc(pvPub crypto.PubKey) *bft.GenesisDoc {
}
gen.AppState = gnoland.GnoGenesisState{
Balances: []string{
"g1luefaaj8sasunh3knlpr37wf0zlccz8n8ev2je=1000000gnot",
"g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l=1000000gnot",
"g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5=1000000gnot",
},
}
return gen
Expand Down
135 changes: 135 additions & 0 deletions examples/gno.land/p/bank/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package bank

// NOTE: unexposed struct for security.
type order struct {
from Address
to Address
amount Coins
processed bool
}

// NOTE: unexposed methods for security.
func (ch *order) string() string {
return "TODO"
}

// Wraps the internal *order for external use.
type Order struct {
*order
}

// XXX only exposed for demonstration. TODO unexpose, make full demo.
func NewOrder(from Address, to Address, amount Coins) Order {
return Order{
order: &order{
from: from,
to: to,
amount: amount,
},
}
}

// Panics if error, or already processed.
func (o Order) Execute() {
if o.order.processed {
panic("order already processed")
}
o.order.processed = true
// TODO implemement.
}

func (o Order) IsZero() bool {
return o.order == nil
}

func (o Order) From() Address {
return o.order.from
}

func (o Order) To() Address {
return o.order.to
}

func (o Order) Amount() Coins {
return o.order.amount
}

func (o Order) Processed() bool {
return o.order.processed
}

//----------------------------------------
// Escrow

type EscrowTerms struct {
PartyA Address
PartyB Address
AmountA Coins
AmountB Coins
}

type EscrowContract struct {
EscrowTerms
OrderA Order
OrderB Order
}

func CreateEscrow(terms EscrowTerms) *EscrowContract {
return &EscrowContract{
EscrowTerms: terms,
}
}

func (esc *EscrowContract) SetOrderA(order Order) {
if !esc.OrderA.IsZero() {
panic("order-a already set")
}
if esc.EscrowTerms.PartyA != order.From() {
panic("invalid order-a:from mismatch")
}
if esc.EscrowTerms.PartyB != order.To() {
panic("invalid order-a:to mismatch")
}
if esc.EscrowTerms.AmountA != order.Amount() {
panic("invalid order-a amount")
}
esc.OrderA = order
}

func (esc *EscrowContract) SetOrderB(order Order) {
if !esc.OrderB.IsZero() {
panic("order-b already set")
}
if esc.EscrowTerms.PartyB != order.From() {
panic("invalid order-b:from mismatch")
}
if esc.EscrowTerms.PartyA != order.To() {
panic("invalid order-b:to mismatch")
}
if esc.EscrowTerms.AmountB != order.Amount() {
panic("invalid order-b amount")
}
esc.OrderA = order
}

func (esc *EscrowContract) Execute() {
if esc.OrderA.IsZero() {
panic("order-a not yet set")
}
if esc.OrderB.IsZero() {
panic("order-b not yet set")
}
// NOTE: succeeds atomically.
esc.OrderA.Execute()
esc.OrderB.Execute()
}

//----------------------------------------
// TODO: actually implement these in std package.

type Address string
type Coins []Coin
type Coin struct {
Denom bool
Amount int64
}
50 changes: 31 additions & 19 deletions examples/gno.land/r/example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,49 @@ The smart contract files that were uploaded to make this
possible can be found here:
https://github.com/gnolang/gno/tree/master/examples/gno.land

## sign an addpkg (add avl package) transaction.
## add test account

> make
> ./build/gnokey add test1 --recover
Use this mnemonic:
> source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast
## start gnoland validator.

> ./build/gnoland
(This can be reset with `make reset`).

## sign an addpkg (add avl package) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/avl" --pkgdir "examples/gno.land/p/avl" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.avl.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpkg.avl.unsigned.txt --chainid "testchain" --number 1 --sequence 0 > addpkg.avl.signed.txt
./build/gnokey broadcast addpkg.avl.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/avl" --pkgdir "examples/gno.land/p/avl" --deposit 100gnot --gas-fee 1gnot --gas-wanted 2000000 > addpkg.avl.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpkg.avl.unsigned.txt --chainid "testchain" --number 0 --sequence 0 > addpkg.avl.signed.txt
> ./build/gnokey broadcast addpkg.avl.signed.txt
## sign an addpkg (add dom package) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/dom" --pkgdir "examples/gno.land/p/dom" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.dom.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpkg.dom.unsigned.txt --chainid "testchain" --number 1 --sequence 1 > addpkg.dom.signed.txt
./build/gnokey broadcast addpkg.dom.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/dom" --pkgdir "examples/gno.land/p/dom" --deposit 100gnot --gas-fee 1gnot --gas-wanted 2000000 > addpkg.dom.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpkg.dom.unsigned.txt --chainid "testchain" --number 0 --sequence 1 > addpkg.dom.signed.txt
> ./build/gnokey broadcast addpkg.dom.signed.txt
## sign an addpkg (add example realm) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/r/example" --pkgdir "examples/gno.land/r/example" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addrealm.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addrealm.unsigned.txt --chainid "testchain" --number 1 --sequence 2 > addrealm.signed.txt
./build/gnokey broadcast addrealm.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/r/example" --pkgdir "examples/gno.land/r/example" --deposit 100gnot --gas-fee 1gnot --gas-wanted 2000000 > addrealm.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addrealm.unsigned.txt --chainid "testchain" --number 0 --sequence 2 > addrealm.signed.txt
> ./build/gnokey broadcast addrealm.signed.txt
## sign a exec (statement execution) transaction.

./build/gnokey maketx exec test1 --pkgpath "gno.land/r/example" --stmtfile "examples/gno.land/r/example/firstpost.gno" --gas-fee 1gnot --gas-wanted 200000 > addpage.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpage.unsigned.txt --chainid "testchain" --number 1 --sequence 3 > addpage.signed.txt
./build/gnokey broadcast addpage.signed.txt
> ./build/gnokey maketx exec test1 --pkgpath "gno.land/r/example" --stmtfile "examples/gno.land/r/example/firstpost.gno" --gas-fee 1gnot --gas-wanted 2000000 > addpage.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpage.unsigned.txt --chainid "testchain" --number 0 --sequence 3 > addpage.signed.txt
> ./build/gnokey broadcast addpage.signed.txt
## render page with ABCI query (evalquery).

./build/gnokey query "vm/qeval" --data "gno.land/r/example
Render()"
> ./build/gnokey query "vm/qeval" --data "gno.land/r/example
> Render()"
44 changes: 25 additions & 19 deletions examples/gno.land/r/example/firstpost.gno
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,44 @@ The smart contract files that were uploaded to make this
possible can be found here:
https://github.com/gnolang/gno/tree/master/examples/gno.land

## sign an addpkg (add avl package) transaction.
## add test account

> make
> ./build/gnokey add test1 --recover

Use this mnemonic:
> source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast

## sign an addpkg (add avl package) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/avl" --pkgdir "examples/gno.land/p/avl" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.avl.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpkg.avl.unsigned.txt --chainid "testchain" --number 1 --sequence 0 > addpkg.avl.signed.txt
./build/gnokey broadcast addpkg.avl.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/avl" --pkgdir "examples/gno.land/p/avl" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.avl.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpkg.avl.unsigned.txt --chainid "testchain" --number 1 --sequence 0 > addpkg.avl.signed.txt
> ./build/gnokey broadcast addpkg.avl.signed.txt

## sign an addpkg (add dom package) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/dom" --pkgdir "examples/gno.land/p/dom" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.dom.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpkg.dom.unsigned.txt --chainid "testchain" --number 1 --sequence 1 > addpkg.dom.signed.txt
./build/gnokey broadcast addpkg.dom.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/p/dom" --pkgdir "examples/gno.land/p/dom" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addpkg.dom.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpkg.dom.unsigned.txt --chainid "testchain" --number 1 --sequence 1 > addpkg.dom.signed.txt
> ./build/gnokey broadcast addpkg.dom.signed.txt

## sign an addpkg (add example realm) transaction.

./build/gnokey maketx addpkg test1 --pkgpath "gno.land/r/example" --pkgdir "examples/gno.land/r/example" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addrealm.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addrealm.unsigned.txt --chainid "testchain" --number 1 --sequence 2 > addrealm.signed.txt
./build/gnokey broadcast addrealm.signed.txt
> ./build/gnokey maketx addpkg test1 --pkgpath "gno.land/r/example" --pkgdir "examples/gno.land/r/example" --deposit 100gnot --gas-fee 1gnot --gas-wanted 200000 > addrealm.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addrealm.unsigned.txt --chainid "testchain" --number 1 --sequence 2 > addrealm.signed.txt
> ./build/gnokey broadcast addrealm.signed.txt

## sign a exec (statement execution) transaction.

./build/gnokey maketx exec test1 --pkgpath "gno.land/r/example" --stmtfile "examples/gno.land/r/example/firstpost.gno" --gas-fee 1gnot --gas-wanted 200000 > addpage.unsigned.txt
./build/gnokey query "auth/accounts/g17d0j59qka0d2vtp4l78w0c59uy34cwsdpfvk5l"
./build/gnokey sign test1 --txpath addpage.unsigned.txt --chainid "testchain" --number 1 --sequence 3 > addpage.signed.txt
./build/gnokey broadcast addpage.signed.txt
> ./build/gnokey maketx exec test1 --pkgpath "gno.land/r/example" --stmtfile "examples/gno.land/r/example/firstpost.gno" --gas-fee 1gnot --gas-wanted 200000 > addpage.unsigned.txt
> ./build/gnokey query "auth/accounts/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5"
> ./build/gnokey sign test1 --txpath addpage.unsigned.txt --chainid "testchain" --number 1 --sequence 3 > addpage.signed.txt
> ./build/gnokey broadcast addpage.signed.txt

## render page with ABCI query (evalquery).

./build/gnokey query "vm/qeval" --data "gno.land/r/example
Render()"
> ./build/gnokey query "vm/qeval" --data "gno.land/r/example
> Render()"
`)
7 changes: 5 additions & 2 deletions gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/gnolang/gno/pkgs/sdk/vm"
"github.com/gnolang/gno/pkgs/std"
"github.com/gnolang/gno/pkgs/store"
"github.com/gnolang/gno/pkgs/store/dbadapter"
"github.com/gnolang/gno/pkgs/store/iavl"
)

Expand All @@ -23,19 +24,21 @@ func NewApp(rootDir string, logger log.Logger) (abci.Application, error) {
// Get main DB.
db := dbm.NewDB("gnolang", dbm.GoLevelDBBackend, filepath.Join(rootDir, "data"))

// Capabilities key to access the main Store.
// Capabilities keys.
mainKey := store.NewStoreKey(sdk.MainStoreKey)
baseKey := store.NewStoreKey("base")

// Create BaseApp.
baseApp := sdk.NewBaseApp("gnoland", logger, db)

// Set mounts for BaseApp's MultiStore.
baseApp.MountStoreWithDB(mainKey, iavl.StoreConstructor, db)
baseApp.MountStoreWithDB(baseKey, dbadapter.StoreConstructor, db)

// Construct keepers.
acctKpr := auth.NewAccountKeeper(mainKey, ProtoGnoAccount)
bankKpr := bank.NewBankKeeper(acctKpr)
vmKpr := vm.NewVMKeeper(mainKey, acctKpr, bankKpr)
vmKpr := vm.NewVMKeeper(baseKey, mainKey, acctKpr, bankKpr)

// Configure InitChainer for genesis.
baseApp.SetInitChainer(InitChainer(acctKpr, bankKpr))
Expand Down
Loading

0 comments on commit 9cc61b0

Please sign in to comment.