Skip to content

Commit

Permalink
Add additional unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zivkovicmilos committed Sep 15, 2023
1 parent 634402b commit a061e08
Show file tree
Hide file tree
Showing 7 changed files with 412 additions and 29 deletions.
8 changes: 5 additions & 3 deletions faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"github.com/gnolang/faucet/client"
"github.com/gnolang/faucet/config"
"github.com/gnolang/faucet/estimate"
"github.com/gnolang/faucet/keyring"
"github.com/gnolang/faucet/keyring/memory"
"github.com/gnolang/faucet/log"
"github.com/gnolang/faucet/log/noop"
"github.com/gnolang/gno/tm2/pkg/std"
Expand All @@ -23,14 +25,14 @@ type Faucet struct {
estimator estimate.Estimator // gas pricing estimations
logger log.Logger // log feedback
client client.Client // TM2 client
keyring keyring.Keyring // the faucet keyring

mux *chi.Mux // HTTP routing

config *config.Config // faucet configuration
middlewares []Middleware // request middlewares
handlers []Handler // request handlers

keyring *keyring // the faucet keyring
sendAmount std.Coins // for fast lookup
}

Expand Down Expand Up @@ -71,8 +73,8 @@ func NewFaucet(
// Set the send amount
f.sendAmount, _ = std.ParseCoins(f.config.SendAmount)

// Generate the keyring
f.keyring = newKeyring(f.config.Mnemonic, f.config.NumAccounts)
// Generate the in-memory keyring
f.keyring = memory.New(f.config.Mnemonic, f.config.NumAccounts)

// Set up the CORS middleware
if f.config.CORSConfig != nil {
Expand Down
12 changes: 12 additions & 0 deletions keyring/keyring.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package keyring

import "github.com/gnolang/gno/tm2/pkg/crypto"

// Keyring defines the faucet keyring functionality
type Keyring interface {
// GetAddresses fetches the addresses in the keyring
GetAddresses() []crypto.Address

// GetKey fetches the private key associated with the specified address
GetKey(address crypto.Address) crypto.PrivKey
}
19 changes: 10 additions & 9 deletions keyring.go → keyring/memory/memory.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package faucet
package memory

import (
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand All @@ -7,13 +7,14 @@ import (
"github.com/gnolang/gno/tm2/pkg/crypto/secp256k1"
)

type keyring struct {
// Keyring is an in-memory keyring
type Keyring struct {
addresses []crypto.Address
keyMap map[crypto.Address]crypto.PrivKey
}

// newKeyring initializes the keyring using the provided mnemonics
func newKeyring(mnemonic string, numAccounts uint64) *keyring {
// New initializes the keyring using the provided mnemonics
func New(mnemonic string, numAccounts uint64) *Keyring {
addresses := make([]crypto.Address, numAccounts)
keyMap := make(map[crypto.Address]crypto.PrivKey, numAccounts)

Expand All @@ -28,19 +29,19 @@ func newKeyring(mnemonic string, numAccounts uint64) *keyring {
keyMap[address] = key
}

return &keyring{
return &Keyring{
addresses: addresses,
keyMap: keyMap,
}
}

// getAddresses fetches the addresses in the keyring
func (k *keyring) getAddresses() []crypto.Address {
// GetAddresses fetches the addresses in the keyring
func (k *Keyring) GetAddresses() []crypto.Address {
return k.addresses
}

// getKey fetches the private key associated with the specified address
func (k *keyring) getKey(address crypto.Address) crypto.PrivKey {
// GetKey fetches the private key associated with the specified address
func (k *Keyring) GetKey(address crypto.Address) crypto.PrivKey {
return k.keyMap[address]
}

Expand Down
14 changes: 7 additions & 7 deletions keyring_test.go → keyring/memory/memory_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package faucet
package memory

import (
"testing"
Expand Down Expand Up @@ -33,7 +33,7 @@ func TestKeyring_NewKeyring(t *testing.T) {
)

// Create the keyring
kr := newKeyring(mnemonic, numAccounts)
kr := New(mnemonic, numAccounts)

// Make sure the keyring is initialized correctly
assert.Len(t, kr.addresses, int(numAccounts))
Expand All @@ -49,10 +49,10 @@ func TestKeyring_GetAddresses(t *testing.T) {
)

// Create the keyring
kr := newKeyring(mnemonic, numAccounts)
kr := New(mnemonic, numAccounts)

// Fetch the addresses
addresses := kr.getAddresses()
addresses := kr.GetAddresses()

// Make sure the addresses are valid
assert.Len(t, addresses, int(numAccounts))
Expand All @@ -71,17 +71,17 @@ func TestKeyring_GetKey(t *testing.T) {
)

// Create the keyring
kr := newKeyring(mnemonic, numAccounts)
kr := New(mnemonic, numAccounts)

// Fetch the addresses
addresses := kr.getAddresses()
addresses := kr.GetAddresses()

// Make sure the addresses are valid
assert.Len(t, addresses, int(numAccounts))

// Fetch the key associated with an address
address := addresses[0]
key := kr.getKey(address)
key := kr.GetKey(address)

// Make sure the key matches the address
assert.Equal(t, address, key.PubKey().Address())
Expand Down
141 changes: 141 additions & 0 deletions mock_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,144 @@ func (m *mockClient) SendTransactionCommit(tx *std.Tx) (*coreTypes.ResultBroadca

return nil, nil
}

type (
getAddressDelegate func() crypto.Address
setAddressDelegate func(crypto.Address) error
getPubKeyDelegate func() crypto.PubKey
setPubKeyDelegate func(crypto.PubKey) error
getAccountNumberDelegate func() uint64
setAccountNumberDelegate func(uint64) error
getSequenceDelegate func() uint64
setSequenceDelegate func(uint64) error
getCoinsDelegate func() std.Coins
setCoinsDelegate func(std.Coins) error
)

type mockAccount struct {
getAddressFn getAddressDelegate
setAddressFn setAddressDelegate
getPubKeyFn getPubKeyDelegate
setPubKeyFn setPubKeyDelegate
getAccountNumberFn getAccountNumberDelegate
setAccountNumberFn setAccountNumberDelegate
getSequenceFn getSequenceDelegate
setSequenceFn setSequenceDelegate
getCoinsFn getCoinsDelegate
setCoinsFn setCoinsDelegate
stringFn stringDelegate
}

func (m *mockAccount) GetAddress() crypto.Address {
if m.getAddressFn != nil {
return m.getAddressFn()
}

return crypto.Address{}
}

func (m *mockAccount) SetAddress(address crypto.Address) error {
if m.setAddressFn != nil {
return m.setAddressFn(address)
}

return nil
}

func (m *mockAccount) GetPubKey() crypto.PubKey {
if m.getPubKeyFn != nil {
return m.getPubKeyFn()
}

return nil
}

func (m *mockAccount) SetPubKey(key crypto.PubKey) error {
if m.setPubKeyFn != nil {
return m.setPubKeyFn(key)
}

return nil
}

func (m *mockAccount) GetAccountNumber() uint64 {
if m.getAccountNumberFn != nil {
return m.getAccountNumberFn()
}

return 0
}

func (m *mockAccount) SetAccountNumber(number uint64) error {
if m.setAccountNumberFn != nil {
return m.setAccountNumberFn(number)
}

return nil
}

func (m *mockAccount) GetSequence() uint64 {
if m.getSequenceFn != nil {
return m.getSequenceFn()
}

return 0
}

func (m *mockAccount) SetSequence(sequence uint64) error {
if m.setSequenceFn != nil {
return m.setSequenceFn(sequence)
}

return nil
}

func (m *mockAccount) GetCoins() std.Coins {
if m.getCoinsFn != nil {
return m.getCoinsFn()
}

return std.Coins{}
}

func (m *mockAccount) SetCoins(coins std.Coins) error {
if m.setCoinsFn != nil {
return m.setCoinsFn(coins)
}

return nil
}

func (m *mockAccount) String() string {
if m.stringFn != nil {
return m.stringFn()
}

return ""
}

type (
getAddressesDelegate func() []crypto.Address
getKeyDelegate func(crypto.Address) crypto.PrivKey
)

type mockKeyring struct {
getAddressesFn getAddressesDelegate
getKeyFn getKeyDelegate
}

func (m *mockKeyring) GetAddresses() []crypto.Address {
if m.getAddressesFn != nil {
return m.getAddressesFn()
}

return nil
}

func (m *mockKeyring) GetKey(address crypto.Address) crypto.PrivKey {
if m.getKeyFn != nil {
return m.getKeyFn(address)
}

return nil
}
27 changes: 17 additions & 10 deletions transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import (
"github.com/gnolang/gno/tm2/pkg/std"
)

var (
errNoFundedAccount = errors.New("no funded account found")
)

// transferFunds transfers funds to the given address
func (f *Faucet) transferFunds(address crypto.Address) error {
// Find an account that has balance to cover the transfer
Expand All @@ -15,15 +19,12 @@ func (f *Faucet) transferFunds(address crypto.Address) error {
return err
}

sendAmount, _ := std.ParseCoins(f.config.SendAmount)

// Prepare the transaction
prepareCfg := prepareCfg{
fromAddress: fundAccount.GetAddress(),
toAddress: address,
sendAmount: sendAmount,
sendAmount: f.sendAmount,
}

// Prepare the transaction
tx := prepareTransaction(f.estimator, prepareCfg)

// Sign the transaction
Expand All @@ -35,7 +36,7 @@ func (f *Faucet) transferFunds(address crypto.Address) error {

if err := signTransaction(
tx,
f.keyring.getKey(fundAccount.GetAddress()),
f.keyring.GetKey(fundAccount.GetAddress()),
signCfg,
); err != nil {
return err
Expand All @@ -48,7 +49,13 @@ func (f *Faucet) transferFunds(address crypto.Address) error {
// findFundedAccount finds an account
// whose balance is enough to cover the send amount
func (f *Faucet) findFundedAccount() (std.Account, error) {
for _, address := range f.keyring.getAddresses() {
// A funded account is an account that can
// cover the initial transfer fee, as well
// as the send amount
estimatedFee := f.estimator.EstimateGasFee()
requiredFunds := f.sendAmount.Add(std.NewCoins(estimatedFee))

for _, address := range f.keyring.GetAddresses() {
// Fetch the account
account, err := f.client.GetAccount(address)
if err != nil {
Expand All @@ -67,15 +74,15 @@ func (f *Faucet) findFundedAccount() (std.Account, error) {
balance := account.GetCoins()

// Make sure there are enough funds
if balance.IsAllLT(f.sendAmount) {
if balance.IsAllLT(requiredFunds) {
f.logger.Error(
"account cannot serve requests",
"address",
address.String(),
"balance",
balance.String(),
"amount",
f.sendAmount,
requiredFunds,
)

continue
Expand All @@ -84,5 +91,5 @@ func (f *Faucet) findFundedAccount() (std.Account, error) {
return account, nil
}

return nil, errors.New("no funded account found")
return nil, errNoFundedAccount
}
Loading

0 comments on commit a061e08

Please sign in to comment.