diff --git a/network/dataStructures/extendedRoundStorage.go b/network/dataStructures/extendedRoundStorage.go index 2d05f54f6641642b411c207bd308d515616d0a3e..38342548330530febb0a2dd2ce01e4c75cf491f7 100644 --- a/network/dataStructures/extendedRoundStorage.go +++ b/network/dataStructures/extendedRoundStorage.go @@ -5,6 +5,9 @@ import ( "gitlab.com/elixxir/primitives/id" ) +// The ExtendedRoundStorage (ERS) interface allows storing rounds inside of an external database for clients to pull +// from, because the ring buffer only contains a limited number of them while clients might need to go further back +// into history. type ExternalRoundStorage interface { // Store: stores the round info inside the underlying storage medium, which generally is a database. Store will // add the round info to the database if it doesn't exist and will only overwrite the data if it does exist in the diff --git a/network/historicalRoundData.go b/network/historicalRoundData.go index 53ac093d0551150452afe900984e0bd14f5f5e9a..1dba5e83861d081e4a2ebaffd3873d2dca9f34bf 100644 --- a/network/historicalRoundData.go +++ b/network/historicalRoundData.go @@ -6,6 +6,7 @@ import ( "gitlab.com/elixxir/primitives/id" ) +// Calls the underlying interface's function to get a specific round from history func (i *Instance) GetHistoricalRound(id id.Round) (*pb.RoundInfo, error) { if i.ers != nil { return i.ers.Retrieve(id) @@ -13,6 +14,7 @@ func (i *Instance) GetHistoricalRound(id id.Round) (*pb.RoundInfo, error) { return nil, errors.New("no ExternalRoundStorage object was defined on instance creation") } +// Calls the underlying interface's function to get specific rounds from history func (i *Instance) GetHistoricalRounds(rounds []id.Round) ([]*pb.RoundInfo, error) { if i.ers != nil { return i.ers.RetrieveMany(rounds) @@ -20,6 +22,7 @@ func (i *Instance) GetHistoricalRounds(rounds []id.Round) ([]*pb.RoundInfo, erro return nil, errors.New("no ExternalRoundStorage object was defined on instance creation") } +// Calls the underlying interface's function to get a range of rounds from history func (i *Instance) GetHistoricalRoundRange(first, last id.Round) ([]*pb.RoundInfo, error) { if i.ers != nil { return i.ers.RetrieveRange(first, last) diff --git a/network/historicalRoundData_test.go b/network/historicalRoundData_test.go index be60551932f44aef6bc93ff6eed5a14ec319ab11..24862048aaf596ae43d3df262f1dd49c64d16cfe 100644 --- a/network/historicalRoundData_test.go +++ b/network/historicalRoundData_test.go @@ -4,12 +4,7 @@ import ( jww "github.com/spf13/jwalterweatherman" pb "gitlab.com/elixxir/comms/mixmessages" ds "gitlab.com/elixxir/comms/network/dataStructures" - "gitlab.com/elixxir/comms/testkeys" - "gitlab.com/elixxir/comms/testutils" - "gitlab.com/elixxir/crypto/signature" - "gitlab.com/elixxir/crypto/signature/rsa" "gitlab.com/elixxir/primitives/id" - "gitlab.com/xx_network/comms/connect" "testing" ) @@ -322,68 +317,3 @@ func TestInstance_GetHistoricalRounds(t *testing.T) { } } } - -// Test that a new round update is inputted into the ERS map -func TestInstance_RoundUpdateAddsToERS(t *testing.T) { - // Get signing certificates - priv := testkeys.LoadFromPath(testkeys.GetNodeKeyPath()) - privKey, err := rsa.LoadPrivateKeyFromPem(priv) - pub := testkeys.LoadFromPath(testkeys.GetNodeCertPath()) - if err != nil { - t.Errorf("Could not generate rsa key: %s", err) - } - - // Create a basic testing NDF and sign it - f := &pb.NDF{} - f.Ndf = []byte(testutils.ExampleJSON) - baseNDF := testutils.NDF - if err != nil { - t.Errorf("Could not generate serialized ndf: %s", err) - } - err = signature.Sign(f, privKey) - if err != nil { - t.Errorf("Could not generate serialized ndf: %s", err) - } - - // Build the Instance object with an ERS memory map - pc := &connect.ProtoComms{} - var ers ds.ExternalRoundStorage = ersMemMap{rounds: make(map[id.Round]*pb.RoundInfo)} - i, err := NewInstance(pc, baseNDF, baseNDF, ers) - if err != nil { - t.Error(nil) - } - - // Add a permissioning host - _, err = i.comm.AddHost(&id.Permissioning, "0.0.0.0:4200", pub, false, true) - if err != nil { - t.Errorf("Failed to add permissioning host: %+v", err) - } - - // Build a basic RoundInfo object and sign it - r := &pb.RoundInfo{ - ID: 2, - UpdateID: 4, - } - err = signature.Sign(r, privKey) - if err != nil { - t.Errorf(err.Error()) - } - - // Cause a RoundUpdate - err = i.RoundUpdate(r) - if err != nil { - t.Errorf(err.Error()) - } - - // Check that the round info was stored correctly - rr, err := ers.Retrieve(id.Round(r.ID)) - if err != nil { - t.Errorf(err.Error()) - } - if rr == nil { - t.Fatalf("returned round info was nil") - } - if rr.ID != r.ID || rr.UpdateID != r.UpdateID { - t.Errorf("Second returned round and original mismatched IDs") - } -} diff --git a/network/instance.go b/network/instance.go index 35e80b8b3b54b35fcef3c4bc95bead129bf9493b..5ff01d8ad32b35769ffba79affa8fdb1f4e44df1 100644 --- a/network/instance.go +++ b/network/instance.go @@ -37,7 +37,8 @@ type Instance struct { ipOverride *ds.IpOverrideList } -// Initializer for instance structs from base comms and NDF +// Initializer for instance structs from base comms and NDF, you can put in nil for +// ERS if you don't want to use it func NewInstance(c *connect.ProtoComms, partial, full *ndf.NetworkDefinition, ers ds.ExternalRoundStorage) (*Instance, error) { var partialNdf *SecuredNdf @@ -102,9 +103,8 @@ func NewInstance(c *connect.ProtoComms, partial, full *ndf.NetworkDefinition, } } - if ers != nil { - i.ers = ers - } + // Set our ERS to the passed in ERS object (or nil) + i.ers = ers return i, nil } diff --git a/network/instance_test.go b/network/instance_test.go index f7869a917894669514c3e3799d243e8fe0a47b60..e855274a00f7925853c709586850fe0d33ac85ff 100644 --- a/network/instance_test.go +++ b/network/instance_test.go @@ -666,3 +666,68 @@ func createBadNdf(t *testing.T) *mixmessages.NDF { return f } + +// Test that a new round update is inputted into the ERS map +func TestInstance_RoundUpdateAddsToERS(t *testing.T) { + // Get signing certificates + priv := testkeys.LoadFromPath(testkeys.GetNodeKeyPath()) + privKey, err := rsa.LoadPrivateKeyFromPem(priv) + pub := testkeys.LoadFromPath(testkeys.GetNodeCertPath()) + if err != nil { + t.Errorf("Could not generate rsa key: %s", err) + } + + // Create a basic testing NDF and sign it + f := &pb.NDF{} + f.Ndf = []byte(testutils.ExampleJSON) + baseNDF := testutils.NDF + if err != nil { + t.Errorf("Could not generate serialized ndf: %s", err) + } + err = signature.Sign(f, privKey) + if err != nil { + t.Errorf("Could not generate serialized ndf: %s", err) + } + + // Build the Instance object with an ERS memory map + pc := &connect.ProtoComms{} + var ers ds.ExternalRoundStorage = ersMemMap{rounds: make(map[id.Round]*pb.RoundInfo)} + i, err := NewInstance(pc, baseNDF, baseNDF, ers) + if err != nil { + t.Error(nil) + } + + // Add a permissioning host + _, err = i.comm.AddHost(&id.Permissioning, "0.0.0.0:4200", pub, false, true) + if err != nil { + t.Errorf("Failed to add permissioning host: %+v", err) + } + + // Build a basic RoundInfo object and sign it + r := &pb.RoundInfo{ + ID: 2, + UpdateID: 4, + } + err = signature.Sign(r, privKey) + if err != nil { + t.Errorf(err.Error()) + } + + // Cause a RoundUpdate + err = i.RoundUpdate(r) + if err != nil { + t.Errorf(err.Error()) + } + + // Check that the round info was stored correctly + rr, err := ers.Retrieve(id.Round(r.ID)) + if err != nil { + t.Errorf(err.Error()) + } + if rr == nil { + t.Fatalf("returned round info was nil") + } + if rr.ID != r.ID || rr.UpdateID != r.UpdateID { + t.Errorf("Second returned round and original mismatched IDs") + } +}