Skip to content

Commit

Permalink
add evaluator config item
Browse files Browse the repository at this point in the history
  • Loading branch information
nikkolasg committed Mar 27, 2019
1 parent 64de81f commit 0b98da4
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 18 deletions.
4 changes: 2 additions & 2 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Config struct {

// NewEvaluatorStrategy returns the signature evaluator to use during the
// Handel round.
NewEvaluatorStrategy func(s signatureStore, h *Handel) SigEvaluator
NewEvaluatorStrategy func(s SignatureStore, h *Handel) SigEvaluator

// NewTimeoutStrategy returns the Timeout strategy to use during the Handel
// round. By default, it uses the linear timeout strategy.
Expand Down Expand Up @@ -107,7 +107,7 @@ var DefaultPartitioner = func(id int32, reg Registry, logger Logger) Partitioner

// DefaultEvaluatorStrategy returns an evaluator based on the store's own
// evaluation strategy.
var DefaultEvaluatorStrategy = func(store signatureStore, h *Handel) SigEvaluator {
var DefaultEvaluatorStrategy = func(store SignatureStore, h *Handel) SigEvaluator {
return newEvaluatorStore(store)
}

Expand Down
2 changes: 1 addition & 1 deletion handel.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ type Handel struct {
// signature over the message
sig Signature
// signature store with different merging/caching strategy
store signatureStore
store SignatureStore
// processing of signature - verification strategy
proc signatureProcessing
// all actors registered that acts on a new signature
Expand Down
9 changes: 5 additions & 4 deletions processing.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type incomingSig struct {
func (is *incomingSig) Individual() bool {
return is.isInd
}

// signatureProcessing is an interface responsible for verifying incoming
// multi-signature. It can decides to drop some incoming signatures if deemed
// useless. It outputs verified signatures to the main handel processing logic
Expand Down Expand Up @@ -77,15 +78,15 @@ func newEvaluator1() SigEvaluator {

// EvaluatorStore is a wrapper around the store's evaluate strategy.
type EvaluatorStore struct {
store signatureStore
store SignatureStore
}

// Evaluate implements the SigEvaluator strategy.
func (f *EvaluatorStore) Evaluate(sp *incomingSig) int {
return f.store.Evaluate(sp)
}

func newEvaluatorStore(store signatureStore) SigEvaluator {
func newEvaluatorStore(store SignatureStore) SigEvaluator {
return &EvaluatorStore{store: store}
}

Expand Down Expand Up @@ -334,7 +335,7 @@ func (f *evaluatorProcessing) verifyAndPublish(sp *incomingSig) {
// fifo queue, verifying all incoming signatures, not matter relevant or not.
type fifoProcessing struct {
sync.Mutex
store signatureStore
store SignatureStore
part Partitioner
cons Constructor
msg []byte
Expand All @@ -346,7 +347,7 @@ type fifoProcessing struct {
// newFifoProcessing returns a signatureProcessing implementation using a fifo
// queue. It needs the store to store the valid signatures, the partitioner +
// constructor + msg to verify the signatures.
func newFifoProcessing(store signatureStore, part Partitioner,
func newFifoProcessing(store SignatureStore, part Partitioner,
c Constructor, msg []byte) signatureProcessing {
return &fifoProcessing{
part: part,
Expand Down
8 changes: 4 additions & 4 deletions report.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,22 @@ func (r *ReportHandel) Processing() Reporter {

// ReportStore is a Store that can report some statistics about the storage
type ReportStore struct {
signatureStore
SignatureStore
sucessReplaced int64
replacedTrial int64
}

// newReportStore returns a signatureStore with som eadditional reporting
// capabilities
func newReportStore(s signatureStore) signatureStore {
func newReportStore(s SignatureStore) SignatureStore {
return &ReportStore{
signatureStore: s,
SignatureStore: s,
}
}

// Store implements the signatureStore interface
func (r *ReportStore) Store(sp *incomingSig) *MultiSignature {
ms := r.signatureStore.Store(sp)
ms := r.SignatureStore.Store(sp)
if ms != nil {
r.sucessReplaced++
} else {
Expand Down
34 changes: 34 additions & 0 deletions simul/confgenerator/confgenerator.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func main() {
//baseNodes := []int{100, 300, 500, 1000, 1500, 2000, 2500,4000 3000, 4000}
baseNodes := []int{100, 300, 500, 1000, 1500, 2000}

evaluatorScenario(configDir, defaultConf, handel, baseNodes, getProcessF(2))
nodeCountScenario(configDir, defaultConf, handel, baseNodes, getProcessF(1))
updateCountScenario(configDir, defaultConf, handel, baseNodes, getProcessF(1))
practicalScenario(configDir, defaultConf, handel, baseNodes, thresholdProcessF(2000))
Expand All @@ -65,6 +66,39 @@ func main() {
timeoutIncScenario(configDir, defaultConf, handel, baseNodes, fixedProcesses)
periodIncScenario(configDir, defaultConf, handel, baseNodes, fixedProcesses)
}
func evaluatorScenario(dir string, defaultConf lib.Config, handel *lib.HandelConfig, baseNodes []int, procF func(int) int) {
nodes := baseNodes
thr := 0.99
failing := 0
evaluators := []string{"store", "equal"}
for _, evaluator := range evaluators {
var runs []lib.RunConfig
for _, node := range nodes {
handelConf := &lib.HandelConfig{
Period: handel.Period,
UpdateCount: handel.UpdateCount,
NodeCount: handel.NodeCount,
Timeout: handel.Timeout,
UnsafeSleepTimeOnSigVerify: handel.UnsafeSleepTimeOnSigVerify,
Evaluator: evaluator,
}

run := lib.RunConfig{
Nodes: node,
Threshold: thrF(thr)(node),
Failing: failing,
Processes: procF(node),
Handel: handelConf,
}
runs = append(runs, run)
}
defaultConf.Runs = runs
fileName := fmt.Sprintf("2000evaluator_%s.toml", evaluator)
if err := defaultConf.WriteTo(filepath.Join(dir, fileName)); err != nil {
panic(err)
}
}
}
func nodeCountScenario(dir string, defaultConf lib.Config, handel *lib.HandelConfig, baseNodes []int, procF func(int) int) {
nodes := baseNodes
thr := 0.99
Expand Down
1 change: 1 addition & 0 deletions simul/config_example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ Retrials = 1
NodeCount = 10
Timeout = "50ms"
UnsafeSleepTimeOnSigVerify = 0
Evaluator = "store"
9 changes: 9 additions & 0 deletions simul/lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ type HandelConfig struct {
Timeout string
// UnsafeSleepTimeOnSigVerify
UnsafeSleepTimeOnSigVerify int

// which queue evaluator are we choosing
Evaluator string
}

// LoadConfig looks up the given file to unmarshal a TOML encoded Config.
Expand Down Expand Up @@ -306,6 +309,12 @@ func (r *RunConfig) GetHandelConfig() *handel.Config {
if err == nil {
ch.NewTimeoutStrategy = handel.LinearTimeoutConstructor(dd)
}
switch r.Handel.Evaluator {
case "store":
ch.NewEvaluatorStrategy = handel.DefaultEvaluatorStrategy
case "equal":
ch.NewEvaluatorStrategy = func(handel.SignatureStore, *handel.Handel) handel.SigEvaluator { return new(handel.Evaluator1) }
}
return ch
}

Expand Down
14 changes: 7 additions & 7 deletions store.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"sync"
)

// signatureStore is a generic interface whose role is to store received valid
// SignatureStore is a generic interface whose role is to store received valid
// multisignature, and to be able to serve the best multisignature received so
// far at a given level. Different strategies can be implemented such as keeping
// only the best one, merging two non-colluding multi-signatures etc.
// NOTE: implementation MUST be thread-safe.
type signatureStore interface {
type SignatureStore interface {
SigEvaluator
// Store saves the multi-signature if it is "better"
// (implementation-dependent) than the one previously saved at the same
Expand Down Expand Up @@ -126,7 +126,7 @@ func (r *replaceStore) unsafeEvaluate(sp *incomingSig) int {

// We take into account the individual signatures already verified we could add.
withIndiv := sp.ms.BitSet.Or(r.indivSigsVerified[sp.level])
newTotal := 0 // The number of signatures in our new best
newTotal := 0 // The number of signatures in our new best
addedSigs := 0 // The number of sigs we add with our new best compared to the existing one. Can be negative
combineCt := 0 // The number of sigs in our new best that come from combining it with individual sigs

Expand All @@ -145,10 +145,10 @@ func (r *replaceStore) unsafeEvaluate(sp *incomingSig) int {
} else {
// We can merge our current best and the new ms. We also add individual
// signatures that we previously verified
finalSet := withIndiv.Or(curBestMs.BitSet)
finalSet := withIndiv.Or(curBestMs.BitSet)
newTotal = finalSet.Cardinality()
addedSigs = newTotal - curBestMs.BitSet.Cardinality()
combineCt = finalSet.Xor(curBestMs.BitSet.Or(sp.ms.BitSet)).Cardinality()
combineCt = finalSet.Xor(curBestMs.BitSet.Or(sp.ms.BitSet)).Cardinality()
}
}

Expand All @@ -164,12 +164,12 @@ func (r *replaceStore) unsafeEvaluate(sp *incomingSig) int {
if newTotal == toReceive {
// This completes a level! That's the best options for us. We give
// a greater value to the first levels/
return 1000000 - int(sp.level) * 10 - combineCt
return 1000000 - int(sp.level)*10 - combineCt
}

// It adds value, but does not complete a level. We
// favorize the older level but take into account the number of sigs we receive as well.
return 100000 - int(sp.level)*100 + addedSigs * 10 - combineCt
return 100000 - int(sp.level)*100 + addedSigs*10 - combineCt
}

// Returns the signature to store (can be combined with the existing one or previously verified signatures) and
Expand Down

0 comments on commit 0b98da4

Please sign in to comment.