Skip to content

Commit

Permalink
add: state_root query; update: docs, get gist proof by state root, no…
Browse files Browse the repository at this point in the history
…t block number, split business logic and user request data
  • Loading branch information
mhrynenko committed May 17, 2024
1 parent fc8e6f6 commit b384f7e
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ get:
required: true
schema:
type: string
- in: query
name: state_root
required: true
schema:
type: string
responses:
'200':
description: Success
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496 // indirect
github.com/bits-and-blooms/bitset v1.10.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
Expand Down
62 changes: 3 additions & 59 deletions internal/service/api/handlers/get_gist_data.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
package handlers

import (
"context"
validation "github.com/go-ozzo/ozzo-validation/v4"
"gitlab.com/distributed_lab/logan/v3/errors"
"math/big"
"net/http"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/iden3/contracts-abi/state/go/abi"
core "github.com/iden3/go-iden3-core/v2"
"github.com/iden3/go-iden3-core/v2/w3c"
"github.com/rarimo/passport-identity-provider/internal/service/api/requests"
"github.com/rarimo/passport-identity-provider/resources"
"gitlab.com/distributed_lab/ape"
"gitlab.com/distributed_lab/ape/problems"
"gitlab.com/distributed_lab/logan/v3"
)

func GetGistData(w http.ResponseWriter, r *http.Request) {
Expand All @@ -25,72 +20,21 @@ func GetGistData(w http.ResponseWriter, r *http.Request) {
return
}

userDID, err := w3c.ParseDID(req.UserDID)
if err != nil {
Log(r).WithError(err).Error("failed to parse user DID")
ape.RenderErr(w, problems.BadRequest(err)...)
return
}

userID, err := core.IDFromDID(*userDID)
userID, err := core.IDFromDID(*req.UserDID)
if err != nil {
Log(r).WithError(err).Error("failed to parse user ID")
ape.RenderErr(w, problems.InternalError())
return
}

blockNum, err := EthClient(r).BlockNumber(context.Background())
if err != nil {
Log(r).WithError(err).Error("failed to get block number")
ape.RenderErr(w, problems.InternalError())
return
}

if req.BlockNumber > blockNum {
Log(r).WithFields(logan.F{
"requested_block_number": req.BlockNumber,
"latest_block_number": blockNum,
}).Error("Requested block number is higher than latest")
ape.RenderErr(w, problems.BadRequest(validation.Errors{
"/block_number": errors.New("Requested block number is higher than latest"),
})...)
return
}

if req.BlockNumber != 0 {
blockNum = req.BlockNumber
}

stateContract := StateContract(r)

gistProof, err := stateContract.GetGISTProof(&bind.CallOpts{
BlockNumber: new(big.Int).SetUint64(blockNum),
}, userID.BigInt())
gistProof, err := StateContract(r).GetGISTProofByRoot(&bind.CallOpts{}, req.StateRoot, userID.BigInt())
if err != nil {
Log(r).WithError(err).Error("failed to get GIST proof")
ape.RenderErr(w, problems.InternalError())
return
}

gistRoot, err := stateContract.GetGISTRoot(&bind.CallOpts{
BlockNumber: new(big.Int).SetUint64(blockNum),
})
if err != nil {
Log(r).WithError(err).Error("failed to get GIST root")
ape.RenderErr(w, problems.InternalError())
return
}

if gistProof.Root.Cmp(gistRoot) != 0 {
Log(r).WithFields(logan.F{
"gist_root": gistRoot.String(),
"gist_proof_root": gistProof.Root.String(),
}).Warn("gist root does not match")
}

response := newGistDataResponse(req.UserDID, gistProof, gistRoot)

ape.Render(w, response)
ape.Render(w, newGistDataResponse(req.UserDID.String(), gistProof, gistProof.Root))
}

func newGistDataResponse(userDID string, proof abi.IStateGistProof, root *big.Int) resources.GistDataResponse {
Expand Down
62 changes: 52 additions & 10 deletions internal/service/api/requests/get_gist_data.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,72 @@
package requests

import (
"math/big"
"net/http"

validation "github.com/go-ozzo/ozzo-validation/v4"
"github.com/go-ozzo/ozzo-validation/v4/is"
"github.com/iden3/go-iden3-core/v2/w3c"
"gitlab.com/distributed_lab/logan/v3"
"gitlab.com/distributed_lab/logan/v3/errors"
"gitlab.com/distributed_lab/urlval"
"net/http"
)

type GetGistDataRequest struct {
UserDID string `url:"user_did"`
BlockNumber uint64 `url:"block_number"`
UserDID *w3c.DID
StateRoot *big.Int
}

type getGistDataQuery struct {
UserDID string `url:"user_did"`
StateRoot string `url:"state_root"`
}

func NewGetGistDataRequest(r *http.Request) (GetGistDataRequest, error) {
var req GetGistDataRequest
var query getGistDataQuery

err := urlval.Decode(r.URL.Query(), &req)
err := urlval.Decode(r.URL.Query(), &query)
if err != nil {
return GetGistDataRequest{}, errors.Wrap(err, "failed to decode url")
return GetGistDataRequest{}, validation.Errors{
"url": errors.Wrap(err, "failed to decode url"),
}
}

return req, validateGetGistDataRequest(req)
return parseGistDataQuery(query)
}

func validateGetGistDataRequest(r GetGistDataRequest) error {
return validation.Errors{
"/user_did": validation.Validate(r.UserDID, validation.Required),
func parseGistDataQuery(query getGistDataQuery) (GetGistDataRequest, error) {
var (
err error
ok bool
req GetGistDataRequest
)

err = validation.Errors{
"/user_did": validation.Validate(query.UserDID, validation.Required),
"/state_root": validation.Validate(query.StateRoot, validation.Required, is.Hexadecimal),
}.Filter()
if err != nil {
return req, err
}

req.UserDID, err = w3c.ParseDID(query.UserDID)
if err != nil {
return req, validation.Errors{
"/user_did": errors.Wrap(err, "failed to parse user DID", logan.F{
"user_did": req.UserDID,
}),
}.Filter()
}

req.StateRoot, ok = new(big.Int).SetString(query.StateRoot, 16)
if !ok {
return req, validation.Errors{
"/state_root": errors.From(errors.New("failed to parse state root"), logan.F{
"state_root": req.StateRoot,
}),
}
}

return req, nil
}
2 changes: 1 addition & 1 deletion internal/service/issuer/main.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package issuer

import (
"github.com/google/uuid"
"math/big"
"strconv"
"time"

"github.com/google/uuid"
"github.com/iden3/go-iden3-crypto/poseidon"
"github.com/imroc/req/v3"
"github.com/rarimo/passport-identity-provider/internal/config"
Expand Down

0 comments on commit b384f7e

Please sign in to comment.