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

feat: add InMemory gnoland node #1241

Merged
merged 47 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
f01ad76
wip: gnoland inmemory
gfanton Oct 10, 2023
676523e
Merge remote-tracking branch 'origin/master' into feat/inmemory-gnoland
gfanton Oct 11, 2023
db5a4c2
Revert "fix(make): disable _test.gnoweb temporarily (#1223)"
gfanton Oct 11, 2023
3b71cc6
feat: add integration node
gfanton Oct 12, 2023
9077ca1
chore: cleanup
gfanton Oct 12, 2023
3a3133c
wip: gnoweb
gfanton Oct 12, 2023
06ecc62
chore: lint
gfanton Oct 12, 2023
84907d1
chore: add some comments
gfanton Oct 12, 2023
8e8bed2
fix: gnoweb tests
gfanton Oct 12, 2023
d510140
fix: enable gnoweb test on the CI
gfanton Oct 12, 2023
d967a5c
Merge branch 'master' into feat/inmemory-gnoland
gfanton Oct 12, 2023
3221a1c
feat: add testing node
gfanton Oct 12, 2023
92de256
chore: remove useless comment
gfanton Oct 12, 2023
2003899
feat: add testing helper
gfanton Oct 12, 2023
e0b59fd
chore: lint
gfanton Oct 12, 2023
6d761d7
wip: testing integration inmemory node
gfanton Oct 13, 2023
19cfdb0
chore: lint
gfanton Oct 16, 2023
7300c4e
fix(integration): waiting for node readiness
gfanton Oct 19, 2023
7ee015b
chore: lint
gfanton Oct 19, 2023
aee3dd9
chore: improve comments
gfanton Oct 20, 2023
a0dd859
Merge remote-tracking branch 'origin/master' into feat/inmemory-gnoland
gfanton Oct 21, 2023
2f8bc50
fix: update InMemoryNodeConfig
gfanton Oct 21, 2023
ff0aef2
chore: fix & lint
gfanton Oct 25, 2023
3584d86
Update gno.land/cmd/gnoland/start.go
gfanton Oct 26, 2023
9fa209b
Merge branch 'master' into feat/inmemory-gnoland
gfanton Oct 26, 2023
a580f54
chore: cleanup
gfanton Oct 27, 2023
d9bcf35
chore: add back previous gnoweb flag
gfanton Oct 27, 2023
daaa7a3
fix: fix gnoweb analytics test
gfanton Oct 27, 2023
81afbf4
chore: lint
gfanton Oct 27, 2023
8df3622
fix: add minimal and full config
gfanton Oct 27, 2023
f6d4b24
fix: creator balances
gfanton Oct 27, 2023
fbe0300
fix: lint
gfanton Oct 27, 2023
e1058ef
Merge branch 'master' into feat/inmemory-gnoland
gfanton Oct 27, 2023
f747694
chore: lint
gfanton Oct 27, 2023
248b083
fix: remove panic & fix potential nil error
gfanton Oct 27, 2023
0200561
Merge branch 'master' into feat/inmemory-gnoland
gfanton Oct 29, 2023
92ce8a8
chore: lint
gfanton Oct 30, 2023
77b416b
fix: use gnoland.Balance in `genesis` command
gfanton Oct 30, 2023
83321a8
Merge branch 'master' into feat/inmemory-gnoland
gfanton Nov 6, 2023
cc3fe3e
fix: use amino marshaler
gfanton Nov 6, 2023
41ef47c
fix: amount can be empty
gfanton Nov 6, 2023
d80231c
fix: rename Balance.Value into Balance.Amount
gfanton Nov 6, 2023
5b23e9f
chore: rename
gfanton Nov 6, 2023
6292f7b
chore: remove gnoroot singleton
gfanton Nov 6, 2023
844995a
chore: lint
gfanton Nov 7, 2023
f700c81
Merge branch 'master' into feat/inmemory-gnoland
gfanton Nov 7, 2023
a86eabc
Merge branch 'master' into feat/inmemory-gnoland
gfanton Nov 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .github/workflows/gnoland.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ jobs:
- _test.gnoland
- _test.gnokey
- _test.pkgs
# XXX: test broken, should be rewritten to run an inmemory localnode
# Re-add to makefile when fixed. Tracked here: https://github.com/gnolang/gno/issues/1222
#- _test.gnoweb
- _test.gnoweb
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
Expand All @@ -78,7 +76,7 @@ jobs:
export LOG_DIR="${{ runner.temp }}/logs/test-${{ matrix.goversion }}-gnoland"
make ${{ matrix.args }}
- name: Upload Test Log
if: always()
if: always()
uses: actions/upload-artifact@v3
with:
name: logs-test-gnoland-go${{ matrix.goversion }}
Expand All @@ -101,7 +99,7 @@ jobs:
uses: codecov/codecov-action@v3
with:
directory: ${{ runner.temp }}/coverage
token: ${{ secrets.CODECOV_TOKEN }}
token: ${{ secrets.CODECOV_TOKEN }}
moul marked this conversation as resolved.
Show resolved Hide resolved
fail_ci_if_error: ${{ github.repository == 'gnolang/gno' }}

docker-integration:
Expand Down
4 changes: 1 addition & 3 deletions gno.land/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,7 @@ fmt:
########################################
# Test suite
.PHONY: test
test: _test.gnoland _test.gnokey _test.pkgs
# XXX: _test.gnoweb is currently disabled. If fixed, re-enable here and in CI.
# https://github.com/gnolang/gno/issues/1222
test: _test.gnoland _test.gnoweb _test.gnokey _test.pkgs

GOTEST_FLAGS ?= -v -p 1 -timeout=30m

Expand Down
131 changes: 37 additions & 94 deletions gno.land/cmd/genesis/balances_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,22 @@ import (
"fmt"
"io"
"os"
"regexp"
"strconv"
"strings"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/tm2/pkg/amino"
"github.com/gnolang/gno/tm2/pkg/bft/types"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto"
"github.com/gnolang/gno/tm2/pkg/sdk/bank"
"github.com/gnolang/gno/tm2/pkg/std"

_ "github.com/gnolang/gno/gno.land/pkg/sdk/vm"
)

var (
balanceRegex = regexp.MustCompile(`^(\w+)=(\d+)ugnot$`)
amountRegex = regexp.MustCompile(`^(\d+)ugnot$`)
)

var (
errNoBalanceSource = errors.New("at least one balance source must be set")
errBalanceParsingAborted = errors.New("balance parsing aborted")
errInvalidBalanceFormat = errors.New("invalid balance format encountered")
errInvalidAddress = errors.New("invalid address encountered")
errInvalidAmount = errors.New("invalid amount encountered")
)

