Skip to content

Commit

Permalink
Consensus: working roster change in cosipbft
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilthoniel committed Apr 27, 2020
1 parent f38185a commit fa7a51e
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 79 deletions.
5 changes: 4 additions & 1 deletion blockchain/skipchain/mod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,13 @@ func (rand fakeRandGenerator) Read(buffer []byte) (int, error) {
}

type fakeGovernance struct {
viewchange.Governance
authority fake.CollectiveAuthority
}

func (gov fakeGovernance) GetAuthority(index uint64) (viewchange.EvolvableAuthority, error) {
return gov.authority, nil
}

func (gov fakeGovernance) GetChangeSet(uint64) viewchange.ChangeSet {
return viewchange.ChangeSet{}
}
85 changes: 74 additions & 11 deletions consensus/cosipbft/forward_link.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"go.dedis.ch/fabric/cosi"
"go.dedis.ch/fabric/crypto"
"go.dedis.ch/fabric/encoding"
"go.dedis.ch/fabric/mino"
"golang.org/x/xerrors"
)

Expand Down Expand Up @@ -60,12 +61,13 @@ func (fl forwardLink) Pack(enc encoding.ProtoMarshaler) (proto.Message, error) {
pb := &ForwardLinkProto{
From: fl.from,
To: fl.to,
ChangeSet: &ChangeSet{
Leader: fl.changeset.Leader,
},
}

var err error
changeset, err := fl.packChangeSet(enc)
if err != nil {
return nil, err
}
pb.ChangeSet = changeset

if fl.prepare != nil {
pb.Prepare, err = enc.PackAny(fl.prepare)
Expand All @@ -84,6 +86,34 @@ func (fl forwardLink) Pack(enc encoding.ProtoMarshaler) (proto.Message, error) {
return pb, nil
}

func (fl forwardLink) packChangeSet(enc encoding.ProtoMarshaler) (*ChangeSet, error) {
pb := &ChangeSet{
Leader: fl.changeset.Leader,
}

if len(fl.changeset.Add) > 0 {
pb.Add = make([]*Player, len(fl.changeset.Add))
for i, add := range fl.changeset.Add {
addr, err := add.Address.MarshalText()
if err != nil {
return nil, err
}

pubkey, err := enc.PackAny(add.PublicKey)
if err != nil {
return nil, err
}

pb.Add[i] = &Player{
Address: addr,
PublicKey: pubkey,
}
}
}

return pb, nil
}

func (fl forwardLink) computeHash(h hash.Hash, enc encoding.ProtoMarshaler) ([]byte, error) {
_, err := h.Write(fl.from)
if err != nil {
Expand Down Expand Up @@ -139,14 +169,18 @@ func (f sha256Factory) New() hash.Hash {
}

type unsecureChainFactory struct {
addrFactory mino.AddressFactory
pubkeyFactory crypto.PublicKeyFactory
signatureFactory crypto.SignatureFactory
verifierFactory crypto.VerifierFactory
hashFactory crypto.HashFactory
encoder encoding.ProtoMarshaler
}

func newUnsecureChainFactory(cosi cosi.CollectiveSigning) *unsecureChainFactory {
func newUnsecureChainFactory(cosi cosi.CollectiveSigning, m mino.Mino) *unsecureChainFactory {
return &unsecureChainFactory{
addrFactory: m.GetAddressFactory(),
pubkeyFactory: cosi.GetPublicKeyFactory(),
signatureFactory: cosi.GetSignatureFactory(),
verifierFactory: cosi.GetVerifierFactory(),
hashFactory: sha256Factory{},
Expand Down Expand Up @@ -174,9 +208,12 @@ func (f *unsecureChainFactory) decodeForwardLink(pb proto.Message) (forwardLink,
fl = forwardLink{
from: src.GetFrom(),
to: src.GetTo(),
changeset: viewchange.ChangeSet{
Leader: src.GetChangeSet().GetLeader(),
},
}

var err error
fl.changeset, err = f.decodeChangeSet(src.GetChangeSet())
if err != nil {
return fl, err
}

if src.GetPrepare() != nil {
Expand Down Expand Up @@ -207,6 +244,30 @@ func (f *unsecureChainFactory) decodeForwardLink(pb proto.Message) (forwardLink,
return fl, nil
}

func (f *unsecureChainFactory) decodeChangeSet(in *ChangeSet) (viewchange.ChangeSet, error) {
changeset := viewchange.ChangeSet{
Leader: in.GetLeader(),
}

if len(in.GetAdd()) > 0 {
changeset.Add = make([]viewchange.Player, len(in.GetAdd()))
for i, add := range in.GetAdd() {
addr := f.addrFactory.FromText(add.GetAddress())
pubkey, err := f.pubkeyFactory.FromProto(add.GetPublicKey())
if err != nil {
return changeset, err
}

changeset.Add[i] = viewchange.Player{
Address: addr,
PublicKey: pubkey,
}
}
}

return changeset, nil
}

func (f *unsecureChainFactory) FromProto(pb proto.Message) (consensus.Chain, error) {
var msg *ChainProto
switch in := pb.(type) {
Expand Down Expand Up @@ -246,9 +307,11 @@ type chainFactory struct {
// newChainFactory returns a new instance of a seal factory that will create
// forward links for appropriate protobuf messages and return an error
// otherwise.
func newChainFactory(cosi cosi.CollectiveSigning, authority viewchange.EvolvableAuthority) *chainFactory {
func newChainFactory(cosi cosi.CollectiveSigning, m mino.Mino,
authority viewchange.EvolvableAuthority) *chainFactory {

return &chainFactory{
unsecureChainFactory: newUnsecureChainFactory(cosi),
unsecureChainFactory: newUnsecureChainFactory(cosi, m),
authority: authority,
}
}
Expand Down Expand Up @@ -277,7 +340,7 @@ func (f *chainFactory) verify(chain forwardLinkChain) error {

lastIndex := len(chain.links) - 1
for i, link := range chain.links {
verifier, err := f.verifierFactory.FromAuthority(f.authority)
verifier, err := f.verifierFactory.FromAuthority(authority)
if err != nil {
return xerrors.Errorf("couldn't create the verifier: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion consensus/cosipbft/forward_link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ func TestChainFactory_FromProto(t *testing.T) {
authority := fake.NewAuthority(3, fake.NewSigner)
authority.Call = call

factory := newChainFactory(&fakeCosi{}, authority)
factory := newChainFactory(&fakeCosi{}, fake.Mino{}, authority)
chain, err := factory.FromProto(chainpb)
require.NoError(t, err)
require.NotNil(t, chain)
Expand Down
127 changes: 98 additions & 29 deletions consensus/cosipbft/messages.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions consensus/cosipbft/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ option go_package = ".;cosipbft";

import "google/protobuf/any.proto";

message Player {
bytes address = 1;
google.protobuf.Any publicKey = 2;
}

message ChangeSet {
uint32 leader = 1;
repeated Player add = 2;
repeated Player remove = 3;
}

// ForwardLinkProto is the message representing a forward link between two
Expand Down
Loading

0 comments on commit fa7a51e

Please sign in to comment.