Skip to content

Commit

Permalink
unify faucet URLs
Browse files Browse the repository at this point in the history
Signed-off-by: p4u <pau@dabax.net>
  • Loading branch information
p4u committed Oct 27, 2023
1 parent c597a32 commit cd31281
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 35 deletions.
19 changes: 7 additions & 12 deletions api/faucet/faucet.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ const (
// It generates a signed package that can be used to request tokens from the faucet.
type FaucetAPI struct {
signingKey *ethereum.SignKeys
networks map[string]uint64
amount uint64
}

// AttachFaucetAPI attaches the faucet API to the given http apirest router.
// The path prefix is used to define the base path in which the endpoint method will be registered.
// For example, if the pathPrefix is "/faucet", the resulting endpoint is /faucet/{network}/{to}.
// The networks map defines the amount of tokens to send for each network. Networks not defined are
// considered invalid.
func AttachFaucetAPI(signingKey *ethereum.SignKeys, networks map[string]uint64,
func AttachFaucetAPI(signingKey *ethereum.SignKeys, amount uint64,
api *apirest.API, pathPrefix string) error {
f := &FaucetAPI{
signingKey: signingKey,
networks: networks,
amount: amount,
}
return api.RegisterMethod(
path.Join(pathPrefix, "{network}/{to}"),
path.Join(pathPrefix, "{to}"),
"GET",
apirest.MethodAccessTypePublic,
f.faucetHandler,
Expand All @@ -46,11 +46,6 @@ func AttachFaucetAPI(signingKey *ethereum.SignKeys, networks map[string]uint64,

func (f *FaucetAPI) faucetHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error {
// check network is correct and get amount to send
network := ctx.URLParam("network")
amount, ok := f.networks[network]
if !ok || amount == 0 {
return api.ErrParamNetworkInvalid
}
// get TO address
toStr := ctx.URLParam("to")
if !common.IsHexAddress(toStr) {
Expand All @@ -59,8 +54,8 @@ func (f *FaucetAPI) faucetHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContex
to := common.HexToAddress(toStr)

// generate faucet package
log.Debugf("faucet request from %s for network %s", to, network)
fpackage, err := vochain.GenerateFaucetPackage(f.signingKey, to, amount)
log.Debugw("faucet request", "from", to.String(), "amount", f.amount)
fpackage, err := vochain.GenerateFaucetPackage(f.signingKey, to, f.amount)
if err != nil {
return api.ErrCantGenerateFaucetPkg.WithErr(err)
}
Expand All @@ -73,7 +68,7 @@ func (f *FaucetAPI) faucetHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContex
}
// send response
resp := &FaucetResponse{
Amount: fmt.Sprint(amount),
Amount: fmt.Sprintf("%d", f.amount),
FaucetPackage: fpackageBytes,
}
data, err := json.Marshal(resp)
Expand Down
2 changes: 1 addition & 1 deletion apiclient/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ func (c *HTTPclient) RegisterSIKForVote(electionId types.HexBytes, proof *Census
},
})
if err != nil {
return nil, fmt.Errorf("error enconding RegisterSIKTx: %w", err)
return nil, fmt.Errorf("error encoding RegisterSIKTx: %w", err)
}
// sign it and send it
hash, _, err := c.SignAndSendTx(stx)
Expand Down
19 changes: 14 additions & 5 deletions apiclient/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"go.vocdoni.io/dvote/httprouter/apirest"
"go.vocdoni.io/dvote/log"
"go.vocdoni.io/dvote/types"
"go.vocdoni.io/dvote/util"
"go.vocdoni.io/proto/build/go/models"
"google.golang.org/protobuf/proto"
)
Expand Down Expand Up @@ -257,8 +258,12 @@ func (c *HTTPclient) EncryptionKeys(electionID types.HexBytes) ([]api.Key, error
// GetFaucetPackageFromDevService returns a faucet package.
// Needs just the destination wallet address, the URL and bearer token are hardcoded
func GetFaucetPackageFromDevService(account string) (*models.FaucetPackage, error) {
url, err := util.BuildURL(DefaultDevelopmentFaucetURL, account)
if err != nil {
return nil, err
}
return GetFaucetPackageFromRemoteService(
DefaultDevelopmentFaucetURL+account,
url,
"",
)
}
Expand All @@ -271,18 +276,22 @@ func GetFaucetPackageFromRemoteService(faucetURL, token string) (*models.FaucetP
if err != nil {
return nil, err
}
header := http.Header{
"User-Agent": []string{"Vocdoni API client / 1.0"},
}
if token != "" {
header.Add("Authorization", "Bearer "+token)
}
c := http.Client{}
resp, err := c.Do(&http.Request{
Method: HTTPGET,
URL: u,
Header: http.Header{
"Authorization": []string{"Bearer " + token},
"User-Agent": []string{"Vocdoni API client / 1.0"},
},
Header: header,
})
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != apirest.HTTPstatusOK {
return nil, fmt.Errorf("faucet request failed: %s", resp.Status)
}
Expand Down
7 changes: 2 additions & 5 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,11 +305,8 @@ func bootStrapAccount(cli *VocdoniCLI) error {
return err
}
} else {
infoPrint.Printf("trying to fetch faucet package from remote service...\n")
faucetPkg, err = apiclient.GetFaucetPackageFromRemoteService(
apiclient.DefaultDevelopmentFaucetURL+cli.api.MyAddress().Hex(),
"",
)
infoPrint.Printf("trying to fetch faucet package from default remote service...\n")
faucetPkg, err = apiclient.GetFaucetPackageFromDevService(cli.api.MyAddress().Hex())
if err != nil {
return err
}
Expand Down
8 changes: 6 additions & 2 deletions cmd/end2endtest/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -574,11 +574,15 @@ func (t *e2eElection) sendVotes(votes []*apiclient.VoteData) map[int]error {
func faucetPackage(faucet, faucetAuthToken, myAddress string) (*models.FaucetPackage, error) {
switch faucet {
case "":
return nil, fmt.Errorf("need to pass a valid --faucet")
return nil, fmt.Errorf("need to pass a valid URL (--faucet)")
case "dev":
return apiclient.GetFaucetPackageFromDevService(myAddress)
default:
return apiclient.GetFaucetPackageFromRemoteService(faucet+myAddress, faucetAuthToken)
url, err := util.BuildURL(faucet, myAddress)
if err != nil {
return nil, err
}
return apiclient.GetFaucetPackageFromRemoteService(url, faucetAuthToken)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/end2endtest/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func main() {
fmt.Fprintf(os.Stderr, "\n")
}
fmt.Fprintf(os.Stderr, "If the network is deployed locally using the docker test suite, ")
fmt.Fprintf(os.Stderr, "the faucet URL might be configured as `--faucet=http://localhost:9090/v2/faucet/dev/`\n")
fmt.Fprintf(os.Stderr, "the faucet URL might be configured as `--faucet=http://localhost:9090/v2/open/claim`\n")
}

flag.CommandLine.SortFlags = false
Expand Down
6 changes: 2 additions & 4 deletions cmd/node/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,9 @@ func main() {
// attach faucet to the API if enabled
if conf.EnableFaucetWithAmount > 0 {
if err := faucet.AttachFaucetAPI(srv.Signer,
map[string]uint64{
conf.Vochain.Chain: conf.EnableFaucetWithAmount,
},
conf.EnableFaucetWithAmount,
uAPI.RouterHandler(),
"/faucet",
"/open/claim",
); err != nil {
log.Fatal(err)
}
Expand Down
6 changes: 2 additions & 4 deletions cmd/voconed/voconed.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,9 @@ func main() {
}
log.Infof("faucet account %s, faucet amount %d", faucetAccount.Address().Hex(), config.enableFaucetWithAmount)
if err := faucet.AttachFaucetAPI(&faucetAccount,
map[string]uint64{
config.chainID: config.enableFaucetWithAmount,
},
config.enableFaucetWithAmount,
uAPI.RouterHandler(),
"/faucet",
"/open/claim",
); err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion dockerfiles/testsuite/start_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ cb595f3fa1a4790dd54c139524a1430fc500f95a02affee6a933fcb88849a48d"
ACCOUNT_KEYS=${ACCOUNT_KEYS:-$DEFAULT_ACCOUNT_KEYS}
GWHOST="http://gateway0:9090/dvote"
APIHOST="http://gateway0:9090/v2"
FAUCET="$APIHOST/faucet/dev/"
FAUCET="$APIHOST/open/claim"
TEST_PREFIX="testsuite_test"
RANDOMID="${RANDOM}${RANDOM}"

Expand Down
28 changes: 28 additions & 0 deletions util/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"crypto/rand"
"fmt"
"math/big"
"net/url"
"path"
"strings"
)

func TrimHex(s string) string {
Expand Down Expand Up @@ -39,3 +42,28 @@ func RandomInt(min, max int) int {
}
return int(num.Int64()) + min
}

// BuildURL constructs a URL from parts. It handles any irregularities like missing or extra slashes.
func BuildURL(parts ...string) (string, error) {
if len(parts) == 0 {
return "", fmt.Errorf("no parts provided")
}

// Parse the base URL (the first part).
base, err := url.Parse(parts[0])
if err != nil {
return "", fmt.Errorf("could not parse base URL: %v", err)
}

// Create a path by joining all parts with a "/". This will also clean the path,
otherParts := parts[1:]
for i, part := range otherParts {
cleanPart := path.Clean("/" + part)
otherParts[i] = strings.TrimPrefix(cleanPart, "/") // Remove the leading slash added for cleaning.
}

// Now, construct the full path with the base path and the other parts.
fullPath := path.Join(base.Path, path.Join(otherParts...))
base.Path = fullPath
return base.String(), nil
}

0 comments on commit cd31281

Please sign in to comment.