Skip to content

Commit

Permalink
Merge pull request #640 from ava-labs/apricot-p0
Browse files Browse the repository at this point in the history
Apricot Phase 0
  • Loading branch information
StephenButtolph committed Dec 5, 2020
2 parents af4e8c9 + a6ebc5c commit 34c7ebd
Show file tree
Hide file tree
Showing 18 changed files with 485 additions and 64 deletions.
2 changes: 1 addition & 1 deletion .ci/run_e2e_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ AVALANCHE_IMAGE="$AVALANCHE_IMAGE_REPO:$AVALANCHE_IMAGE_TAG"
echo "Using Avalanche Image: $AVALANCHE_IMAGE"

DOCKER_REPO="avaplatform"
BYZANTINE_IMAGE="$DOCKER_REPO/avalanche-byzantine:v0.1.4-rc.1"
BYZANTINE_IMAGE="$DOCKER_REPO/avalanche-byzantine:v0.1.5-rc.1"
TEST_SUITE_IMAGE="$DOCKER_REPO/avalanche-testing:v0.10.4"

# If Docker Credentials are not available skip the Byzantine Tests
Expand Down
1 change: 1 addition & 0 deletions genesis/genesis_fuji.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,5 +208,6 @@ var (
MinStakeDuration: 24 * time.Hour,
MaxStakeDuration: 365 * 24 * time.Hour,
StakeMintingPeriod: 365 * 24 * time.Hour,
ApricotPhase0Time: time.Date(2020, 12, 5, 5, 00, 0, 0, time.UTC),
}
)
1 change: 1 addition & 0 deletions genesis/genesis_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,5 +102,6 @@ var (
MinStakeDuration: 24 * time.Hour,
MaxStakeDuration: 365 * 24 * time.Hour,
StakeMintingPeriod: 365 * 24 * time.Hour,
ApricotPhase0Time: time.Date(2020, 12, 5, 5, 00, 0, 0, time.UTC),
}
)
1 change: 1 addition & 0 deletions genesis/genesis_mainnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -175781,5 +175781,6 @@ var (
MinStakeDuration: 2 * 7 * 24 * time.Hour,
MaxStakeDuration: 365 * 24 * time.Hour,
StakeMintingPeriod: 365 * 24 * time.Hour,
ApricotPhase0Time: time.Date(2020, 12, 8, 3, 00, 0, 0, time.UTC),
}
)
3 changes: 3 additions & 0 deletions genesis/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ type Params struct {
MaxStakeDuration time.Duration
// StakeMintingPeriod is the amount of time for a consumption period.
StakeMintingPeriod time.Duration

// Time that Apricot phase 0 rules go into effect
ApricotPhase0Time time.Time
}

// GetParams ...
Expand Down
70 changes: 62 additions & 8 deletions network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ const (
var (
errNetworkClosed = errors.New("network closed")
errPeerIsMyself = errors.New("peer is myself")

minimumUnmaskedVersion = version.NewDefaultVersion(constants.PlatformName, 1, 1, 0)
)

func init() { rand.Seed(time.Now().UnixNano()) }
Expand Down Expand Up @@ -136,6 +138,8 @@ type network struct {
connMeter ConnMeter
executor timer.Executor
b Builder
apricotPhase0Time time.Time

// stateLock should never be held when grabbing a peer lock
stateLock sync.RWMutex
pendingBytes int64
Expand Down Expand Up @@ -170,6 +174,9 @@ type network struct {
// restarter can shutdown and restart the node.
// If nil, node will not restart even if it has no peers.
restarter utils.Restarter

hasMasked bool
maskedValidators ids.ShortSet
}

// NewDefaultNetwork returns a new Network implementation with the provided
Expand All @@ -195,6 +202,7 @@ func NewDefaultNetwork(
restartOnDisconnected bool,
disconnectedCheckFreq time.Duration,
disconnectedRestartTimeout time.Duration,
apricotPhase0Time time.Time,
) Network {
return NewNetwork(
registerer,
Expand Down Expand Up @@ -235,6 +243,7 @@ func NewDefaultNetwork(
restartOnDisconnected,
disconnectedCheckFreq,
disconnectedRestartTimeout,
apricotPhase0Time,
)
}

Expand Down Expand Up @@ -278,6 +287,7 @@ func NewNetwork(
restartOnDisconnected bool,
disconnectedCheckFreq time.Duration,
disconnectedRestartTimeout time.Duration,
apricotPhase0Time time.Time,
) Network {
// #nosec G404
netw := &network{
Expand Down Expand Up @@ -327,6 +337,7 @@ func NewNetwork(
disconnectedCheckFreq: disconnectedCheckFreq,
connectedMeter: timer.TimedMeter{Duration: disconnectedRestartTimeout},
restarter: restarter,
apricotPhase0Time: apricotPhase0Time,
}

if err := netw.initialize(registerer); err != nil {
Expand Down Expand Up @@ -664,7 +675,23 @@ func (n *network) GetHeartbeat() int64 { return atomic.LoadInt64(&n.lastHeartbea
// assumes the stateLock is not held.
func (n *network) Dispatch() error {
go n.gossip() // Periodically gossip peers
for { // Continuously accept new connections
go func() {
duration := time.Until(n.apricotPhase0Time)
time.Sleep(duration)

n.stateLock.Lock()
defer n.stateLock.Unlock()

n.hasMasked = true
for _, vdrID := range n.maskedValidators.List() {
if err := n.vdrs.MaskValidator(vdrID); err != nil {
n.log.Error("failed to mask validator %s due to %s", vdrID, err)
}
}
n.maskedValidators.Clear()
n.log.Verbo("The new staking set is:\n%s", n.vdrs)
}()
for { // Continuously accept new connections
conn, err := n.listener.Accept() // Returns error when n.Close() is called
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
Expand Down Expand Up @@ -867,7 +894,10 @@ func (n *network) gossip() {
if peer.connected.GetValue() &&
!ip.IsZero() &&
n.vdrs.Contains(peer.id) {
ips = append(ips, ip)
peerVersion := peer.versionStruct.GetValue().(version.Version)
if !peerVersion.Before(minimumUnmaskedVersion) || time.Since(n.apricotPhase0Time) < 0 {
ips = append(ips, ip)
}
}
}

Expand Down Expand Up @@ -1108,13 +1138,15 @@ func (n *network) tryAddPeer(p *peer) error {
func (n *network) validatorIPs() []utils.IPDesc {
n.stateLock.RLock()
defer n.stateLock.RUnlock()

ips := make([]utils.IPDesc, 0, len(n.peers))
for _, peer := range n.peers {
ip := peer.getIP()
if peer.connected.GetValue() &&
!ip.IsZero() &&
n.vdrs.Contains(peer.id) {
ips = append(ips, ip)
if peer.connected.GetValue() && !ip.IsZero() && n.vdrs.Contains(peer.id) {
peerVersion := peer.versionStruct.GetValue().(version.Version)
if !peerVersion.Before(minimumUnmaskedVersion) || time.Since(n.apricotPhase0Time) < 0 {
ips = append(ips, ip)
}
}
}
return ips
Expand All @@ -1127,6 +1159,29 @@ func (n *network) connected(p *peer) {
p.net.stateLock.Lock()
defer p.net.stateLock.Unlock()

p.connected.SetValue(true)

peerVersion := p.versionStruct.GetValue().(version.Version)

if n.hasMasked {
if peerVersion.Before(minimumUnmaskedVersion) {
if err := n.vdrs.MaskValidator(p.id); err != nil {
n.log.Error("failed to mask validator %s due to %s", p.id, err)
}
} else {
if err := n.vdrs.RevealValidator(p.id); err != nil {
n.log.Error("failed to reveal validator %s due to %s", p.id, err)
}
}
n.log.Verbo("The new staking set is:\n%s", n.vdrs)
} else {
if peerVersion.Before(minimumUnmaskedVersion) {
n.maskedValidators.Add(p.id)
} else {
n.maskedValidators.Remove(p.id)
}
}

ip := p.getIP()
n.log.Debug("connected to %s at %s", p.id, ip)

Expand Down Expand Up @@ -1202,8 +1257,7 @@ func (n *network) getPeers(validatorIDs ids.ShortSet) []*PeerElement {
return peers
}

// Safe copy the peers
// assumes the stateLock is not held.
// Safe copy the peers. Assumes the stateLock is not held.
func (n *network) getAllPeers() []*peer {
n.stateLock.RLock()
defer n.stateLock.RUnlock()
Expand Down
11 changes: 11 additions & 0 deletions network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ func TestNewDefaultNetwork(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net)

Expand Down Expand Up @@ -322,6 +323,7 @@ func TestEstablishConnection(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net0)

Expand All @@ -346,6 +348,7 @@ func TestEstablishConnection(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net1)

Expand Down Expand Up @@ -470,6 +473,7 @@ func TestDoubleTrack(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net0)

Expand All @@ -494,6 +498,7 @@ func TestDoubleTrack(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net1)

Expand Down Expand Up @@ -619,6 +624,7 @@ func TestDoubleClose(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net0)

Expand All @@ -643,6 +649,7 @@ func TestDoubleClose(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net1)

Expand Down Expand Up @@ -773,6 +780,7 @@ func TestTrackConnected(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net0)

Expand All @@ -797,6 +805,7 @@ func TestTrackConnected(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net1)

Expand Down Expand Up @@ -901,6 +910,7 @@ func TestTrackConnectedRace(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net0)

Expand All @@ -925,6 +935,7 @@ func TestTrackConnectedRace(t *testing.T) {
false,
0,
0,
time.Now(),
)
assert.NotNil(t, net1)

Expand Down
13 changes: 10 additions & 3 deletions network/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/ava-labs/avalanchego/utils"
"github.com/ava-labs/avalanchego/utils/formatting"
"github.com/ava-labs/avalanchego/utils/wrappers"
"github.com/ava-labs/avalanchego/version"
)

type peer struct {
Expand Down Expand Up @@ -59,7 +60,7 @@ type peer struct {
conn net.Conn

// version that the peer reported during the handshake
versionStr utils.AtomicInterface
versionStruct, versionStr utils.AtomicInterface

// unix time of the last message sent and received respectively
lastSent, lastReceived int64
Expand Down Expand Up @@ -330,6 +331,13 @@ func (p *peer) handle(msg Msg) {
}
return
}

peerVersion := p.versionStruct.GetValue().(version.Version)
if peerVersion.Before(minimumUnmaskedVersion) && time.Until(p.net.apricotPhase0Time) < 0 {
p.net.log.Verbo("dropping message from un-upgraded validator %s", p.id)
return
}

switch op {
case GetAcceptedFrontier:
p.getAcceptedFrontier(msg)
Expand Down Expand Up @@ -556,6 +564,7 @@ func (p *peer) version(msg Msg) {

p.SendPeerList()

p.versionStruct.SetValue(peerVersion)
p.versionStr.SetValue(peerVersion.String())
p.gotVersion.SetValue(true)

Expand Down Expand Up @@ -785,8 +794,6 @@ func (p *peer) tryMarkConnected() {
p.gotVersion.GetValue() && // not waiting for version
p.gotPeerList.GetValue() && // not waiting for peerlist
!p.closed.GetValue() { // and not already disconnected

p.connected.SetValue(true)
p.net.connected(p)
}
}
Expand Down
8 changes: 5 additions & 3 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ var (
genesisHashKey = []byte("genesisID")

// Version is the version of this code
Version = version.NewDefaultVersion(constants.PlatformName, 1, 0, 6)
Version = version.NewDefaultVersion(constants.PlatformName, 1, 1, 0)
versionParser = version.NewDefaultParser()
beaconConnectionTimeout = 1 * time.Minute
)
Expand Down Expand Up @@ -202,8 +202,8 @@ func (n *Node) initNetworking() error {

if reqWeight > 0 {
// Set a timer that will fire after a given timeout unless we connect
// to a suffucient portion of stake-weighted nodes. If the timeout fires,
// the node will shutdown.
// to a sufficient portion of stake-weighted nodes. If the timeout
// fires, the node will shutdown.
timer := timer.NewTimer(func() {
// If the timeout fires and we're already shutting down, nothing to do.
if !n.shuttingDown.GetValue() {
Expand Down Expand Up @@ -244,6 +244,7 @@ func (n *Node) initNetworking() error {
n.Config.RestartOnDisconnected,
n.Config.DisconnectedCheckFreq,
n.Config.DisconnectedRestartTimeout,
n.Config.ApricotPhase0Time,
)

n.nodeCloser = utils.HandleSignals(func(os.Signal) {
Expand Down Expand Up @@ -593,6 +594,7 @@ func (n *Node) initChainManager(avaxAssetID ids.ID) error {
MinStakeDuration: n.Config.MinStakeDuration,
MaxStakeDuration: n.Config.MaxStakeDuration,
StakeMintingPeriod: n.Config.StakeMintingPeriod,
ApricotPhase0Time: n.Config.ApricotPhase0Time,
}),
n.vmManager.RegisterVMFactory(avm.ID, &avm.Factory{
CreationFee: n.Config.CreationTxFee,
Expand Down
Loading

0 comments on commit 34c7ebd

Please sign in to comment.