Skip to content

Commit

Permalink
api: add namespace arg on getProcessList
Browse files Browse the repository at this point in the history
- The namespace of a processes contract can be passed
  as an argument to the getProcessList request.
  This allows to fetch only the processes that are registred
  on a specific namespace and not all the processes of the vochain
  for a given entity.
- The 0 value is valid and represents the namespace 0.
- Is possible to obtain all the processes of all namespaces
  just by not passing the namespace argument on the request at all.
  • Loading branch information
jordipainan committed Feb 24, 2021
1 parent 3543401 commit cdbb0a0
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 20 deletions.
1 change: 0 additions & 1 deletion chain/contractWrappers.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ func NewVotingHandle(contractsAddress []common.Address, dialEndpoint string) (*V

// NewProcessTxArgs gets the info of a created process on the processes contract and creates a NewProcessTx instance
func (ph *VotingHandle) NewProcessTxArgs(ctx context.Context, pid [types.ProcessIDsize]byte, namespace uint16) (*models.NewProcessTx, error) {
// TODO: @jordipainan What to do with namespace?
// get process info from the processes contract
processMeta, err := ph.VotingProcess.Get(&ethbind.CallOpts{Context: ctx}, pid)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion router/voteCallbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ func (r *Router) getProcessList(request routerRequest) {
if max > MaxListIterations || max <= 0 {
max = MaxListIterations
}
processList, err := r.Scrutinizer.ProcessList(request.EntityId, request.FromID, max)
processList, err := r.Scrutinizer.ProcessList(request.EntityId, request.FromID, max, request.Namespace)
if err != nil {
r.sendError(request, fmt.Sprintf("cannot get entity process list: (%s)", err))
return
Expand Down
1 change: 1 addition & 0 deletions types/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type MetaRequest struct {
ListSize int64 `json:"listSize,omitempty"`
Method string `json:"method"`
Name string `json:"name,omitempty"`
Namespace *uint32 `json:"namespace,omitempty"`
Nullifier HexBytes `json:"nullifier,omitempty"`
Payload []byte `json:"payload,omitempty"`
ProcessID HexBytes `json:"processId,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion vochain/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ func NewProcessTxCheck(vtx *models.Tx, state *State) (*models.Process, error) {
return tx.Process, nil
}

// SetProcessTxCheck is an abstraction of ABCI checkTx for canceling an existing process
// SetProcessTxCheck is an abstraction of ABCI checkTx for updating an existing process
func SetProcessTxCheck(vtx *models.Tx, state *State) error {
tx := vtx.GetSetProcess()
// check signature available
Expand Down
16 changes: 13 additions & 3 deletions vochain/scrutinizer/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func (s *Scrutinizer) ProcessInfo(pid []byte) (*models.Process, error) {
}

// ProcessList returns the list of processes (finished or not) for a specific entity.
func (s *Scrutinizer) ProcessList(entityID []byte, fromID []byte, max int64) ([][]byte, error) {
func (s *Scrutinizer) ProcessList(entityID []byte, fromID []byte, max int64, namespace *uint32) ([][]byte, error) {
plistkey := []byte{types.ScrutinizerEntityPrefix}
plistkey = append(plistkey, entityID...)
processList, err := s.Storage.Get(plistkey)
Expand All @@ -37,8 +37,18 @@ func (s *Scrutinizer) ProcessList(entityID []byte, fromID []byte, max int64) ([]
if !fromLock {
keyCopy := make([]byte, len(process))
copy(keyCopy, process)
processListResult = append(processListResult, keyCopy)
max--
if p, err := s.VochainState.Process(keyCopy, true); err != nil {
log.Debugf("error fetching process %x: %s", p.ProcessId, err)
continue
} else if namespace == nil {
processListResult = append(processListResult, keyCopy)
max--
} else {
if p.Namespace == *namespace {
processListResult = append(processListResult, keyCopy)
max--
}
}
}
if fromLock && bytes.Equal(fromID, process) {
fromLock = false
Expand Down
109 changes: 95 additions & 14 deletions vochain/scrutinizer/scrutinizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
qt "github.com/frankban/quicktest"
"go.vocdoni.io/dvote/crypto/ethereum"
"go.vocdoni.io/dvote/crypto/nacl"
Expand Down Expand Up @@ -71,33 +72,115 @@ func TestProcessList(t *testing.T) {
}

func testProcessList(t *testing.T, procsCount int) {
log.Init("info", "stdout")
state, err := vochain.NewState(t.TempDir())

app, err := vochain.NewBaseApplication(t.TempDir())
if err != nil {
t.Fatal(err)
}

sc, err := NewScrutinizer(t.TempDir(), state)
if err != nil {
oracle := ethereum.SignKeys{}
if err := oracle.Generate(); err != nil {
t.Fatal(err)
}
if err := app.State.AddOracle(common.HexToAddress(oracle.AddressString())); err != nil {
t.Fatal(err)
}

// Add 10 entities and process for storing random content
for i := 0; i < 10; i++ {
sc.addEntity(util.RandomBytes(20), util.RandomBytes(32))
sc, err := NewScrutinizer(t.TempDir(), app.State)
if err != nil {
t.Fatal(err)
}

// For a entity, add 25 processes (this will be the queried entity)
// For a entity, add processes (this will be the queried entity)
eidTest := util.RandomBytes(20)
for i := 0; i < procsCount; i++ {
sc.addEntity(eidTest, util.RandomBytes(32))
// Add a process with status=READY and interruptible=true
censusURI := "ipfs://123456789"
pid := util.RandomBytes(types.ProcessIDsize)
process := &models.Process{
ProcessId: pid,
StartBlock: 0,
EnvelopeType: &models.EnvelopeType{EncryptedVotes: false},
Mode: &models.ProcessMode{Interruptible: true},
VoteOptions: &models.ProcessVoteOptions{MaxCount: 16, MaxValue: 16},
Status: models.ProcessStatus_READY,
EntityId: eidTest,
CensusRoot: util.RandomBytes(32),
CensusURI: &censusURI,
CensusOrigin: models.CensusOrigin_OFF_CHAIN_TREE,
BlockCount: 1024,
Namespace: 0,
}
t.Logf("adding process %x", process.ProcessId)
if err := app.State.AddProcess(process); err != nil {
t.Fatal(err)
}
sc.addEntity(eidTest, process.ProcessId)
}

defaultNamespace := new(uint32)
*defaultNamespace = 0
procs := processList(t, sc, eidTest, procsCount, 155, defaultNamespace)
if len(procs) != procsCount {
t.Fatalf("expected %d processes, got %d", procsCount, len(procs))
}

// try adding a new with different namespace
censusURI := "ipfs://123456789"
process := &models.Process{
ProcessId: util.RandomBytes(types.ProcessIDsize),
StartBlock: 0,
EnvelopeType: &models.EnvelopeType{EncryptedVotes: false},
Mode: &models.ProcessMode{Interruptible: true},
VoteOptions: &models.ProcessVoteOptions{MaxCount: 16, MaxValue: 16},
Status: models.ProcessStatus_READY,
EntityId: eidTest,
CensusRoot: util.RandomBytes(32),
CensusURI: &censusURI,
CensusOrigin: models.CensusOrigin_OFF_CHAIN_TREE,
BlockCount: 1024,
Namespace: 1,
}
t.Logf("adding process %x", process.ProcessId)
if err := app.State.AddProcess(process); err != nil {
t.Fatal(err)
}
sc.addEntity(eidTest, process.ProcessId)

procs2 := processList(t, sc, eidTest, procsCount, 155, defaultNamespace)
if len(procs2) != procsCount {
t.Fatalf("expected %d processes, got %d", procsCount, len(procs2))
}
// add new process
process.ProcessId = util.RandomBytes(types.ProcessIDsize)
process.Namespace = 0
t.Logf("adding process %x", process.ProcessId)
if err := app.State.AddProcess(process); err != nil {
t.Fatal(err)
}
sc.addEntity(eidTest, process.ProcessId)

// try get processList with another max value
procs3 := processList(t, sc, eidTest, procsCount+1, 155, defaultNamespace)
// should count the last process added as the namespace is the ones matching with the requested
if len(procs3) != procsCount+1 {
t.Fatalf("expected %d processes, got %d", procsCount+1, len(procs3))
}

// should count all processes
procs4 := processList(t, sc, eidTest, procsCount+2, 155, nil)
// should count the last process added as the namespace is the ones matching with the requested
if len(procs4) != procsCount+2 {
t.Fatalf("expected %d processes, got %d", procsCount+2, len(procs4))
}
}

func processList(t *testing.T, sc *Scrutinizer, eid []byte, procsCount int, max int64, namespace *uint32) map[string]bool {
procs := make(map[string]bool)
last := []byte{}
var list [][]byte
var err error
for len(procs) < procsCount {
list, err = sc.ProcessList(eidTest, last, 10)
list, err = sc.ProcessList(eid, last, max, namespace)
if err != nil {
t.Fatal(err)
}
Expand All @@ -113,9 +196,7 @@ func testProcessList(t *testing.T, procsCount int) {
}
last = list[len(list)-1]
}
if len(procs) != procsCount {
t.Fatalf("expected %d processes, got %d", procsCount, len(procs))
}
return procs
}

func TestResults(t *testing.T) {
Expand Down

0 comments on commit cdbb0a0

Please sign in to comment.