Skip to content

Commit

Permalink
Merge pull request #29 from rarimo/feat/poll-modification
Browse files Browse the repository at this point in the history
Feat/poll modification
  • Loading branch information
Zaptoss authored Aug 2, 2024
2 parents 098eb4d + 9983bbd commit abd07f4
Show file tree
Hide file tree
Showing 18 changed files with 3,393 additions and 106 deletions.
12 changes: 10 additions & 2 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ event_types:
short_description: Short description
no_auto_open: true
auto_claim: true
- name: poll_participation
title: Participate in a poll
reward: 1
frequency: unlimited
description: Vote in a poll and get additional points
short_description: Vote in a poll and get additional points
no_auto_open: true
auto_claim: true
- name: meetup_participation
title: Prove your participation by scanning QR code
reward: 5
Expand Down Expand Up @@ -106,9 +114,9 @@ poseidonsmt_root_verifier:
contract: poseidon_smt_contract_address
request_timeout: 10s

proposalsmt_root_verifier:
poll_verifier:
rpc: evm_rpc_url
request_timeout: 10s
proposal_state_address: 0x123...123

sig_verifier:
verification_key: "37bc75afc97f8bdcd21cda85ae7b2885b5f1205ae3d79942e56457230f1636a037cc7ebfe42998d66a3dd3446b9d29366271b4f2bd8e0d307db1d320b38fc02f"
9 changes: 6 additions & 3 deletions docs/spec/components/schemas/FulfillPollEvent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ allOf:
attributes:
required:
- proof
- proposal_id
type: object
properties:
proof:
type: object
format: types.ZKProof
description: |
Proof of voting in some poll.
The poll ID must be equal to `meta.static.poll_id` from the event.
description: Proof of voting in some poll.
proposal_id:
type: string
pattern: '[0-9]+'
description: Vote proposal id
5 changes: 0 additions & 5 deletions docs/spec/components/schemas/FulfillPollEventKey.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
type: object
required:
- id
- type
properties:
id:
type: string
description: Event ID
example: "059c81dd-2a54-44a8-8142-c15ad8f88949"
type:
type: string
enum: [ fulfill_poll_event ]
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
patch:
post:
tags:
- Events
summary: Fulfill poll event
description: Fulfill event for voting in Georgian poll by sending proof of voting
operationId: fulfillPollEvent
parameters:
- in: path
name: 'id'
required: true
schema:
type: string
example: "059c81dd-2a54-44a8-8142-c15ad8f88949"
security:
- BearerAuth: []
requestBody:
required: true
content:
Expand Down Expand Up @@ -46,5 +41,11 @@ patch:
$ref: '#/components/schemas/Errors'
404:
$ref: '#/components/responses/notFound'
409:
description: Event already fulfilled
content:
application/vnd.api+json:
schema:
$ref: '#/components/schemas/Errors'
500:
$ref: '#/components/responses/internalError'
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/go-ozzo/ozzo-validation/v4 v4.3.0
github.com/google/jsonapi v1.0.0
github.com/iden3/go-rapidsnark/types v0.0.3
github.com/iden3/go-rapidsnark/verifier v0.0.5
github.com/rarimo/geo-auth-svc v1.1.0
github.com/rarimo/saver-grpc-lib v1.0.0
github.com/rarimo/zkverifier-kit v1.2.0
Expand Down Expand Up @@ -93,7 +94,6 @@ require (
github.com/hdevalence/ed25519consensus v0.0.0-20220222234857-c00d1f31bab3 // indirect
github.com/holiman/uint256 v1.2.4 // indirect
github.com/iden3/go-iden3-crypto v0.0.15 // indirect
github.com/iden3/go-rapidsnark/verifier v0.0.5 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmhodges/levigo v1.0.0 // indirect
github.com/jmoiron/sqlx v1.3.5 // indirect
Expand Down
5 changes: 3 additions & 2 deletions internal/config/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Config interface {
broadcaster.Broadcasterer
evtypes.EventTypeser
hmacsig.SigCalculatorProvider
PollVerifierer

Levels() *Levels
Verifiers() Verifiers
Expand All @@ -32,9 +33,9 @@ type config struct {
broadcaster.Broadcasterer
evtypes.EventTypeser
hmacsig.SigCalculatorProvider
PollVerifierer

passport root.VerifierProvider
poll root.VerifierProvider

levels comfig.Once
verifier comfig.Once
Expand All @@ -48,9 +49,9 @@ func New(getter kv.Getter) Config {
Listenerer: comfig.NewListenerer(getter),
Logger: comfig.NewLogger(getter, comfig.LoggerOpts{}),
Auther: auth.NewAuther(getter), //nolint:misspell
PollVerifierer: NewPollVerifier(getter),
Broadcasterer: broadcaster.New(getter),
passport: root.NewVerifierProvider(getter, root.PoseidonSMT),
poll: root.NewVerifierProvider(getter, root.ProposalSMT),
EventTypeser: evtypes.NewConfig(getter),
SigCalculatorProvider: hmacsig.NewCalculatorProvider(getter),
}
Expand Down
125 changes: 125 additions & 0 deletions internal/config/poll_verifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package config

import (
"errors"
"fmt"
"math/big"
"os"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
zkptypes "github.com/iden3/go-rapidsnark/types"
zkpverifier "github.com/iden3/go-rapidsnark/verifier"
"github.com/rarimo/geo-points-svc/internal/contracts/proposalsmt"
"github.com/rarimo/geo-points-svc/internal/contracts/proposalsstate"

"gitlab.com/distributed_lab/figure/v3"
"gitlab.com/distributed_lab/kit/comfig"
"gitlab.com/distributed_lab/kit/kv"
)

const pollVerificationKey = "./proof_keys/poll.json"

var (
ErrInvalidProposalEventID = errors.New("invalid proposal event id")
ErrInvalidRoot = errors.New("invalid root")
ErrInvalidChallengedEventID = errors.New("invalid challenged event id")
)

const (
PollChallengedNullifier = iota
PollNullifierTreeRoot
PollParticipationEventID
PollChallengedEventID
)

type PollVerifierer interface {
PollVerifier() *PollVerifier
}

func NewPollVerifier(getter kv.Getter) PollVerifierer {
return &pollVerifier{
getter: getter,
}
}

type pollVerifier struct {
once comfig.Once
getter kv.Getter
}

type PollVerifier struct {
RPC *ethclient.Client `fig:"rpc,required"`
ProposalStateAddress common.Address `fig:"proposal_state_address,required"`

proposalsStateCaller *proposalsstate.ProposalsStateCaller
verificationKey []byte
}

func (c *pollVerifier) PollVerifier() *PollVerifier {
return c.once.Do(func() interface{} {

var cfg PollVerifier

err := figure.Out(&cfg).
From(kv.MustGetStringMap(c.getter, "poll_verifier")).
With(figure.EthereumHooks, figure.BaseHooks).
Please()
if err != nil {
panic(fmt.Errorf("failed to figure out vote verifier config: %w", err))
}

cfg.verificationKey, err = os.ReadFile(pollVerificationKey)
if err != nil {
panic(fmt.Errorf("failed to read pollVerificationKey: %w", err))
}

cfg.proposalsStateCaller, err = proposalsstate.NewProposalsStateCaller(cfg.ProposalStateAddress, cfg.RPC)
if err != nil {
panic(fmt.Errorf("failed to create proposals state caller: %w", err))
}

return &cfg
}).(*PollVerifier)
}

func (v *PollVerifier) VerifyProof(proof zkptypes.ZKProof, proposalID, proposalEventID *big.Int) error {
proposalInfo, err := v.proposalsStateCaller.GetProposalInfo(nil, proposalID)
if err != nil {
return fmt.Errorf("failed to get proposal info: %w", err)
}

proposalEventIDContract, err := v.proposalsStateCaller.GetProposalEventId(nil, proposalID)
if err != nil {
return fmt.Errorf("failed to get proposal event id: %w", err)
}

if proposalEventIDContract.Cmp(proposalEventID) != 0 {
return ErrInvalidProposalEventID
}

proposalSMTAddress := proposalInfo.ProposalSMT
proposalSMTCaller, err := proposalsmt.NewProposalSMTCaller(proposalSMTAddress, v.RPC)
if err != nil {
return fmt.Errorf("failed to create proposal smt caller: %w", err)
}

root, err := proposalSMTCaller.GetRoot(nil)
if err != nil {
return fmt.Errorf("failed to get root: %w", err)
}

if new(big.Int).SetBytes(root[:]).String() != proof.PubSignals[PollNullifierTreeRoot] {
return ErrInvalidRoot
}

if proof.PubSignals[PollChallengedEventID] != proofEventIDValue {
return ErrInvalidChallengedEventID
}

if err = zkpverifier.VerifyGroth16(proof, v.verificationKey); err != nil {
return fmt.Errorf("failed to verify proof: %w", err)
}

return nil
}
13 changes: 0 additions & 13 deletions internal/config/verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const (
maxIdentityCount = 1
documentTypeID = "ID"
passportVerificationKey = "./proof_keys/passport.json"
pollVerificationKey = "./proof_keys/poll.json"
)

type Verifiers struct {
Expand Down Expand Up @@ -55,20 +54,8 @@ func (c *config) Verifiers() Verifiers {
panic(fmt.Errorf("failed to initialize passport verifier: %w", err))
}

poll, err := zk.NewVerifier(nil,
zk.WithProofType(zk.PollParticipation),
zk.WithEventID(proofEventIDValue),
zk.WithVerificationKeyFile(pollVerificationKey))
if err != nil {
panic(fmt.Errorf("failed to initialize poll verifier: %w", err))
}

rv := c.poll.ProvideVerifier().(*root.ProposalSMTVerifier)

return Verifiers{
Passport: pass,
Poll: poll,
PollRoot: rv,
}
}).(Verifiers)
}
Loading

0 comments on commit abd07f4

Please sign in to comment.