Browse Source

Keep adapting code to new merkletree

Add RootHash JSON parameter.
Remove Spanshopt API method.
Add support on genProof/checkProof/dump to specify the RootHash
Refactory of some code

Signed-off-by: p4u <p4u@dabax.net>
feature_chain_module
p4u 5 years ago
parent
commit
0c3587bb9c
2 changed files with 109 additions and 48 deletions
  1. +83
    -44
      service/censusmanager.go
  2. +26
    -4
      tree/tree.go

+ 83
- 44
service/censusmanager.go

@ -6,13 +6,13 @@ import (
"log" "log"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"time" "time"
tree "github.com/vocdoni/dvote-census/tree" tree "github.com/vocdoni/dvote-census/tree"
signature "github.com/vocdoni/dvote-relay/crypto/signature" signature "github.com/vocdoni/dvote-relay/crypto/signature"
) )
const hashSize = 32
const authTimeWindow = 10 // Time window (seconds) in which TimeStamp will be accepted if auth enabled const authTimeWindow = 10 // Time window (seconds) in which TimeStamp will be accepted if auth enabled
var MkTrees map[string]*tree.Tree // MerkleTree dvote-census library var MkTrees map[string]*tree.Tree // MerkleTree dvote-census library
var Signatures map[string]string var Signatures map[string]string
@ -20,6 +20,7 @@ var Signature signature.SignKeys // Signature dvote-relay library
type Claim struct { type Claim struct {
CensusID string `json:"censusID"` // References to MerkleTree namespace CensusID string `json:"censusID"` // References to MerkleTree namespace
RootHash string `json:"rootHash"` // References to MerkleTree rootHash
ClaimData string `json:"claimData"` // Data to add to the MerkleTree ClaimData string `json:"claimData"` // Data to add to the MerkleTree
ProofData string `json:"proofData"` // MerkleProof to check ProofData string `json:"proofData"` // MerkleProof to check
TimeStamp string `json:"timeStamp"` // Unix TimeStamp in seconds TimeStamp string `json:"timeStamp"` // Unix TimeStamp in seconds
@ -98,8 +99,9 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
} }
// Process data // Process data
log.Printf("Received censusID:{%s} claimData:{%s} proofData:{%s} timeStamp:{%s} signature:{%s}\n",
c.CensusID, c.ClaimData, c.ProofData, c.TimeStamp, c.Signature)
log.Printf("censusID:{%s} rootHash:{%s} claimData:{%s} proofData:{%s} timeStamp:{%s} signature:{%s}\n",
c.CensusID, c.RootHash, c.ClaimData, c.ProofData, c.TimeStamp, c.Signature)
authString := fmt.Sprintf("%s%s%s%s", c.CensusID, c.RootHash, c.ClaimData, c.TimeStamp)
resp.Error = false resp.Error = false
resp.Response = "" resp.Response = ""
censusFound := false censusFound := false
@ -114,14 +116,8 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
} }
if op == "add" { if op == "add" {
msg := fmt.Sprintf("%s%s%s", c.CensusID, c.ClaimData, c.TimeStamp)
if auth := checkAuth(c.TimeStamp, c.Signature, Signatures[c.CensusID], msg); auth {
if strings.HasPrefix(c.CensusID, "0x") {
resp.Error = true
resp.Response = "add claim to snapshot is not allowed"
} else {
err = MkTrees[c.CensusID].AddClaim([]byte(c.ClaimData))
}
if auth := checkAuth(c.TimeStamp, c.Signature, Signatures[c.CensusID], authString); auth {
err = MkTrees[c.CensusID].AddClaim([]byte(c.ClaimData))
} else { } else {
resp.Error = true resp.Error = true
resp.Response = "invalid authentication" resp.Response = "invalid authentication"
@ -129,61 +125,107 @@ func claimHandler(w http.ResponseWriter, req *http.Request, op string) {
} }
if op == "gen" { if op == "gen" {
resp.Response, err = MkTrees[c.CensusID].GenProof([]byte(c.ClaimData))
var t *tree.Tree
var err error
if len(c.RootHash) > 1 { //if rootHash specified
t, err = MkTrees[c.CensusID].Snapshot(c.RootHash)
if err != nil {
log.Printf("Snapshot error: %s", err.Error())
resp.Error = true
resp.Response = "invalid root hash"
reply(&resp, w)
return
}
} else { //if rootHash not specified use current tree
t = MkTrees[c.CensusID]
}
resp.Response, err = t.GenProof([]byte(c.ClaimData))
if err != nil {
resp.Error = true
resp.Response = err.Error()
reply(&resp, w)
return
}
} }
if op == "root" { if op == "root" {
resp.Response = MkTrees[c.CensusID].GetRoot() resp.Response = MkTrees[c.CensusID].GetRoot()
} }
if op == "idx" {
}
if op == "dump" { if op == "dump" {
values, err := MkTrees[c.CensusID].Dump()
var t *tree.Tree
if auth := checkAuth(c.TimeStamp, c.Signature, Signatures[c.CensusID], authString); !auth {
resp.Error = true
resp.Response = "invalid authentication"
reply(&resp, w)
return
}
if len(c.RootHash) > 1 { //if rootHash specified
t, err = MkTrees[c.CensusID].Snapshot(c.RootHash)
if err != nil {
log.Printf("Snapshot error: %s", err.Error())
resp.Error = true
resp.Response = "invalid root hash"
reply(&resp, w)
return
}
} else { //if rootHash not specified use current merkletree
t = MkTrees[c.CensusID]
}
//dump the claim data and return it
values, err := t.Dump()
if err != nil { if err != nil {
resp.Error = true resp.Error = true
resp.Response = fmt.Sprint(err)
resp.Response = err.Error()
} else { } else {
jValues, err := json.Marshal(values) jValues, err := json.Marshal(values)
if err != nil { if err != nil {
resp.Error = true resp.Error = true
resp.Response = fmt.Sprint(err)
resp.Response = err.Error()
} else { } else {
resp.Response = string(jValues) resp.Response = string(jValues)
} }
} }
} }
if op == "snapshot" {
msg := fmt.Sprintf("%s%s%s", c.CensusID, c.ClaimData, c.TimeStamp)
if auth := checkAuth(c.TimeStamp, c.Signature, Signatures[c.CensusID], msg); auth {
if strings.HasPrefix(c.CensusID, "0x") {
if op == "check" {
if len(c.ProofData) < 1 {
resp.Error = true
resp.Response = "proofData not provided"
reply(&resp, w)
return
}
var t *tree.Tree
if len(c.RootHash) > 1 { //if rootHash specified
t, err = MkTrees[c.CensusID].Snapshot(c.RootHash)
if err != nil {
log.Printf("Snapshot error: %s", err.Error())
resp.Error = true resp.Error = true
resp.Response = "snapshot an snapshot makes no sense"
} else {
snapshotNamespace, err := MkTrees[c.CensusID].Snapshot()
if err != nil {
resp.Error = true
resp.Response = fmt.Sprint(err)
} else {
resp.Response = snapshotNamespace
}
resp.Response = "invalid root hash"
reply(&resp, w)
return
} }
} else {
resp.Error = true
resp.Response = "invalid authentication"
} else { //if rootHash not specified use current merkletree
t = MkTrees[c.CensusID]
} }
}
if op == "check" {
if len(c.ProofData) < 1 {
validProof, err := t.CheckProof([]byte(c.ClaimData), c.ProofData)
if err != nil {
resp.Error = true resp.Error = true
resp.Response = "proofData not provided"
resp.Response = err.Error()
reply(&resp, w)
return
}
if validProof {
resp.Response = "valid"
} else { } else {
validProof, _ := MkTrees[c.CensusID].CheckProof([]byte(c.ClaimData), c.ProofData)
if validProof {
resp.Response = "valid"
} else {
resp.Response = "invalid"
}
resp.Response = "invalid"
} }
} }
@ -211,9 +253,6 @@ func Listen(port int, proto string) {
http.HandleFunc("/getRoot", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/getRoot", func(w http.ResponseWriter, r *http.Request) {
claimHandler(w, r, "root") claimHandler(w, r, "root")
}) })
http.HandleFunc("/snapshot", func(w http.ResponseWriter, r *http.Request) {
claimHandler(w, r, "snapshot")
})
http.HandleFunc("/dump", func(w http.ResponseWriter, r *http.Request) { http.HandleFunc("/dump", func(w http.ResponseWriter, r *http.Request) {
claimHandler(w, r, "dump") claimHandler(w, r, "dump")
}) })

+ 26
- 4
tree/tree.go

@ -1,8 +1,8 @@
package tree package tree
import ( import (
"bytes"
"errors" "errors"
"fmt"
"os/user" "os/user"
common3 "github.com/iden3/go-iden3/common" common3 "github.com/iden3/go-iden3/common"
@ -103,6 +103,16 @@ func (t *Tree) GetRoot() string {
return t.Tree.RootKey().String() return t.Tree.RootKey().String()
} }
func (t *Tree) GetIndex(data []byte) (string, error) {
e, err := t.GetClaim(data)
if err != nil {
return "", err
}
index, err := t.Tree.GetDataByIndex(e.Entry().HIndex())
return index.String(), err
}
/*
func (t *Tree) Dump() ([]string, error) { func (t *Tree) Dump() ([]string, error) {
var response []string var response []string
@ -121,8 +131,20 @@ func (t *Tree) Dump() ([]string, error) {
}) })
return response, err return response, err
} }
*/
func (t *Tree) Dump() (string, error) {
w := bytes.NewBufferString("")
err := t.Tree.DumpClaims(w, nil) // as rootKey we can pass a nil pointer, and it will use the current RootKey
return w.String(), err
}
func (t *Tree) Snapshot() (string, error) {
snapshotNamespace := t.Tree.RootKey().String()
return snapshotNamespace, nil
func (t *Tree) Snapshot(root string) (*Tree, error) {
var rootHash merkletree.Hash
copy(rootHash[:32], root)
mt, err := t.Tree.Snapshot(&rootHash)
snapshotTree := new(Tree)
snapshotTree.Tree = mt
return snapshotTree, err
} }

Loading…
Cancel
Save