Skip to content

Commit

Permalink
epoch and fork test finished
Browse files Browse the repository at this point in the history
  • Loading branch information
darren0718 committed Aug 19, 2019
1 parent e0c1e41 commit 8b73fb1
Show file tree
Hide file tree
Showing 31 changed files with 1,786 additions and 239 deletions.
4 changes: 2 additions & 2 deletions consensus/group/era.go
Expand Up @@ -22,8 +22,8 @@ import (
)

const (
maxGroupPerEpoch = 25 // max group num can be created during one epoch
steadyStateBackTrackGap = 20 // The gap from the present to the steady state
maxGroupPerEpoch = 5 //25 // max group num can be created during one epoch
steadyStateBackTrackGap = 5 //20 // The gap from the present to the steady state

// era window consist of following graph:
/* ^seed |---gap1---|---round1:encrypted share piece---|--gap2--|---round2:mpk share---|---gap3---|---round3:origin share piece---|---gap4---|end$ */
Expand Down
2 changes: 1 addition & 1 deletion consensus/group/genesis.go
Expand Up @@ -62,7 +62,7 @@ func GenerateGenesis() *types.GenesisInfo {
}
members := make([]types.MemberI, len(genesis.Members))
for i, mem := range genesis.Members {
members[i] = &member{id: mem.ID, pk: mem.PK}
members[i] = &member{id: mem.ID.Serialize(), pk: mem.PK.Serialize()}
}
coreGroup := &group{header: gHeader, members: members}

Expand Down
10 changes: 5 additions & 5 deletions consensus/group/packet.go
Expand Up @@ -95,16 +95,16 @@ func (pkt *mpkPacket) Sign() []byte {
}

type member struct {
id groupsig.ID
pk groupsig.Pubkey
id []byte
pk []byte
}

func (m *member) ID() []byte {
return m.id.Serialize()
return m.id
}

func (m *member) PK() []byte {
return m.pk.Serialize()
return m.pk
}

type groupHeader struct {
Expand Down Expand Up @@ -200,7 +200,7 @@ func idleCreateResult(err error) *createResult {
func generateGroupInfo(packets []types.MpkPacket, era *era, gpk groupsig.Pubkey, threshold int) *group {
members := make([]types.MemberI, 0)
for _, pkt := range packets {
members = append(members, &member{id: groupsig.DeserializeID(pkt.Sender()), pk: groupsig.DeserializePubkeyBytes(pkt.Mpk())})
members = append(members, &member{id: pkt.Sender(), pk: pkt.Mpk()})
}
gHeader := &groupHeader{
seed: era.Seed(),
Expand Down
94 changes: 71 additions & 23 deletions consensus/logical/group.go
Expand Up @@ -28,12 +28,56 @@ type member struct {
pk groupsig.Pubkey
}

type groupHeader struct {
seed common.Hash
workHeight uint64
dismissHeight uint64
gpk groupsig.Pubkey
threshold uint32
groupHeight uint64
}

func (gh *groupHeader) Seed() common.Hash {
return gh.seed
}

func (gh *groupHeader) WorkHeight() uint64 {
return gh.workHeight
}

func (gh *groupHeader) DismissHeight() uint64 {
return gh.dismissHeight
}

func (gh *groupHeader) PublicKey() []byte {
return gh.gpk.Serialize()
}

func (gh *groupHeader) Threshold() uint32 {
return gh.threshold
}

func (gh *groupHeader) GroupHeight() uint64 {
return gh.groupHeight
}

type verifyGroup struct {
header types.GroupHeaderI
header *groupHeader
members []*member
memIndex map[string]int
}

func convertGroupHeaderI(gh types.GroupHeaderI) *groupHeader {
return &groupHeader{
seed: gh.Seed(),
workHeight: gh.WorkHeight(),
dismissHeight: gh.DismissHeight(),
gpk: groupsig.DeserializePubkeyBytes(gh.PublicKey()),
threshold: gh.Threshold(),
groupHeight: gh.GroupHeight(),
}
}

func convertGroupI(g types.GroupI) *verifyGroup {
mems := make([]*member, len(g.Members()))
memIndex := make(map[string]int)
Expand All @@ -42,7 +86,7 @@ func convertGroupI(g types.GroupI) *verifyGroup {
memIndex[mems[i].id.GetHexString()] = i
}
return &verifyGroup{
header: g.Header(),
header: convertGroupHeaderI(g.Header()),
memIndex: memIndex,
members: mems,
}
Expand Down Expand Up @@ -106,6 +150,8 @@ type groupInfoReader interface {
Height() uint64
}

type groupGetter func(seed common.Hash) types.GroupI

type groupReader struct {
skStore skStorage
cache *lru.Cache
Expand All @@ -116,43 +162,43 @@ func newGroupReader(infoReader groupInfoReader, skReader skStorage) *groupReader
return &groupReader{
skStore: skReader,
reader: infoReader,
cache: common.MustNewLRUCache(50),
cache: common.MustNewLRUCache(200),
}
}

func (gr *groupReader) getGroupHeaderBySeed(seed common.Hash) types.GroupHeaderI {
if v, ok := gr.cache.Get(seed); ok {
return v.(*verifyGroup).header
}
g := gr.reader.GetGroupHeaderBySeed(seed)
if g != nil {
gr.cache.ContainsOrAdd(seed, &verifyGroup{header: g})
func (gr *groupReader) getGroupHeaderBySeed(seed common.Hash) *groupHeader {
g := gr.getGroupBySeed(seed)
if g == nil {
return nil
}
return g
return g.header
}

func (gr *groupReader) getGroupBySeed(seed common.Hash) *verifyGroup {
if v, ok := gr.cache.Get(seed); ok {
g := v.(*verifyGroup)
if len(g.members) > 0 {
return g
return gr.tryToGetOrConvert(seed, gr.reader.GetGroupBySeed)
}

func (gr *groupReader) tryToGetOrConvert(seed common.Hash, getter groupGetter) *verifyGroup {
if v, ok := gr.cache.Get(seed); !ok {
g := getter(seed)
if g == nil {
return nil
}
}
g := gr.reader.GetGroupBySeed(seed)
if g != nil {
stdLogger.Debugf("get group seed %v len %v", seed, g.Members())
gi := convertGroupI(g)
gr.cache.ContainsOrAdd(gi.header.Seed(), gi)
gr.cache.ContainsOrAdd(gi.header.seed, gi)
return gi
} else {
return v.(*verifyGroup)
}
return nil
}

func (gr *groupReader) getActivatedGroupsByHeight(h uint64) []*verifyGroup {
gs := gr.reader.GetActivatedGroupsAt(h)
vgs := make([]*verifyGroup, len(gs))
for i, gi := range gs {
vgs[i] = convertGroupI(gi)
vgs[i] = gr.tryToGetOrConvert(gi.Header().Seed(), func(seed common.Hash) types.GroupI {
return gi
})
}
return vgs
}
Expand All @@ -161,7 +207,9 @@ func (gr *groupReader) getLivedGroupsByHeight(h uint64) []*verifyGroup {
gs := gr.reader.GetLivedGroupsAt(h)
vgs := make([]*verifyGroup, len(gs))
for i, gi := range gs {
vgs[i] = convertGroupI(gi)
vgs[i] = gr.tryToGetOrConvert(gi.Header().Seed(), func(seed common.Hash) types.GroupI {
return gi
})
}
return vgs
}
Expand Down
134 changes: 134 additions & 0 deletions consensus/logical/group_test.go
@@ -0,0 +1,134 @@
// Copyright (C) 2019 ZVChain
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

package logical

import (
"github.com/zvchain/zvchain/common"
"github.com/zvchain/zvchain/middleware/types"
"testing"
)

type group4GroupTest struct {
header *groupHeader
}

func (g *group4GroupTest) Header() types.GroupHeaderI {
return g.header
}

func (g *group4GroupTest) Members() []types.MemberI {
return nil
}

type groupReader4Test struct {
groups []types.GroupI
}

func newGroupReader4Test(num uint64) *groupReader4Test {
gr := &groupReader4Test{
groups: make([]types.GroupI, 0),
}
gr.initGroups(num)
return gr
}
func newGroupHeader4Test(wh, dh uint64) *groupHeader {
return &groupHeader{
seed: common.BytesToHash(common.Uint64ToByte(wh)),
workHeight: wh,
dismissHeight: dh,
}
}

func newGroup4Test(wh, dh uint64) *group4GroupTest {
return &group4GroupTest{
header: newGroupHeader4Test(wh, dh),
}
}

func (gr *groupReader4Test) initGroups(num uint64) {
for n := uint64(0); n < num; n++ {
gr.groups = append(gr.groups, newGroup4Test(n, 10*n))
}
}

func (gr *groupReader4Test) GetActivatedGroupsAt(height uint64) []types.GroupI {
gs := make([]types.GroupI, 0)
for _, g := range gr.groups {
if g.Header().DismissHeight() > height && g.Header().WorkHeight() <= height {
gs = append(gs, g)
}
}
return gs
}

func (gr *groupReader4Test) GetLivedGroupsAt(height uint64) []types.GroupI {
gs := make([]types.GroupI, 0)
for _, g := range gr.groups {
if g.Header().DismissHeight() > height {
gs = append(gs, g)
}
}
return gs
}

func (gr *groupReader4Test) GetGroupBySeed(seedHash common.Hash) types.GroupI {
for _, g := range gr.groups {
if g.Header().Seed() == seedHash {
return g
}
}
return nil
}

func (gr *groupReader4Test) GetGroupHeaderBySeed(seedHash common.Hash) types.GroupHeaderI {
g := gr.GetGroupBySeed(seedHash)
if g != nil {
return g.Header()
}
return nil
}

func (gr *groupReader4Test) Height() uint64 {
return uint64(len(gr.groups)) + 1
}

func TestGroupReader_GetGroupBySeed(t *testing.T) {
gr := newGroupReader(newGroupReader4Test(100), nil)

for n := 0; n < 10; n++ {
g := gr.getGroupBySeed(common.BytesToHash(common.Uint64ToByte(uint64(n))))
t.Log(g.header.seed, g.header.workHeight, g.header.dismissHeight)
}

for n := 0; n < 10; n++ {
g := gr.getGroupBySeed(common.BytesToHash(common.Uint64ToByte(uint64(n))))
t.Log(g.header.seed, g.header.workHeight, g.header.dismissHeight)
}
}

func TestGroupReader_GetActiveGroups(t *testing.T) {
gr := newGroupReader(newGroupReader4Test(100), nil)

for n := 0; n < 10; n++ {
g := gr.getGroupBySeed(common.BytesToHash(common.Uint64ToByte(uint64(n))))
t.Log(g.header.seed, g.header.workHeight, g.header.dismissHeight)
}

gs := gr.getActivatedGroupsByHeight(30)
for _, g := range gs {
t.Log(g.header.seed, g.header.workHeight, g.header.dismissHeight)
}
}

0 comments on commit 8b73fb1

Please sign in to comment.