Skip to content

Commit

Permalink
Merge branch 'master' into dev/jeronimoalbi/datastore
Browse files Browse the repository at this point in the history
  • Loading branch information
jeronimoalbi committed Feb 7, 2025
2 parents 8a3544b + f75a77a commit 69c3e8a
Show file tree
Hide file tree
Showing 49 changed files with 3,200 additions and 151 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/genesis-verify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
testnet: [ "test5.gno.land" ]
testnet: [ ] # Currently, all active testnet deployment genesis.json are legacy
runs-on: ubuntu-latest
steps:
- name: Checkout code
Expand Down
29 changes: 27 additions & 2 deletions contribs/gnogenesis/internal/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import (
"github.com/gnolang/gno/tm2/pkg/commands"
)

var errInvalidGenesisState = errors.New("invalid genesis state type")
var (
errInvalidGenesisState = errors.New("invalid genesis state type")
errInvalidTxSignature = errors.New("invalid tx signature")
)

type verifyCfg struct {
common.Cfg
Expand Down Expand Up @@ -60,10 +63,32 @@ func execVerify(cfg *verifyCfg, io commands.IO) error {
}

// Validate the initial transactions
for _, tx := range state.Txs {
for index, tx := range state.Txs {
if validateErr := tx.Tx.ValidateBasic(); validateErr != nil {
return fmt.Errorf("invalid transacton, %w", validateErr)
}

// Genesis txs can only be signed by 1 account.
// Basic tx validation ensures there is at least 1 signer
signer := tx.Tx.GetSignatures()[0]

// Grab the signature bytes of the tx.
// Genesis transactions are signed with
// account number and sequence set to 0
signBytes, err := tx.Tx.GetSignBytes(genesis.ChainID, 0, 0)
if err != nil {
return fmt.Errorf("unable to get tx signature payload, %w", err)
}

// Verify the signature using the public key
if !signer.PubKey.VerifyBytes(signBytes, signer.Signature) {
return fmt.Errorf(
"%w #%d, by signer %s",
errInvalidTxSignature,
index,
signer.PubKey.Address(),
)
}
}

// Validate the initial balances
Expand Down
97 changes: 97 additions & 0 deletions contribs/gnogenesis/internal/verify/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import (
"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/tm2/pkg/bft/types"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto/ed25519"
"github.com/gnolang/gno/tm2/pkg/crypto/mock"
"github.com/gnolang/gno/tm2/pkg/sdk/bank"
"github.com/gnolang/gno/tm2/pkg/std"
"github.com/gnolang/gno/tm2/pkg/testutils"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -63,6 +67,99 @@ func TestGenesis_Verify(t *testing.T) {
require.Error(t, cmdErr)
})

t.Run("invalid tx signature", func(t *testing.T) {
t.Parallel()

g := getValidTestGenesis()

testTable := []struct {
name string
signBytesFn func(tx *std.Tx) []byte
}{
{
name: "invalid chain ID",
signBytesFn: func(tx *std.Tx) []byte {
// Sign the transaction, but with a chain ID
// that differs from the genesis chain ID
signBytes, err := tx.GetSignBytes(g.ChainID+"wrong", 0, 0)
require.NoError(t, err)

return signBytes
},
},
{
name: "invalid account params",
signBytesFn: func(tx *std.Tx) []byte {
// Sign the transaction, but with an
// account number that is not 0
signBytes, err := tx.GetSignBytes(g.ChainID, 10, 0)
require.NoError(t, err)

return signBytes
},
},
}

for _, testCase := range testTable {
t.Run(testCase.name, func(t *testing.T) {
t.Parallel()

tempFile, cleanup := testutils.NewTestFile(t)
t.Cleanup(cleanup)

// Generate the transaction
signer := ed25519.GenPrivKey()

sendMsg := bank.MsgSend{
FromAddress: signer.PubKey().Address(),
ToAddress: signer.PubKey().Address(),
Amount: std.NewCoins(std.NewCoin("ugnot", 10)),
}

tx := std.Tx{
Msgs: []std.Msg{sendMsg},
Fee: std.Fee{
GasWanted: 1000000,
GasFee: std.NewCoin("ugnot", 20),
},
}

// Sign the transaction
signBytes := testCase.signBytesFn(&tx)

signature, err := signer.Sign(signBytes)
require.NoError(t, err)

tx.Signatures = append(tx.Signatures, std.Signature{
PubKey: signer.PubKey(),
Signature: signature,
})

g.AppState = gnoland.GnoGenesisState{
Balances: []gnoland.Balance{},
Txs: []gnoland.TxWithMetadata{
{
Tx: tx,
},
},
}

require.NoError(t, g.SaveAs(tempFile.Name()))

// Create the command
cmd := NewVerifyCmd(commands.NewTestIO())
args := []string{
"--genesis-path",
tempFile.Name(),
}

// Run the command
cmdErr := cmd.ParseAndRun(context.Background(), args)
assert.ErrorIs(t, cmdErr, errInvalidTxSignature)
})
}
})

t.Run("invalid balances", func(t *testing.T) {
t.Parallel()

Expand Down
1 change: 1 addition & 0 deletions examples/gno.land/p/moul/cow/gno.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module gno.land/p/moul/cow
Loading

0 comments on commit 69c3e8a

Please sign in to comment.