Skip to content

Commit

Permalink
[FAB-702] - Add gossip node metastate object
Browse files Browse the repository at this point in the history
Add struct to store current state of the ledger at gossip node
to be able send this information accross all gossiping nodes and
use it to complete missing blocks of state gaps.

Change-Id: Id0f838ce3dcf4ad9adbfd95ddf14b42c62f84839
Signed-off-by: Artem Barger <bartem@il.ibm.com>
  • Loading branch information
C0rWin committed Oct 31, 2016
1 parent b4473da commit b57dbfa
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
72 changes: 72 additions & 0 deletions gossip/state/metastate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package state

import (
"bytes"
"encoding/binary"
)

// Metadata information to store the information about current
// height of the ledger (last accepted block sequence number).
type NodeMetastate struct {

// Actual ledger height
LedgerHeight uint64
}

// Create new meta data with given ledger height148.69
func NewNodeMetastate(height uint64) *NodeMetastate {
return &NodeMetastate{height}
}

// Decodes meta state into byte array for serialization
func (n *NodeMetastate) Bytes() ([]byte, error) {
buffer := new(bytes.Buffer)
// Explicitly specify byte order for write into the buffer
// to provide cross platform support, note the it consistent
// with FromBytes function
err := binary.Write(buffer, binary.BigEndian, *n)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}

// Get ledger height from the state
func (n *NodeMetastate) Height() uint64 {
return n.LedgerHeight
}

// Update state with new ledger height
func (n *NodeMetastate) Update(height uint64) {
n.LedgerHeight = height
}

// Encode from byte array into meta data structure
func FromBytes(buf []byte) (*NodeMetastate, error) {
state := NodeMetastate{}
reader := bytes.NewReader(buf)
// As bytes are written in the big endian to keep supporting
// cross platforming and for consistency reasons read also
// done using same order
err := binary.Read(reader, binary.BigEndian, &state)
if err != nil {
return nil, err
}
return &state, nil
}
74 changes: 74 additions & 0 deletions gossip/state/metastate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package state

import (
"testing"
"github.com/docker/docker/pkg/testutil/assert"
)

func TestNewNodeMetastate(t *testing.T) {
metastate := NewNodeMetastate(0)
assert.Equal(t, metastate.Height(), uint64(0))
}

func TestNodeMetastateImpl_Update(t *testing.T) {
metastate := NewNodeMetastate(0)
assert.Equal(t, metastate.Height(), uint64(0))
metastate.Update(10)
assert.Equal(t, metastate.Height(), uint64(10))
}

// Test node metastate encoding
func TestNodeMetastateImpl_Bytes(t *testing.T) {
metastate := NewNodeMetastate(0)
// Encode state into bytes and check there is no errors
_, err := metastate.Bytes()
assert.NilError(t, err)
}

// Check the deserialization of the meta stats structure
func TestNodeMetastate_FromBytes(t *testing.T) {
metastate := NewNodeMetastate(0)
// Serialize into bytes array
bytes, err := metastate.Bytes()
assert.NilError(t, err)
if bytes == nil {
t.Fatal("Was not able to serialize meta state into byte array.")
}

// Deserialize back and check, that state still have same
// height value
state, err := FromBytes(bytes)
assert.NilError(t, err)

assert.Equal(t, state.Height(), uint64(0))

// Update state to the new height and serialize it again
state.Update(17)
bytes, err = state.Bytes()
assert.NilError(t, err)
if bytes == nil {
t.Fatal("Was not able to serialize meta state into byte array.")
}

// Restore state from byte array and validate
// that stored height is still the same
updatedState, err := FromBytes(bytes)
assert.NilError(t, err)
assert.Equal(t, updatedState.Height(), uint64(17))
}

0 comments on commit b57dbfa

Please sign in to comment.