Skip to content

Commit b57dbfa

Browse files
committed
[FAB-702] - Add gossip node metastate object
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 <[email protected]>
1 parent b4473da commit b57dbfa

File tree

2 files changed

+146
-0
lines changed

2 files changed

+146
-0
lines changed

gossip/state/metastate.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package state
18+
19+
import (
20+
"bytes"
21+
"encoding/binary"
22+
)
23+
24+
// Metadata information to store the information about current
25+
// height of the ledger (last accepted block sequence number).
26+
type NodeMetastate struct {
27+
28+
// Actual ledger height
29+
LedgerHeight uint64
30+
}
31+
32+
// Create new meta data with given ledger height148.69
33+
func NewNodeMetastate(height uint64) *NodeMetastate {
34+
return &NodeMetastate{height}
35+
}
36+
37+
// Decodes meta state into byte array for serialization
38+
func (n *NodeMetastate) Bytes() ([]byte, error) {
39+
buffer := new(bytes.Buffer)
40+
// Explicitly specify byte order for write into the buffer
41+
// to provide cross platform support, note the it consistent
42+
// with FromBytes function
43+
err := binary.Write(buffer, binary.BigEndian, *n)
44+
if err != nil {
45+
return nil, err
46+
}
47+
return buffer.Bytes(), nil
48+
}
49+
50+
// Get ledger height from the state
51+
func (n *NodeMetastate) Height() uint64 {
52+
return n.LedgerHeight
53+
}
54+
55+
// Update state with new ledger height
56+
func (n *NodeMetastate) Update(height uint64) {
57+
n.LedgerHeight = height
58+
}
59+
60+
// Encode from byte array into meta data structure
61+
func FromBytes(buf []byte) (*NodeMetastate, error) {
62+
state := NodeMetastate{}
63+
reader := bytes.NewReader(buf)
64+
// As bytes are written in the big endian to keep supporting
65+
// cross platforming and for consistency reasons read also
66+
// done using same order
67+
err := binary.Read(reader, binary.BigEndian, &state)
68+
if err != nil {
69+
return nil, err
70+
}
71+
return &state, nil
72+
}

gossip/state/metastate_test.go

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
Copyright IBM Corp. 2016 All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package state
18+
19+
import (
20+
"testing"
21+
"github.com/docker/docker/pkg/testutil/assert"
22+
)
23+
24+
func TestNewNodeMetastate(t *testing.T) {
25+
metastate := NewNodeMetastate(0)
26+
assert.Equal(t, metastate.Height(), uint64(0))
27+
}
28+
29+
func TestNodeMetastateImpl_Update(t *testing.T) {
30+
metastate := NewNodeMetastate(0)
31+
assert.Equal(t, metastate.Height(), uint64(0))
32+
metastate.Update(10)
33+
assert.Equal(t, metastate.Height(), uint64(10))
34+
}
35+
36+
// Test node metastate encoding
37+
func TestNodeMetastateImpl_Bytes(t *testing.T) {
38+
metastate := NewNodeMetastate(0)
39+
// Encode state into bytes and check there is no errors
40+
_, err := metastate.Bytes()
41+
assert.NilError(t, err)
42+
}
43+
44+
// Check the deserialization of the meta stats structure
45+
func TestNodeMetastate_FromBytes(t *testing.T) {
46+
metastate := NewNodeMetastate(0)
47+
// Serialize into bytes array
48+
bytes, err := metastate.Bytes()
49+
assert.NilError(t, err)
50+
if bytes == nil {
51+
t.Fatal("Was not able to serialize meta state into byte array.")
52+
}
53+
54+
// Deserialize back and check, that state still have same
55+
// height value
56+
state, err := FromBytes(bytes)
57+
assert.NilError(t, err)
58+
59+
assert.Equal(t, state.Height(), uint64(0))
60+
61+
// Update state to the new height and serialize it again
62+
state.Update(17)
63+
bytes, err = state.Bytes()
64+
assert.NilError(t, err)
65+
if bytes == nil {
66+
t.Fatal("Was not able to serialize meta state into byte array.")
67+
}
68+
69+
// Restore state from byte array and validate
70+
// that stored height is still the same
71+
updatedState, err := FromBytes(bytes)
72+
assert.NilError(t, err)
73+
assert.Equal(t, updatedState.Height(), uint64(17))
74+
}

0 commit comments

Comments
 (0)