Skip to content

Commit

Permalink
[Proof] Relay signature & Merkle proof validation (#406)
Browse files Browse the repository at this point in the history
Co-authored-by: Bryan White <[email protected]>
Co-authored-by: Daniel Olshansky <[email protected]>
  • Loading branch information
3 people authored Mar 22, 2024
1 parent 1c13536 commit 158e893
Show file tree
Hide file tree
Showing 44 changed files with 1,158 additions and 571 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -616,8 +616,14 @@ acc_initialize_pubkeys: ## Make sure the account keeper has public keys for all

.PHONY: acc_initialize_pubkeys_warn_message
acc_initialize_pubkeys_warn_message: ## Print a warning message about the need to run `make acc_initialize_pubkeys`
@printf "!!!!!!!!! YOU MUST RUN THE FOLLOWING COMMAND ONCE FOR E2E TESTS TO WORK AFTER THE NETWORK HAS STARTED !!!!!!!!!\n"\
"\t\tmake acc_initialize_pubkeys\n"
@echo "+----------------------------------------------------------------------------------+"
@echo "| |"
@echo "| IMPORTANT: Please run the following command once to initialize E2E tests |"
@echo "| after the network has started: |"
@echo "| make acc_initialize_pubkeys |"
@echo "| |"
@echo "+----------------------------------------------------------------------------------+"


##############
### Claims ###
Expand Down
95 changes: 49 additions & 46 deletions api/poktroll/service/relay.pulsar.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion e2e/tests/tokenomics.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Feature: Tokenomics Namespaces
And an account exists for "supplier1"
And an account exists for "app1"
When the supplier "supplier1" has serviced a session with "20" relays for service "svc1" for application "app1"
And the user should wait for "5" seconds
# And the user should wait for "5" seconds
# TODO_UPNEXT(@Olshansk, #359): Expand on the two expectations below after integrating the tokenomics module
# into the supplier module.
# Then the account balance of "supplier1" should be "1000" uPOKT "more" than before
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,4 @@ require (
)

// replace github.com/cosmos/cosmos-sdk => github.com/rollkit/cosmos-sdk v0.50.1-rollkit-v0.11.19-no-fraud-proofs
replace github.com/pokt-network/smt => github.com/pokt-network/smt v0.9.3-0.20240321060129-e3dbbbd9f97d
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -978,8 +978,8 @@ github.com/pkg/profile v1.7.0/go.mod h1:8Uer0jas47ZQMJ7VD+OHknK4YDY07LPUC6dEvqDj
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pokt-network/smt v0.9.2 h1:h/GnFm1F6mNBbF1hopr+9+y7nr173SU55NX7NxTVU0Y=
github.com/pokt-network/smt v0.9.2/go.mod h1:S4Ho4OPkK2v2vUCHNtA49XDjqUC/OFYpBbynRVYmxvA=
github.com/pokt-network/smt v0.9.3-0.20240321060129-e3dbbbd9f97d h1:6x7LiRWV+mHugWbJlGaYSWESEV+by8hGIbXb3/bWXOg=
github.com/pokt-network/smt v0.9.3-0.20240321060129-e3dbbbd9f97d/go.mod h1:S4Ho4OPkK2v2vUCHNtA49XDjqUC/OFYpBbynRVYmxvA=
github.com/pokt-network/smt/kvstore/badger v0.0.0-20240109205447-868237978c0b h1:TjfgV3vgW0zW47Br/OgUXD4M8iyR74EYanbFfN4ed8o=
github.com/pokt-network/smt/kvstore/badger v0.0.0-20240109205447-868237978c0b/go.mod h1:GbzcG5ebj8twKmBL1VzdPM4NS44okwYXBfQaVXT+6yU=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
Expand Down
7 changes: 5 additions & 2 deletions pkg/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import (
comettypes "github.com/cometbft/cometbft/rpc/core/types"
cosmosclient "github.com/cosmos/cosmos-sdk/client"
cosmoskeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
cosmostypes "github.com/cosmos/cosmos-sdk/types"
accounttypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/pokt-network/smt"

"github.com/pokt-network/poktroll/pkg/either"
Expand Down Expand Up @@ -231,7 +231,10 @@ type SupplierClientOption func(SupplierClient)
// on-chain account information
type AccountQueryClient interface {
// GetAccount queries the chain for the details of the account provided
GetAccount(ctx context.Context, address string) (accounttypes.AccountI, error)
GetAccount(ctx context.Context, address string) (cosmostypes.AccountI, error)

// GetPubKeyFromAddress returns the public key of the given address.
GetPubKeyFromAddress(ctx context.Context, address string) (cryptotypes.PubKey, error)
}

// ApplicationQueryClient defines an interface that enables the querying of the
Expand Down
42 changes: 37 additions & 5 deletions pkg/client/query/accquerier.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"

"cosmossdk.io/depinject"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types"
accounttypes "github.com/cosmos/cosmos-sdk/x/auth/types"
grpc "github.com/cosmos/gogoproto/grpc"

Expand All @@ -18,6 +20,10 @@ var _ client.AccountQueryClient = (*accQuerier)(nil)
type accQuerier struct {
clientConn grpc.ClientConn
accountQuerier accounttypes.QueryClient

// accountCache is a cache of accounts that have already been queried.
// TODO_TECHDEBT: Add a size limit to the cache and consider an LRU cache.
accountCache map[string]types.AccountI
}

// NewAccountQuerier returns a new instance of a client.AccountQueryClient by
Expand All @@ -26,7 +32,7 @@ type accQuerier struct {
// Required dependencies:
// - clientCtx
func NewAccountQuerier(deps depinject.Config) (client.AccountQueryClient, error) {
aq := &accQuerier{}
aq := &accQuerier{accountCache: make(map[string]types.AccountI)}

if err := depinject.Inject(
deps,
Expand All @@ -44,15 +50,41 @@ func NewAccountQuerier(deps depinject.Config) (client.AccountQueryClient, error)
func (aq *accQuerier) GetAccount(
ctx context.Context,
address string,
) (accounttypes.AccountI, error) {
) (types.AccountI, error) {
if foundAccount, isAccountFound := aq.accountCache[address]; isAccountFound {
return foundAccount, nil
}

// Query the blockchain for the account record
req := &accounttypes.QueryAccountRequest{Address: address}
res, err := aq.accountQuerier.Account(ctx, req)
if err != nil {
return nil, ErrQueryAccountNotFound.Wrapf("address: %s [%v]", address, err)
}
var acc accounttypes.AccountI
if err = queryCodec.UnpackAny(res.Account, &acc); err != nil {

// Unpack and cache the account object
var fetchedAccount types.AccountI
if err = queryCodec.UnpackAny(res.Account, &fetchedAccount); err != nil {
return nil, ErrQueryUnableToDeserializeAccount.Wrapf("address: %s [%v]", address, err)
}
return acc, nil
aq.accountCache[address] = fetchedAccount

return fetchedAccount, nil
}

// GetPubKeyFromAddress returns the public key of the given address.
// It uses the accountQuerier to get the account and then returns its public key.
func (aq *accQuerier) GetPubKeyFromAddress(ctx context.Context, address string) (cryptotypes.PubKey, error) {
acc, err := aq.GetAccount(ctx, address)
if err != nil {
return nil, err
}

// If the account's public key is nil, then return an error.
pubKey := acc.GetPubKey()
if pubKey == nil {
return nil, ErrQueryPubKeyNotFound
}

return pubKey, nil
}
1 change: 1 addition & 0 deletions pkg/client/query/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ var (
ErrQueryAccountNotFound = sdkerrors.Register(codespace, 1, "account not found")
ErrQueryUnableToDeserializeAccount = sdkerrors.Register(codespace, 2, "unable to deserialize account")
ErrQueryRetrieveSession = sdkerrors.Register(codespace, 3, "error while trying to retrieve a session")
ErrQueryPubKeyNotFound = sdkerrors.Register(codespace, 4, "account pub key not found")
)
5 changes: 4 additions & 1 deletion pkg/client/supplier/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,11 @@ func TestSupplierClient_SubmitProof(t *testing.T) {
kvStore, err := badger.NewKVStore("")
require.NoError(t, err)

// Generating an ephemeral tree & spec just so we can submit
// a proof of the right size.
tree := smt.NewSparseMerkleSumTrie(kvStore, sha256.New())
proof, err := tree.ProveClosest([]byte{1})
emptyPath := make([]byte, tree.PathHasherSize())
proof, err := tree.ProveClosest(emptyPath)
require.NoError(t, err)

go func() {
Expand Down
7 changes: 6 additions & 1 deletion pkg/client/tx/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tx_test

import (
"context"
"crypto/sha256"
"sync"
"testing"
"time"
Expand All @@ -14,6 +15,7 @@ import (
cosmoskeyring "github.com/cosmos/cosmos-sdk/crypto/keyring"
"github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
"github.com/pokt-network/smt"
"github.com/stretchr/testify/require"

"github.com/pokt-network/poktroll/pkg/client"
Expand Down Expand Up @@ -401,8 +403,11 @@ func TestTxClient_SignAndBroadcast_Timeout(t *testing.T) {
err, errCh := eitherErr.SyncOrAsyncError()
require.NoError(t, err)

spec := smt.NoPrehashSpec(sha256.New(), true)
emptyBlockHash := make([]byte, spec.PathHasherSize())

for i := 0; i < tx.DefaultCommitTimeoutHeightOffset; i++ {
blocksPublishCh <- testblock.NewAnyTimesBlock(t, []byte{}, int64(i+1))
blocksPublishCh <- testblock.NewAnyTimesBlock(t, emptyBlockHash, int64(i+1))
}

// Assert that we receive the expected error type & message.
Expand Down
Loading

0 comments on commit 158e893

Please sign in to comment.