type balancesAddCfg struct {
Expand Down Expand Up @@ -152,7 +142,7 @@ func execBalancesAdd(ctx context.Context, cfg *balancesAddCfg, io *commands.IO)

// Construct the initial genesis balance sheet
state := genesis.AppState.(gnoland.GnoGenesisState)
genesisBalances, err := extractGenesisBalances(state)
genesisBalances, err := mapGenesisBalancesFromState(state)
if err != nil {
return err
}
Expand Down Expand Up @@ -190,12 +180,11 @@ func getBalancesFromEntries(entries []string) (accountBalances, error) {
balances := make(accountBalances)

for _, entry := range entries {
accountBalance, err := getBalanceFromEntry(entry)
if err != nil {
return nil, fmt.Errorf("unable to extract balance data, %w", err)
var balance gnoland.Balance
if err := balance.Parse(entry); err != nil {
return nil, fmt.Errorf("unable to parse balance entry: %w", err)
}

balances[accountBalance.address] = accountBalance.amount
balances[balance.Address] = balance
}

return balances, nil
Expand All @@ -220,12 +209,12 @@ func getBalancesFromSheet(sheet io.Reader) (accountBalances, error) {
continue
}

accountBalance, err := getBalanceFromEntry(entry)
if err != nil {
var balance gnoland.Balance
if err := balance.Parse(entry); err != nil {
return nil, fmt.Errorf("unable to extract balance data, %w", err)
}

balances[accountBalance.address] = accountBalance.amount
balances[balance.Address] = balance
}

if err := scanner.Err(); err != nil {
Expand Down Expand Up @@ -262,21 +251,19 @@ func getBalancesFromTransactions(

if err := amino.UnmarshalJSON(line, &tx); err != nil {
io.ErrPrintfln(
"invalid amino JSON encountered: %s",
"invalid amino JSON encountered: %q",
string(line),
)

continue
}

feeAmount, err := getAmountFromEntry(tx.Fee.GasFee.String())
if err != nil {
feeAmount := std.NewCoins(tx.Fee.GasFee)
if feeAmount.AmountOf("ugnot") <= 0 {
io.ErrPrintfln(
"invalid gas fee amount encountered: %s",
"invalid gas fee amount encountered: %q",
tx.Fee.GasFee.String(),
)

continue
}

for _, msg := range tx.Msgs {
Expand All @@ -286,13 +273,12 @@ func getBalancesFromTransactions(

msgSend := msg.(bank.MsgSend)

sendAmount, err := getAmountFromEntry(msgSend.Amount.String())
if err != nil {
sendAmount := msgSend.Amount
if sendAmount.AmountOf("ugnot") <= 0 {
io.ErrPrintfln(
"invalid send amount encountered: %s",
msgSend.Amount.String(),
)

continue
}

Expand All @@ -304,27 +290,35 @@ func getBalancesFromTransactions(
// causes an accounts balance to go < 0. In these cases,
// we initialize the account (it is present in the balance sheet), but
// with the balance of 0
from := balances[msgSend.FromAddress]
to := balances[msgSend.ToAddress]

to += sendAmount
from := balances[msgSend.FromAddress].Amount
to := balances[msgSend.ToAddress].Amount

to = to.Add(sendAmount)

if from < sendAmount || from < feeAmount {
if from.IsAllLT(sendAmount) || from.IsAllLT(feeAmount) {
// Account cannot cover send amount / fee
// (see message above)
from = 0
from = std.NewCoins(std.NewCoin("ugnot", 0))
}

if from > sendAmount {
from -= sendAmount
if from.IsAllGT(sendAmount) {
from = from.Sub(sendAmount)
}

if from > feeAmount {
from -= feeAmount
if from.IsAllGT(feeAmount) {
from = from.Sub(feeAmount)
}

balances[msgSend.FromAddress] = from
balances[msgSend.ToAddress] = to
// Set new balance
balances[msgSend.FromAddress] = gnoland.Balance{
Address: msgSend.FromAddress,
Amount: from,
}
balances[msgSend.ToAddress] = gnoland.Balance{
Address: msgSend.ToAddress,
Amount: to,
}
}
}
}
Expand All @@ -340,65 +334,14 @@ func getBalancesFromTransactions(
return balances, nil
}

// getAmountFromEntry
func getAmountFromEntry(entry string) (int64, error) {
matches := amountRegex.FindStringSubmatch(entry)

// Check if there is a match
if len(matches) != 2 {
return 0, fmt.Errorf(
"invalid amount, %s",
entry,
)
}

amount, err := strconv.ParseInt(matches[1], 10, 64)
if err != nil {
return 0, fmt.Errorf("invalid amount, %s", matches[1])
}

return amount, nil
}

// getBalanceFromEntry extracts the account balance information
// from a single line in the form of: <address>=<amount>ugnot
func getBalanceFromEntry(entry string) (*accountBalance, error) {
matches := balanceRegex.FindStringSubmatch(entry)
if len(matches) != 3 {
return nil, fmt.Errorf("%w, %s", errInvalidBalanceFormat, entry)
}

// Validate the address
address, err := crypto.AddressFromString(matches[1])
if err != nil {
return nil, fmt.Errorf("%w, %w", errInvalidAddress, err)
}

// Validate the amount
amount, err := strconv.ParseInt(matches[2], 10, 64)
if err != nil {
return nil, fmt.Errorf("%w, %w", errInvalidAmount, err)
}

return &accountBalance{
address: address,
amount: amount,
}, nil
}

// extractGenesisBalances extracts the initial account balances from the
// mapGenesisBalancesFromState extracts the initial account balances from the
// genesis app state
func extractGenesisBalances(state gnoland.GnoGenesisState) (accountBalances, error) {
func mapGenesisBalancesFromState(state gnoland.GnoGenesisState) (accountBalances, error) {
// Construct the initial genesis balance sheet
genesisBalances := make(accountBalances)

for _, entry := range state.Balances {
accountBalance, err := getBalanceFromEntry(entry)
if err != nil {
return nil, fmt.Errorf("invalid genesis balance entry, %w", err)
}

genesisBalances[accountBalance.address] = accountBalance.amount
for _, balance := range state.Balances {
genesisBalances[balance.Address] = balance
}

return genesisBalances, nil
Expand Down
Loading
Loading