Merge branch 'master' into minor-fixes

This commit is contained in:
Stephen Buttolph 2020-04-27 13:06:12 -04:00 committed by GitHub
commit b04b84d4c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 143 additions and 67 deletions

View File

@ -26,6 +26,10 @@ import (
"github.com/ava-labs/gecko/utils/wrappers"
)
const (
dbVersion = "v0.1.0"
)
// Results of parsing the CLI
var (
Config = node.Config{}
@ -143,7 +147,7 @@ func init() {
// DB:
if *db && err == nil {
// TODO: Add better params here
dbPath := path.Join(*dbDir, genesis.NetworkName(Config.NetworkID))
dbPath := path.Join(*dbDir, genesis.NetworkName(Config.NetworkID), dbVersion)
db, err := leveldb.New(dbPath, 0, 0, 0)
Config.DB = db
errs.Add(err)

View File

@ -19,6 +19,8 @@ import (
"errors"
"fmt"
"math"
"strconv"
"strings"
"sync"
"time"
"unsafe"
@ -61,9 +63,23 @@ Attempt reconnections
node isn't connected to after awhile delete the connection.
*/
// Version this avalanche instance is executing.
var (
VersionPrefix = "avalanche/"
VersionSeparator = "."
MajorVersion = 0
MinorVersion = 1
PatchVersion = 0
ClientVersion = fmt.Sprintf("%s%d%s%d%s%d",
VersionPrefix,
MajorVersion,
VersionSeparator,
MinorVersion,
VersionSeparator,
PatchVersion)
)
const (
// CurrentVersion this avalanche instance is executing.
CurrentVersion = "avalanche/0.0.1"
// MaxClockDifference allowed between connected nodes.
MaxClockDifference = time.Minute
// PeerListGossipSpacing is the amount of time to wait between pushing this
@ -356,7 +372,7 @@ func (nm *Handshake) SendGetVersion(peer salticidae.PeerID) {
// SendVersion to the requested peer
func (nm *Handshake) SendVersion(peer salticidae.PeerID) error {
build := Builder{}
v, err := build.Version(nm.networkID, nm.clock.Unix(), toIPDesc(nm.myAddr), CurrentVersion)
v, err := build.Version(nm.networkID, nm.clock.Unix(), toIPDesc(nm.myAddr), ClientVersion)
if err != nil {
return fmt.Errorf("packing Version failed due to %s", err)
}
@ -518,6 +534,59 @@ func (nm *Handshake) disconnectedFromPeer(peer salticidae.PeerID) {
}
}
// checkCompatibility Check to make sure that the peer and I speak the same language.
func (nm *Handshake) checkCompatibility(peerVersion string) bool {
if !strings.HasPrefix(peerVersion, VersionPrefix) {
nm.log.Warn("Peer attempted to connect with an invalid version prefix")
return false
}
peerVersion = peerVersion[len(VersionPrefix):]
splitPeerVersion := strings.SplitN(peerVersion, VersionSeparator, 3)
if len(splitPeerVersion) != 3 {
nm.log.Warn("Peer attempted to connect with an invalid number of subversions")
return false
}
major, err := strconv.Atoi(splitPeerVersion[0])
if err != nil {
nm.log.Warn("Peer attempted to connect with an invalid major version")
return false
}
minor, err := strconv.Atoi(splitPeerVersion[1])
if err != nil {
nm.log.Warn("Peer attempted to connect with an invalid minor version")
return false
}
patch, err := strconv.Atoi(splitPeerVersion[2])
if err != nil {
nm.log.Warn("Peer attempted to connect with an invalid patch version")
return false
}
switch {
case major < MajorVersion:
// peers major version is too low
return false
case major > MajorVersion:
nm.log.Warn("Peer attempted to connect with a higher major version, this client may need to be updated")
return false
}
switch {
case minor < MinorVersion:
// peers minor version is too low
return false
case minor > MinorVersion:
nm.log.Warn("Peer attempted to connect with a higher minor version, this client may need to be updated")
return false
}
if patch > PatchVersion {
nm.log.Warn("Peer is connecting with a higher patch version, this client may need to be updated")
}
return true
}
// peerHandler notifies a change to the set of connected peers
// connected is true if a new peer is connected
// connected is false if a formerly connected peer has disconnected
@ -645,8 +714,8 @@ func version(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.P
return
}
if peerVersion := pMsg.Get(VersionStr).(string); !checkCompatibility(CurrentVersion, peerVersion) {
HandshakeNet.log.Warn("Bad version")
if peerVersion := pMsg.Get(VersionStr).(string); !HandshakeNet.checkCompatibility(peerVersion) {
HandshakeNet.log.Debug("Dropping connection due to an incompatible version from peer")
HandshakeNet.net.DelPeer(peer)
return
@ -741,12 +810,6 @@ func getCert(cert salticidae.X509) ids.ShortID {
return certID
}
// checkCompatibility Check to make sure that the peer and I speak the same language.
func checkCompatibility(myVersion string, peerVersion string) bool {
// At the moment, we are all compatible.
return true
}
func toShortID(ip utils.IPDesc) ids.ShortID {
return ids.NewShortID(hashing.ComputeHash160Array([]byte(ip.String())))
}

View File

@ -10,20 +10,21 @@ import (
)
const (
errMsg = "__________ .___\n" +
"\\______ \\____________ __| _/__.__.\n" +
" | | _/\\_ __ \\__ \\ / __ < | |\n" +
" | | \\ | | \\// __ \\_/ /_/ |\\___ |\n" +
" |______ / |__| (____ /\\____ |/ ____|\n" +
" \\/ \\/ \\/\\/\n" +
errMsg = "" +
`__________ .___` + "\n" +
`\______ \____________ __| _/__.__.` + "\n" +
` | | _/\_ __ \__ \ / __ < | |` + "\n" +
` | | \ | | \// __ \_/ /_/ |\___ |` + "\n" +
` |______ / |__| (____ /\____ |/ ____|` + "\n" +
` \/ \/ \/\/` + "\n" +
"\n" +
"🏆 🏆 🏆 🏆 🏆 🏆\n" +
" ________ ________ ________________\n" +
" / _____/ \\_____ \\ / _ \\__ ___/\n" +
"/ \\ ___ / | \\ / /_\\ \\| |\n" +
"\\ \\_\\ \\/ | \\/ | \\ |\n" +
" \\______ /\\_______ /\\____|__ /____|\n" +
" \\/ \\/ \\/\n"
`🏆 🏆 🏆 🏆 🏆 🏆` + "\n" +
` ________ ________ ________________` + "\n" +
` / _____/ \_____ \ / _ \__ ___/` + "\n" +
`/ \ ___ / | \ / /_\ \| |` + "\n" +
`\ \_\ \/ | \/ | \ |` + "\n" +
` \______ /\_______ /\____|__ /____|` + "\n" +
` \/ \/ \/` + "\n"
)
// Parameters required for snowball consensus

View File

@ -82,6 +82,10 @@ func (s *Serializer) ParseVertex(b []byte) (avacon.Vertex, error) {
// BuildVertex implements the avalanche.State interface
func (s *Serializer) BuildVertex(parentSet ids.Set, txs []snowstorm.Tx) (avacon.Vertex, error) {
if len(txs) == 0 {
return nil, errNoTxs
}
parentIDs := parentSet.List()
ids.SortIDs(parentIDs)
sortTxs(txs)

View File

@ -24,6 +24,7 @@ var (
errExtraSpace = errors.New("trailing buffer space")
errInvalidParents = errors.New("vertex contains non-sorted or duplicated parentIDs")
errInvalidTxs = errors.New("vertex contains non-sorted or duplicated transactions")
errNoTxs = errors.New("vertex contains no transactions")
)
type vertex struct {
@ -45,6 +46,8 @@ func (vtx *vertex) Verify() error {
switch {
case !ids.IsSortedAndUniqueIDs(vtx.parentIDs):
return errInvalidParents
case len(vtx.txs) == 0:
return errNoTxs
case !isSortedAndUniqueTxs(vtx.txs):
return errInvalidTxs
default:
@ -55,7 +58,7 @@ func (vtx *vertex) Verify() error {
/*
* Vertex:
* Codec | 04 Bytes
* Chain | 32 Bytes
* Chain | 32 Bytes
* Height | 08 Bytes
* NumParents | 04 Bytes
* Repeated (NumParents):

View File

@ -316,8 +316,37 @@ func (t *Transitive) batch(txs []snowstorm.Tx, force, empty bool) {
}
}
if len(batch) > 0 || (empty && !issued) {
if len(batch) > 0 {
t.issueBatch(batch)
} else if empty && !issued {
t.issueRepoll()
}
}
func (t *Transitive) issueRepoll() {
preferredIDs := t.Consensus.Preferences().List()
numPreferredIDs := len(preferredIDs)
if numPreferredIDs == 0 {
t.Config.Context.Log.Error("Re-query attempt was dropped due to no pending vertices")
return
}
sampler := random.Uniform{N: len(preferredIDs)}
vtxID := preferredIDs[sampler.Sample()]
p := t.Consensus.Parameters()
vdrs := t.Config.Validators.Sample(p.K) // Validators to sample
vdrSet := ids.ShortSet{} // Validators to sample repr. as a set
for _, vdr := range vdrs {
vdrSet.Add(vdr.ID())
}
t.RequestID++
if numVdrs := len(vdrs); numVdrs == p.K && t.polls.Add(t.RequestID, vdrSet.Len()) {
t.Config.Sender.PullQuery(vdrSet, t.RequestID, vtxID)
} else if numVdrs < p.K {
t.Config.Context.Log.Error("Re-query for %s was dropped due to an insufficient number of validators", vtxID)
}
}

View File

@ -698,23 +698,12 @@ func TestEngineScheduleRepoll(t *testing.T) {
sender.PushQueryF = nil
st.buildVertex = func(_ ids.Set, txs []snowstorm.Tx) (avalanche.Vertex, error) {
consumers := []snowstorm.Tx{}
for _, tx := range txs {
consumers = append(consumers, tx)
}
return &Vtx{
parents: []avalanche.Vertex{gVtx, mVtx},
id: GenerateID(),
txs: consumers,
status: choices.Processing,
bytes: []byte{1},
}, nil
}
repolled := new(bool)
sender.PushQueryF = func(_ ids.ShortSet, _ uint32, _ ids.ID, _ []byte) {
sender.PullQueryF = func(_ ids.ShortSet, _ uint32, vtxID ids.ID) {
*repolled = true
if !vtxID.Equals(vtx.ID()) {
t.Fatalf("Wrong vertex queried")
}
}
te.QueryFailed(vdr.ID(), *requestID)
@ -979,31 +968,14 @@ func TestEngineIssueRepoll(t *testing.T) {
te.Initialize(config)
te.finishBootstrapping()
newVtxID := new(ids.ID)
st.buildVertex = func(s ids.Set, txs []snowstorm.Tx) (avalanche.Vertex, error) {
if len(txs) != 0 {
t.Fatalf("Wrong vertex issued")
}
if s.Len() != 2 || !s.Contains(gVtx.ID()) || !s.Contains(mVtx.ID()) {
t.Fatalf("Wrong vertex issued")
}
vtx := &Vtx{
parents: []avalanche.Vertex{gVtx, mVtx},
id: GenerateID(),
status: choices.Processing,
bytes: []byte{1},
}
*newVtxID = vtx.ID()
return vtx, nil
}
sender.PushQueryF = func(vdrs ids.ShortSet, _ uint32, vtxID ids.ID, vtx []byte) {
sender.PullQueryF = func(vdrs ids.ShortSet, _ uint32, vtxID ids.ID) {
vdrSet := ids.ShortSet{}
vdrSet.Add(vdr.ID())
if !vdrs.Equals(vdrSet) || !vtxID.Equals(*newVtxID) {
t.Fatalf("Wrong query message")
if !vdrs.Equals(vdrSet) {
t.Fatalf("Wrong query recipients")
}
if !vtxID.Equals(gVtx.ID()) && !vtxID.Equals(mVtx.ID()) {
t.Fatalf("Unknown re-query")
}
}

View File

@ -9,7 +9,7 @@ import (
)
func TestAddDefaultSubnetValidator(t *testing.T) {
expectedJSONString := `{"startTime":"0","endtime":"0","id":null,"destination":null,"delegationFeeRate":"0","payerNonce":"0"}`
expectedJSONString := `{"startTime":"0","endTime":"0","id":null,"destination":null,"delegationFeeRate":"0","payerNonce":"0"}`
args := AddDefaultSubnetValidatorArgs{}
bytes, err := json.Marshal(&args)
if err != nil {

View File

@ -44,7 +44,7 @@ type APIAccount struct {
// is sent when this staker is done staking.
type APIValidator struct {
StartTime json.Uint64 `json:"startTime"`
EndTime json.Uint64 `json:"endtime"`
EndTime json.Uint64 `json:"endTime"`
Weight *json.Uint64 `json:"weight,omitempty"`
StakeAmount *json.Uint64 `json:"stakeAmount,omitempty"`
ID ids.ShortID `json:"id"`