mirror of https://github.com/poanetwork/gecko.git
Merge branch 'master' of github.com:ava-labs/gecko-internal
This commit is contained in:
commit
8ec2862c04
|
@ -10,6 +10,10 @@ import (
|
||||||
"github.com/ava-labs/gecko/ids"
|
"github.com/ava-labs/gecko/ids"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minCacheSize = 32
|
||||||
|
)
|
||||||
|
|
||||||
type entry struct {
|
type entry struct {
|
||||||
Key ids.ID
|
Key ids.ID
|
||||||
Value interface{}
|
Value interface{}
|
||||||
|
@ -59,7 +63,7 @@ func (c *LRU) Flush() {
|
||||||
|
|
||||||
func (c *LRU) init() {
|
func (c *LRU) init() {
|
||||||
if c.entryMap == nil {
|
if c.entryMap == nil {
|
||||||
c.entryMap = make(map[[32]byte]*list.Element)
|
c.entryMap = make(map[[32]byte]*list.Element, minCacheSize)
|
||||||
}
|
}
|
||||||
if c.entryList == nil {
|
if c.entryList == nil {
|
||||||
c.entryList = list.New()
|
c.entryList = list.New()
|
||||||
|
@ -134,6 +138,6 @@ func (c *LRU) evict(key ids.ID) {
|
||||||
func (c *LRU) flush() {
|
func (c *LRU) flush() {
|
||||||
c.init()
|
c.init()
|
||||||
|
|
||||||
c.entryMap = make(map[[32]byte]*list.Element)
|
c.entryMap = make(map[[32]byte]*list.Element, minCacheSize)
|
||||||
c.entryList = list.New()
|
c.entryList = list.New()
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkLRUCachePutSmall(b *testing.B) {
|
||||||
|
smallLen := 5
|
||||||
|
cache := &LRU{Size: smallLen}
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
for i := 0; i < smallLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
cache.Put(ids.NewID(idBytes), n)
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
cache.Flush()
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkLRUCachePutMedium(b *testing.B) {
|
||||||
|
mediumLen := 250
|
||||||
|
cache := &LRU{Size: mediumLen}
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
for i := 0; i < mediumLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
cache.Put(ids.NewID(idBytes), n)
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
cache.Flush()
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkLRUCachePutLarge(b *testing.B) {
|
||||||
|
largeLen := 10000
|
||||||
|
cache := &LRU{Size: largeLen}
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
for i := 0; i < largeLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
cache.Put(ids.NewID(idBytes), n)
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
cache.Flush()
|
||||||
|
b.StartTimer()
|
||||||
|
}
|
||||||
|
}
|
17
ids/bag.go
17
ids/bag.go
|
@ -8,6 +8,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minBagSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
// Bag is a multiset of IDs.
|
// Bag is a multiset of IDs.
|
||||||
//
|
//
|
||||||
// A bag has the ability to split and filter on it's bits for ease of use for
|
// A bag has the ability to split and filter on it's bits for ease of use for
|
||||||
|
@ -25,7 +29,7 @@ type Bag struct {
|
||||||
|
|
||||||
func (b *Bag) init() {
|
func (b *Bag) init() {
|
||||||
if b.counts == nil {
|
if b.counts == nil {
|
||||||
b.counts = make(map[[32]byte]int)
|
b.counts = make(map[[32]byte]int, minBagSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,16 +76,21 @@ func (b *Bag) AddCount(id ID, count int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count returns the number of times the id has been added.
|
// Count returns the number of times the id has been added.
|
||||||
func (b *Bag) Count(id ID) int { return b.counts[*id.ID] }
|
func (b *Bag) Count(id ID) int {
|
||||||
|
b.init()
|
||||||
|
return b.counts[*id.ID]
|
||||||
|
}
|
||||||
|
|
||||||
// Len returns the number of times an id has been added.
|
// Len returns the number of times an id has been added.
|
||||||
func (b *Bag) Len() int { return b.size }
|
func (b *Bag) Len() int { return b.size }
|
||||||
|
|
||||||
// List returns a list of all ids that have been added.
|
// List returns a list of all ids that have been added.
|
||||||
func (b *Bag) List() []ID {
|
func (b *Bag) List() []ID {
|
||||||
idList := []ID(nil)
|
idList := make([]ID, len(b.counts), len(b.counts))
|
||||||
|
i := 0
|
||||||
for id := range b.counts {
|
for id := range b.counts {
|
||||||
idList = append(idList, NewID(id))
|
idList[i] = NewID(id)
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
return idList
|
return idList
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ids
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
func BenchmarkBagListSmall(b *testing.B) {
|
||||||
|
smallLen := 5
|
||||||
|
bag := Bag{}
|
||||||
|
for i := 0; i < smallLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
bag.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
bag.List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkBagListMedium(b *testing.B) {
|
||||||
|
mediumLen := 25
|
||||||
|
bag := Bag{}
|
||||||
|
for i := 0; i < mediumLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
bag.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
bag.List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkBagListLarge(b *testing.B) {
|
||||||
|
largeLen := 100000
|
||||||
|
bag := Bag{}
|
||||||
|
for i := 0; i < largeLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
bag.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
bag.List()
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,8 +18,8 @@ func TestBagAdd(t *testing.T) {
|
||||||
} else if count := bag.Count(id1); count != 0 {
|
} else if count := bag.Count(id1); count != 0 {
|
||||||
t.Fatalf("Bag.Count returned %d expected %d", count, 0)
|
t.Fatalf("Bag.Count returned %d expected %d", count, 0)
|
||||||
} else if size := bag.Len(); size != 0 {
|
} else if size := bag.Len(); size != 0 {
|
||||||
t.Fatalf("Bag.Len returned %d expected %d", count, 0)
|
t.Fatalf("Bag.Len returned %d elements expected %d", count, 0)
|
||||||
} else if list := bag.List(); list != nil {
|
} else if list := bag.List(); len(list) != 0 {
|
||||||
t.Fatalf("Bag.List returned %v expected %v", list, nil)
|
t.Fatalf("Bag.List returned %v expected %v", list, nil)
|
||||||
} else if mode, freq := bag.Mode(); !mode.IsZero() {
|
} else if mode, freq := bag.Mode(); !mode.IsZero() {
|
||||||
t.Fatalf("Bag.Mode[0] returned %s expected %s", mode, ID{})
|
t.Fatalf("Bag.Mode[0] returned %s expected %s", mode, ID{})
|
||||||
|
|
14
ids/set.go
14
ids/set.go
|
@ -7,11 +7,19 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// The minimum capacity of a set
|
||||||
|
minSetSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
// Set is a set of IDs
|
// Set is a set of IDs
|
||||||
type Set map[[32]byte]bool
|
type Set map[[32]byte]bool
|
||||||
|
|
||||||
func (ids *Set) init(size int) {
|
func (ids *Set) init(size int) {
|
||||||
if *ids == nil {
|
if *ids == nil {
|
||||||
|
if minSetSize > size {
|
||||||
|
size = minSetSize
|
||||||
|
}
|
||||||
*ids = make(map[[32]byte]bool, size)
|
*ids = make(map[[32]byte]bool, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,9 +78,11 @@ func (ids *Set) Clear() { *ids = nil }
|
||||||
|
|
||||||
// List converts this set into a list
|
// List converts this set into a list
|
||||||
func (ids Set) List() []ID {
|
func (ids Set) List() []ID {
|
||||||
idList := []ID(nil)
|
idList := make([]ID, ids.Len(), ids.Len())
|
||||||
|
i := 0
|
||||||
for id := range ids {
|
for id := range ids {
|
||||||
idList = append(idList, NewID(id))
|
idList[i] = NewID(id)
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
return idList
|
return idList
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
package ids
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
func BenchmarkSetListSmall(b *testing.B) {
|
||||||
|
smallLen := 5
|
||||||
|
set := Set{}
|
||||||
|
for i := 0; i < smallLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
set.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
set.List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetListMedium(b *testing.B) {
|
||||||
|
mediumLen := 25
|
||||||
|
set := Set{}
|
||||||
|
for i := 0; i < mediumLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
set.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
set.List()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetListLarge(b *testing.B) {
|
||||||
|
largeLen := 100000
|
||||||
|
set := Set{}
|
||||||
|
for i := 0; i < largeLen; i++ {
|
||||||
|
var idBytes [32]byte
|
||||||
|
rand.Read(idBytes[:])
|
||||||
|
NewID(idBytes)
|
||||||
|
set.Add(NewID(idBytes))
|
||||||
|
}
|
||||||
|
b.ResetTimer()
|
||||||
|
for n := 0; n < b.N; n++ {
|
||||||
|
set.List()
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,18 @@ package ids
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
||||||
|
const (
|
||||||
|
minShortSetSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
// ShortSet is a set of ShortIDs
|
// ShortSet is a set of ShortIDs
|
||||||
type ShortSet map[[20]byte]bool
|
type ShortSet map[[20]byte]bool
|
||||||
|
|
||||||
func (ids *ShortSet) init(size int) {
|
func (ids *ShortSet) init(size int) {
|
||||||
if *ids == nil {
|
if *ids == nil {
|
||||||
|
if minShortSetSize > size {
|
||||||
|
size = minShortSetSize
|
||||||
|
}
|
||||||
*ids = make(map[[20]byte]bool, size)
|
*ids = make(map[[20]byte]bool, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,9 +72,11 @@ func (ids ShortSet) CappedList(size int) []ShortID {
|
||||||
|
|
||||||
// List converts this set into a list
|
// List converts this set into a list
|
||||||
func (ids ShortSet) List() []ShortID {
|
func (ids ShortSet) List() []ShortID {
|
||||||
idList := make([]ShortID, len(ids))[:0]
|
idList := make([]ShortID, len(ids), len(ids))
|
||||||
|
i := 0
|
||||||
for id := range ids {
|
for id := range ids {
|
||||||
idList = append(idList, NewShortID(id))
|
idList[i] = NewShortID(id)
|
||||||
|
i++
|
||||||
}
|
}
|
||||||
return idList
|
return idList
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,12 +8,16 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minUniqueBagSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
// UniqueBag ...
|
// UniqueBag ...
|
||||||
type UniqueBag map[[32]byte]BitSet
|
type UniqueBag map[[32]byte]BitSet
|
||||||
|
|
||||||
func (b *UniqueBag) init() {
|
func (b *UniqueBag) init() {
|
||||||
if *b == nil {
|
if *b == nil {
|
||||||
*b = make(map[[32]byte]BitSet)
|
*b = make(map[[32]byte]BitSet, minUniqueBagSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,10 @@ const (
|
||||||
defaultGetVersionTimeout = 2 * time.Second
|
defaultGetVersionTimeout = 2 * time.Second
|
||||||
defaultAllowPrivateIPs = true
|
defaultAllowPrivateIPs = true
|
||||||
defaultGossipSize = 50
|
defaultGossipSize = 50
|
||||||
|
|
||||||
|
// Request ID used when sending a Put message to gossip an accepted container
|
||||||
|
// (ie not sent in response to a Get)
|
||||||
|
GossipMsgRequestID = math.MaxUint32
|
||||||
)
|
)
|
||||||
|
|
||||||
// Network defines the functionality of the networking library.
|
// Network defines the functionality of the networking library.
|
||||||
|
@ -705,7 +709,7 @@ func (n *network) Track(ip utils.IPDesc) {
|
||||||
|
|
||||||
// assumes the stateLock is not held.
|
// assumes the stateLock is not held.
|
||||||
func (n *network) gossipContainer(chainID, containerID ids.ID, container []byte) error {
|
func (n *network) gossipContainer(chainID, containerID ids.ID, container []byte) error {
|
||||||
msg, err := n.b.Put(chainID, math.MaxUint32, containerID, container)
|
msg, err := n.b.Put(chainID, GossipMsgRequestID, containerID, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("attempted to pack too large of a Put message.\nContainer length: %d", len(container))
|
return fmt.Errorf("attempted to pack too large of a Put message.\nContainer length: %d", len(container))
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,7 +169,11 @@ func (t *Transitive) Put(vdr ids.ShortID, requestID uint32, vtxID ids.ID, vtxByt
|
||||||
t.Config.Context.Log.Verbo("Put(%s, %d, %s) called", vdr, requestID, vtxID)
|
t.Config.Context.Log.Verbo("Put(%s, %d, %s) called", vdr, requestID, vtxID)
|
||||||
|
|
||||||
if !t.bootstrapped { // Bootstrapping unfinished --> didn't call Get --> this message is invalid
|
if !t.bootstrapped { // Bootstrapping unfinished --> didn't call Get --> this message is invalid
|
||||||
|
if requestID == network.GossipMsgRequestID {
|
||||||
|
t.Config.Context.Log.Verbo("dropping gossip Put(%s, %d, %s) due to bootstrapping", vdr, requestID, vtxID)
|
||||||
|
} else {
|
||||||
t.Config.Context.Log.Debug("dropping Put(%s, %d, %s) due to bootstrapping", vdr, requestID, vtxID)
|
t.Config.Context.Log.Debug("dropping Put(%s, %d, %s) due to bootstrapping", vdr, requestID, vtxID)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,10 @@ import (
|
||||||
"github.com/ava-labs/gecko/ids"
|
"github.com/ava-labs/gecko/ids"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minRequestsSize = 32
|
||||||
|
)
|
||||||
|
|
||||||
type req struct {
|
type req struct {
|
||||||
vdr ids.ShortID
|
vdr ids.ShortID
|
||||||
id uint32
|
id uint32
|
||||||
|
@ -22,7 +26,7 @@ type Requests struct {
|
||||||
// are only in one request at a time.
|
// are only in one request at a time.
|
||||||
func (r *Requests) Add(vdr ids.ShortID, requestID uint32, containerID ids.ID) {
|
func (r *Requests) Add(vdr ids.ShortID, requestID uint32, containerID ids.ID) {
|
||||||
if r.reqsToID == nil {
|
if r.reqsToID == nil {
|
||||||
r.reqsToID = make(map[[20]byte]map[uint32]ids.ID)
|
r.reqsToID = make(map[[20]byte]map[uint32]ids.ID, minRequestsSize)
|
||||||
}
|
}
|
||||||
vdrKey := vdr.Key()
|
vdrKey := vdr.Key()
|
||||||
vdrReqs, ok := r.reqsToID[vdrKey]
|
vdrReqs, ok := r.reqsToID[vdrKey]
|
||||||
|
@ -33,7 +37,7 @@ func (r *Requests) Add(vdr ids.ShortID, requestID uint32, containerID ids.ID) {
|
||||||
vdrReqs[requestID] = containerID
|
vdrReqs[requestID] = containerID
|
||||||
|
|
||||||
if r.idToReq == nil {
|
if r.idToReq == nil {
|
||||||
r.idToReq = make(map[[32]byte]req)
|
r.idToReq = make(map[[32]byte]req, minRequestsSize)
|
||||||
}
|
}
|
||||||
r.idToReq[containerID.Key()] = req{
|
r.idToReq[containerID.Key()] = req{
|
||||||
vdr: vdr,
|
vdr: vdr,
|
||||||
|
|
|
@ -185,7 +185,11 @@ func (t *Transitive) GetAncestors(vdr ids.ShortID, requestID uint32, blkID ids.I
|
||||||
func (t *Transitive) Put(vdr ids.ShortID, requestID uint32, blkID ids.ID, blkBytes []byte) error {
|
func (t *Transitive) Put(vdr ids.ShortID, requestID uint32, blkID ids.ID, blkBytes []byte) error {
|
||||||
// bootstrapping isn't done --> we didn't send any gets --> this put is invalid
|
// bootstrapping isn't done --> we didn't send any gets --> this put is invalid
|
||||||
if !t.bootstrapped {
|
if !t.bootstrapped {
|
||||||
|
if requestID == network.GossipMsgRequestID {
|
||||||
|
t.Config.Context.Log.Verbo("dropping gossip Put(%s, %d, %s) due to bootstrapping", vdr, requestID, blkID)
|
||||||
|
} else {
|
||||||
t.Config.Context.Log.Debug("dropping Put(%s, %d, %s) due to bootstrapping", vdr, requestID, blkID)
|
t.Config.Context.Log.Debug("dropping Put(%s, %d, %s) due to bootstrapping", vdr, requestID, blkID)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,16 @@ import (
|
||||||
"github.com/ava-labs/gecko/ids"
|
"github.com/ava-labs/gecko/ids"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minBlockerSize = 16
|
||||||
|
)
|
||||||
|
|
||||||
// Blocker tracks objects that are blocked
|
// Blocker tracks objects that are blocked
|
||||||
type Blocker map[[32]byte][]Blockable
|
type Blocker map[[32]byte][]Blockable
|
||||||
|
|
||||||
func (b *Blocker) init() {
|
func (b *Blocker) init() {
|
||||||
if *b == nil {
|
if *b == nil {
|
||||||
*b = make(map[[32]byte][]Blockable)
|
*b = make(map[[32]byte][]Blockable, minBlockerSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue