Merge pull request #106 from ava-labs/snowball-testing

Clarify that the snowball byzantine struct is only for testing
This commit is contained in:
Stephen Buttolph 2020-06-22 01:25:01 -04:00 committed by GitHub
commit db01f2e7e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 104 deletions

View File

@ -1,48 +0,0 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package snowball
import (
"github.com/ava-labs/gecko/ids"
)
// ByzantineFactory implements Factory by returning a byzantine struct
type ByzantineFactory struct{}
// New implements Factory
func (ByzantineFactory) New() Consensus { return &Byzantine{} }
// Byzantine is a naive implementation of a multi-choice snowball instance
type Byzantine struct {
// params contains all the configurations of a snowball instance
params Parameters
// Hardcode the preference
preference ids.ID
}
// Initialize implements the Consensus interface
func (b *Byzantine) Initialize(params Parameters, choice ids.ID) {
b.params = params
b.preference = choice
}
// Parameters implements the Consensus interface
func (b *Byzantine) Parameters() Parameters { return b.params }
// Add implements the Consensus interface
func (b *Byzantine) Add(choice ids.ID) {}
// Preference implements the Consensus interface
func (b *Byzantine) Preference() ids.ID { return b.preference }
// RecordPoll implements the Consensus interface
func (b *Byzantine) RecordPoll(votes ids.Bag) {}
// RecordUnsuccessfulPoll implements the Consensus interface
func (b *Byzantine) RecordUnsuccessfulPoll() {}
// Finalized implements the Consensus interface
func (b *Byzantine) Finalized() bool { return true }
func (b *Byzantine) String() string { return b.preference.String() }

View File

@ -1,54 +0,0 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package snowball
import (
"testing"
"github.com/ava-labs/gecko/ids"
"github.com/prometheus/client_golang/prometheus"
)
func TestByzantine(t *testing.T) {
params := Parameters{
Metrics: prometheus.NewRegistry(),
K: 1, Alpha: 1, BetaVirtuous: 3, BetaRogue: 5,
}
byzFactory := ByzantineFactory{}
byz := byzFactory.New()
byz.Initialize(params, Blue)
if ret := byz.Parameters(); ret != params {
t.Fatalf("Should have returned the correct params")
}
byz.Add(Green)
if pref := byz.Preference(); !pref.Equals(Blue) {
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
}
oneGreen := ids.Bag{}
oneGreen.Add(Green)
byz.RecordPoll(oneGreen)
if pref := byz.Preference(); !pref.Equals(Blue) {
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
}
byz.RecordUnsuccessfulPoll()
if pref := byz.Preference(); !pref.Equals(Blue) {
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
}
if final := byz.Finalized(); !final {
t.Fatalf("Should be marked as accepted")
}
if str := byz.String(); str != Blue.String() {
t.Fatalf("Wrong string, expected %s returned %s", Blue, str)
}
}

View File

@ -11,6 +11,46 @@ import (
"github.com/ava-labs/gecko/ids" "github.com/ava-labs/gecko/ids"
) )
// ByzantineFactory implements Factory by returning a byzantine struct
type ByzantineFactory struct{}
// New implements Factory
func (ByzantineFactory) New() Consensus { return &Byzantine{} }
// Byzantine is a naive implementation of a multi-choice snowball instance
type Byzantine struct {
// params contains all the configurations of a snowball instance
params Parameters
// Hardcode the preference
preference ids.ID
}
// Initialize implements the Consensus interface
func (b *Byzantine) Initialize(params Parameters, choice ids.ID) {
b.params = params
b.preference = choice
}
// Parameters implements the Consensus interface
func (b *Byzantine) Parameters() Parameters { return b.params }
// Add implements the Consensus interface
func (b *Byzantine) Add(choice ids.ID) {}
// Preference implements the Consensus interface
func (b *Byzantine) Preference() ids.ID { return b.preference }
// RecordPoll implements the Consensus interface
func (b *Byzantine) RecordPoll(votes ids.Bag) {}
// RecordUnsuccessfulPoll implements the Consensus interface
func (b *Byzantine) RecordUnsuccessfulPoll() {}
// Finalized implements the Consensus interface
func (b *Byzantine) Finalized() bool { return true }
func (b *Byzantine) String() string { return b.preference.String() }
var ( var (
Red = ids.Empty.Prefix(0) Red = ids.Empty.Prefix(0)
Blue = ids.Empty.Prefix(1) Blue = ids.Empty.Prefix(1)

View File

@ -34,7 +34,7 @@ func (f *Flat) Parameters() Parameters { return f.params }
// RecordPoll implements the Consensus interface // RecordPoll implements the Consensus interface
func (f *Flat) RecordPoll(votes ids.Bag) { func (f *Flat) RecordPoll(votes ids.Bag) {
if pollMode, numVotes := votes.Mode(); numVotes >= f.params.Alpha { if pollMode, numVotes := votes.Mode(); numVotes >= f.params.Alpha {
f.nnarySnowball.RecordSuccessfulPoll(pollMode) f.RecordSuccessfulPoll(pollMode)
} else { } else {
f.RecordUnsuccessfulPoll() f.RecordUnsuccessfulPoll()
} }

View File

@ -51,7 +51,7 @@ func (sf *nnarySnowflake) RecordSuccessfulPoll(choice ids.ID) {
return // This instace is already decided. return // This instace is already decided.
} }
if preference := sf.nnarySlush.Preference(); preference.Equals(choice) { if preference := sf.Preference(); preference.Equals(choice) {
sf.confidence++ sf.confidence++
} else { } else {
// confidence is set to 1 because there has already been 1 successful // confidence is set to 1 because there has already been 1 successful