mirror of https://github.com/poanetwork/gecko.git
Merge pull request #58 from ava-labs/bootstrap-improvements-merged
Bootstrap improvements merged
This commit is contained in:
commit
9ffe0fe47a
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/api"
|
||||
"github.com/ava-labs/gecko/chains"
|
||||
"github.com/ava-labs/gecko/genesis"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/network"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
|
@ -46,38 +47,45 @@ func NewService(nodeID ids.ShortID, networkID uint32, log logging.Logger, chainM
|
|||
return &common.HTTPHandler{Handler: newServer}
|
||||
}
|
||||
|
||||
// GetNodeIDArgs are the arguments for calling GetNodeID
|
||||
type GetNodeIDArgs struct{}
|
||||
|
||||
// GetNodeIDReply are the results from calling GetNodeID
|
||||
type GetNodeIDReply struct {
|
||||
NodeID ids.ShortID `json:"nodeID"`
|
||||
}
|
||||
|
||||
// GetNodeID returns the node ID of this node
|
||||
func (service *Admin) GetNodeID(r *http.Request, args *GetNodeIDArgs, reply *GetNodeIDReply) error {
|
||||
func (service *Admin) GetNodeID(_ *http.Request, _ *struct{}, reply *GetNodeIDReply) error {
|
||||
service.log.Debug("Admin: GetNodeID called")
|
||||
|
||||
reply.NodeID = service.nodeID
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkIDArgs are the arguments for calling GetNetworkID
|
||||
type GetNetworkIDArgs struct{}
|
||||
|
||||
// GetNetworkIDReply are the results from calling GetNetworkID
|
||||
type GetNetworkIDReply struct {
|
||||
NetworkID cjson.Uint32 `json:"networkID"`
|
||||
}
|
||||
|
||||
// GetNetworkID returns the network ID this node is running on
|
||||
func (service *Admin) GetNetworkID(r *http.Request, args *GetNetworkIDArgs, reply *GetNetworkIDReply) error {
|
||||
func (service *Admin) GetNetworkID(_ *http.Request, _ *struct{}, reply *GetNetworkIDReply) error {
|
||||
service.log.Debug("Admin: GetNetworkID called")
|
||||
|
||||
reply.NetworkID = cjson.Uint32(service.networkID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkNameReply is the result from calling GetNetworkName
|
||||
type GetNetworkNameReply struct {
|
||||
NetworkName string `json:"networkName"`
|
||||
}
|
||||
|
||||
// GetNetworkName returns the network name this node is running on
|
||||
func (service *Admin) GetNetworkName(_ *http.Request, _ *struct{}, reply *GetNetworkNameReply) error {
|
||||
service.log.Debug("Admin: GetNetworkName called")
|
||||
|
||||
reply.NetworkName = genesis.NetworkName(service.networkID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlockchainIDArgs are the arguments for calling GetBlockchainID
|
||||
type GetBlockchainIDArgs struct {
|
||||
Alias string `json:"alias"`
|
||||
|
@ -89,7 +97,7 @@ type GetBlockchainIDReply struct {
|
|||
}
|
||||
|
||||
// GetBlockchainID returns the blockchain ID that resolves the alias that was supplied
|
||||
func (service *Admin) GetBlockchainID(r *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
|
||||
func (service *Admin) GetBlockchainID(_ *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
|
||||
service.log.Debug("Admin: GetBlockchainID called")
|
||||
|
||||
bID, err := service.chainManager.Lookup(args.Alias)
|
||||
|
@ -97,16 +105,13 @@ func (service *Admin) GetBlockchainID(r *http.Request, args *GetBlockchainIDArgs
|
|||
return err
|
||||
}
|
||||
|
||||
// PeersArgs are the arguments for calling Peers
|
||||
type PeersArgs struct{}
|
||||
|
||||
// PeersReply are the results from calling Peers
|
||||
type PeersReply struct {
|
||||
Peers []network.PeerID `json:"peers"`
|
||||
}
|
||||
|
||||
// Peers returns the list of current validators
|
||||
func (service *Admin) Peers(r *http.Request, args *PeersArgs, reply *PeersReply) error {
|
||||
func (service *Admin) Peers(_ *http.Request, _ *struct{}, reply *PeersReply) error {
|
||||
service.log.Debug("Admin: Peers called")
|
||||
reply.Peers = service.networking.Peers()
|
||||
return nil
|
||||
|
@ -123,22 +128,19 @@ type StartCPUProfilerReply struct {
|
|||
}
|
||||
|
||||
// StartCPUProfiler starts a cpu profile writing to the specified file
|
||||
func (service *Admin) StartCPUProfiler(r *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
|
||||
func (service *Admin) StartCPUProfiler(_ *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
|
||||
service.log.Debug("Admin: StartCPUProfiler called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.StartCPUProfiler(args.Filename)
|
||||
}
|
||||
|
||||
// StopCPUProfilerArgs are the arguments for calling StopCPUProfiler
|
||||
type StopCPUProfilerArgs struct{}
|
||||
|
||||
// StopCPUProfilerReply are the results from calling StopCPUProfiler
|
||||
type StopCPUProfilerReply struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
// StopCPUProfiler stops the cpu profile
|
||||
func (service *Admin) StopCPUProfiler(r *http.Request, args *StopCPUProfilerArgs, reply *StopCPUProfilerReply) error {
|
||||
func (service *Admin) StopCPUProfiler(_ *http.Request, _ *struct{}, reply *StopCPUProfilerReply) error {
|
||||
service.log.Debug("Admin: StopCPUProfiler called")
|
||||
reply.Success = true
|
||||
return service.performance.StopCPUProfiler()
|
||||
|
@ -155,7 +157,7 @@ type MemoryProfileReply struct {
|
|||
}
|
||||
|
||||
// MemoryProfile runs a memory profile writing to the specified file
|
||||
func (service *Admin) MemoryProfile(r *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
|
||||
func (service *Admin) MemoryProfile(_ *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
|
||||
service.log.Debug("Admin: MemoryProfile called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.MemoryProfile(args.Filename)
|
||||
|
@ -172,7 +174,7 @@ type LockProfileReply struct {
|
|||
}
|
||||
|
||||
// LockProfile runs a mutex profile writing to the specified file
|
||||
func (service *Admin) LockProfile(r *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
|
||||
func (service *Admin) LockProfile(_ *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
|
||||
service.log.Debug("Admin: LockProfile called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.LockProfile(args.Filename)
|
||||
|
@ -190,7 +192,7 @@ type AliasReply struct {
|
|||
}
|
||||
|
||||
// Alias attempts to alias an HTTP endpoint to a new name
|
||||
func (service *Admin) Alias(r *http.Request, args *AliasArgs, reply *AliasReply) error {
|
||||
func (service *Admin) Alias(_ *http.Request, args *AliasArgs, reply *AliasReply) error {
|
||||
service.log.Debug("Admin: Alias called with URL: %s, Alias: %s", args.Endpoint, args.Alias)
|
||||
reply.Success = true
|
||||
return service.httpServer.AddAliasesWithReadLock(args.Endpoint, args.Alias)
|
||||
|
@ -233,7 +235,7 @@ type StacktraceReply struct {
|
|||
}
|
||||
|
||||
// Stacktrace returns the current global stacktrace
|
||||
func (service *Admin) Stacktrace(_ *http.Request, _ *StacktraceArgs, reply *StacktraceReply) error {
|
||||
func (service *Admin) Stacktrace(_ *http.Request, _ *struct{}, reply *StacktraceReply) error {
|
||||
reply.Stacktrace = logging.Stacktrace{Global: true}.String()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -429,7 +429,13 @@ func (m *manager) createAvalancheChain(
|
|||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(&engine, msgChan, defaultChannelSize)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
defaultChannelSize,
|
||||
fmt.Sprintf("%s_handler", consensusParams.Namespace),
|
||||
consensusParams.Metrics,
|
||||
)
|
||||
|
||||
// Allows messages to be routed to the new chain
|
||||
m.chainRouter.AddChain(handler)
|
||||
|
@ -515,7 +521,13 @@ func (m *manager) createSnowmanChain(
|
|||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(&engine, msgChan, defaultChannelSize)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
defaultChannelSize,
|
||||
fmt.Sprintf("%s_handler", consensusParams.Namespace),
|
||||
consensusParams.Metrics,
|
||||
)
|
||||
|
||||
// Allow incoming messages to be routed to the new chain
|
||||
m.chainRouter.AddChain(handler)
|
||||
|
|
|
@ -62,6 +62,9 @@ func (b *UniqueBag) Difference(diff *UniqueBag) {
|
|||
// GetSet ...
|
||||
func (b *UniqueBag) GetSet(id ID) BitSet { return (*b)[*id.ID] }
|
||||
|
||||
// RemoveSet ...
|
||||
func (b *UniqueBag) RemoveSet(id ID) { delete(*b, id.Key()) }
|
||||
|
||||
// List ...
|
||||
func (b *UniqueBag) List() []ID {
|
||||
idList := []ID(nil)
|
||||
|
|
|
@ -41,7 +41,7 @@ func main() {
|
|||
defer Config.DB.Close()
|
||||
|
||||
if Config.StakingIP.IsZero() {
|
||||
log.Warn("NAT traversal has failed. If this node becomes a staker, it may lose its reward due to being unreachable.")
|
||||
log.Warn("NAT traversal has failed. It will be able to connect to less nodes.")
|
||||
}
|
||||
|
||||
// Track if sybil control is enforced
|
||||
|
@ -62,7 +62,7 @@ func main() {
|
|||
|
||||
// Track if assertions should be executed
|
||||
if Config.LoggingConfig.Assertions {
|
||||
log.Warn("assertions are enabled. This may slow down execution")
|
||||
log.Debug("assertions are enabled. This may slow down execution")
|
||||
}
|
||||
|
||||
mapper := nat.NewDefaultMapper(log, Config.Nat, nat.TCP, "gecko")
|
||||
|
@ -83,5 +83,5 @@ func main() {
|
|||
|
||||
log.Debug("dispatching node handlers")
|
||||
err = node.Dispatch()
|
||||
log.Debug("dispatch returned with: %s", err)
|
||||
log.Debug("node dispatching returned with %s", err)
|
||||
}
|
||||
|
|
|
@ -77,6 +77,10 @@ type Vertex interface {
|
|||
// Returns the vertices this vertex depends on
|
||||
Parents() []Vertex
|
||||
|
||||
// Returns the height of this vertex. A vertex's height is defined by one
|
||||
// greater than the maximum height of the parents.
|
||||
Height() uint64
|
||||
|
||||
// Returns a series of state transitions to be performed on acceptance
|
||||
Txs() []snowstorm.Tx
|
||||
|
||||
|
|
|
@ -37,14 +37,14 @@ func (m *metrics) Initialize(log logging.Logger, namespace string, registerer pr
|
|||
Namespace: namespace,
|
||||
Name: "vtx_accepted",
|
||||
Help: "Latency of accepting from the time the vertex was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
m.latRejected = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: namespace,
|
||||
Name: "vtx_rejected",
|
||||
Help: "Latency of rejecting from the time the vertex was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
|
||||
if err := registerer.Register(m.numProcessing); err != nil {
|
||||
|
|
|
@ -16,7 +16,7 @@ type Vtx struct {
|
|||
id ids.ID
|
||||
txs []snowstorm.Tx
|
||||
|
||||
height int
|
||||
height uint64
|
||||
status choices.Status
|
||||
|
||||
bytes []byte
|
||||
|
@ -25,6 +25,7 @@ type Vtx struct {
|
|||
func (v *Vtx) ID() ids.ID { return v.id }
|
||||
func (v *Vtx) ParentIDs() []ids.ID { return nil }
|
||||
func (v *Vtx) Parents() []Vertex { return v.dependencies }
|
||||
func (v *Vtx) Height() uint64 { return v.height }
|
||||
func (v *Vtx) Txs() []snowstorm.Tx { return v.txs }
|
||||
func (v *Vtx) Status() choices.Status { return v.status }
|
||||
func (v *Vtx) Live() {}
|
||||
|
|
|
@ -37,14 +37,14 @@ func (m *metrics) Initialize(log logging.Logger, namespace string, registerer pr
|
|||
Namespace: namespace,
|
||||
Name: "accepted",
|
||||
Help: "Latency of accepting from the time the block was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
m.latRejected = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: namespace,
|
||||
Name: "rejected",
|
||||
Help: "Latency of rejecting from the time the block was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
|
||||
if err := registerer.Register(m.numProcessing); err != nil {
|
||||
|
|
|
@ -37,14 +37,14 @@ func (m *metrics) Initialize(log logging.Logger, namespace string, registerer pr
|
|||
Namespace: namespace,
|
||||
Name: "tx_accepted",
|
||||
Help: "Latency of accepting from the time the transaction was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
m.latRejected = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: namespace,
|
||||
Name: "tx_rejected",
|
||||
Help: "Latency of rejecting from the time the transaction was issued in milliseconds",
|
||||
Buckets: timer.Buckets,
|
||||
Buckets: timer.MillisecondsBuckets,
|
||||
})
|
||||
|
||||
if err := registerer.Register(m.numProcessing); err != nil {
|
||||
|
|
|
@ -236,6 +236,11 @@ func (b *bootstrapper) GetAncestorsFailed(vdr ids.ShortID, requestID uint32) err
|
|||
|
||||
// ForceAccepted ...
|
||||
func (b *bootstrapper) ForceAccepted(acceptedContainerIDs ids.Set) error {
|
||||
if err := b.VM.Bootstrapping(); err != nil {
|
||||
return fmt.Errorf("failed to notify VM that bootstrapping has started: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
for _, vtxID := range acceptedContainerIDs.List() {
|
||||
if vtx, err := b.State.GetVertex(vtxID); err == nil {
|
||||
if err := b.process(vtx); err != nil {
|
||||
|
@ -267,6 +272,11 @@ func (b *bootstrapper) finish() error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := b.VM.Bootstrapped(); err != nil {
|
||||
return fmt.Errorf("failed to notify VM that bootstrapping has finished: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
// Start consensus
|
||||
if err := b.onFinished(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -58,7 +58,13 @@ func newConfig(t *testing.T) (BootstrapConfig, ids.ShortID, *common.SenderTest,
|
|||
peerID := peer.ID()
|
||||
peers.Add(peer)
|
||||
|
||||
handler.Initialize(engine, make(chan common.Message), 1)
|
||||
handler.Initialize(
|
||||
engine,
|
||||
make(chan common.Message),
|
||||
1,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
timeouts.Initialize(0)
|
||||
router.Initialize(ctx.Log, timeouts, time.Hour, time.Second)
|
||||
|
||||
|
@ -83,7 +89,7 @@ func newConfig(t *testing.T) (BootstrapConfig, ids.ShortID, *common.SenderTest,
|
|||
|
||||
// Three vertices in the accepted frontier. None have parents. No need to fetch anything
|
||||
func TestBootstrapperSingleFrontier(t *testing.T) {
|
||||
config, _, _, state, _ := newConfig(t)
|
||||
config, _, _, state, vm := newConfig(t)
|
||||
|
||||
vtxID0 := ids.Empty.Prefix(0)
|
||||
vtxID1 := ids.Empty.Prefix(1)
|
||||
|
@ -148,6 +154,9 @@ func TestBootstrapperSingleFrontier(t *testing.T) {
|
|||
return nil, errParsedUnknownVertex
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
bs.ForceAccepted(acceptedIDs)
|
||||
|
||||
if !*finished {
|
||||
|
@ -170,7 +179,7 @@ func TestBootstrapperSingleFrontier(t *testing.T) {
|
|||
// Requests again and gets an unexpected vertex.
|
||||
// Requests again and gets the expected vertex.
|
||||
func TestBootstrapperByzantineResponses(t *testing.T) {
|
||||
config, peerID, sender, state, _ := newConfig(t)
|
||||
config, peerID, sender, state, vm := newConfig(t)
|
||||
|
||||
vtxID0 := ids.Empty.Prefix(0)
|
||||
vtxID1 := ids.Empty.Prefix(1)
|
||||
|
@ -251,6 +260,7 @@ func TestBootstrapperByzantineResponses(t *testing.T) {
|
|||
t.Fatal(errParsedUnknownVertex)
|
||||
return nil, errParsedUnknownVertex
|
||||
}
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request vtx0
|
||||
t.Fatal(err)
|
||||
|
@ -298,6 +308,9 @@ func TestBootstrapperByzantineResponses(t *testing.T) {
|
|||
panic(errUnknownVertex)
|
||||
}
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{vtxBytes0}); err != nil { // send expected vertex
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -422,6 +435,8 @@ func TestBootstrapperTxDependencies(t *testing.T) {
|
|||
*reqIDPtr = reqID
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request vtx0
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -437,6 +452,9 @@ func TestBootstrapperTxDependencies(t *testing.T) {
|
|||
t.Fatal(errParsedUnknownVertex)
|
||||
return nil, errParsedUnknownVertex
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *reqIDPtr, [][]byte{vtxBytes0}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -459,9 +477,9 @@ func TestBootstrapperTxDependencies(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// Unfilfilled tx dependency
|
||||
// Unfulfilled tx dependency
|
||||
func TestBootstrapperMissingTxDependency(t *testing.T) {
|
||||
config, peerID, sender, state, _ := newConfig(t)
|
||||
config, peerID, sender, state, vm := newConfig(t)
|
||||
|
||||
utxos := []ids.ID{GenerateID(), GenerateID()}
|
||||
|
||||
|
@ -554,10 +572,14 @@ func TestBootstrapperMissingTxDependency(t *testing.T) {
|
|||
*reqIDPtr = reqID
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request vtx1
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *reqIDPtr, [][]byte{vtxBytes0}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -670,7 +692,7 @@ func TestBootstrapperFilterAccepted(t *testing.T) {
|
|||
|
||||
// MultiPut only contains 1 of the two needed vertices; have to issue another GetAncestors
|
||||
func TestBootstrapperIncompleteMultiPut(t *testing.T) {
|
||||
config, peerID, sender, state, _ := newConfig(t)
|
||||
config, peerID, sender, state, vm := newConfig(t)
|
||||
|
||||
vtxID0 := ids.Empty.Prefix(0)
|
||||
vtxID1 := ids.Empty.Prefix(1)
|
||||
|
@ -753,6 +775,8 @@ func TestBootstrapperIncompleteMultiPut(t *testing.T) {
|
|||
requested = vtxID
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request vtx1
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(vtxID1) {
|
||||
|
@ -767,6 +791,8 @@ func TestBootstrapperIncompleteMultiPut(t *testing.T) {
|
|||
t.Fatal("should hae requested vtx0")
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *reqIDPtr, [][]byte{vtxBytes0}); err != nil { // Provide vtx0; can finish now
|
||||
t.Fatal(err)
|
||||
} else if !bs.finished {
|
||||
|
@ -778,5 +804,4 @@ func TestBootstrapperIncompleteMultiPut(t *testing.T) {
|
|||
} else if vtx2.Status() != choices.Accepted {
|
||||
t.Fatal("should be accepted")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ type Vtx struct {
|
|||
id ids.ID
|
||||
txs []snowstorm.Tx
|
||||
|
||||
height int
|
||||
height uint64
|
||||
status choices.Status
|
||||
|
||||
bytes []byte
|
||||
|
@ -36,6 +36,7 @@ type Vtx struct {
|
|||
func (v *Vtx) ID() ids.ID { return v.id }
|
||||
func (v *Vtx) DependencyIDs() []ids.ID { return nil }
|
||||
func (v *Vtx) Parents() []avalanche.Vertex { return v.parents }
|
||||
func (v *Vtx) Height() uint64 { return v.height }
|
||||
func (v *Vtx) Txs() []snowstorm.Tx { return v.txs }
|
||||
func (v *Vtx) Status() choices.Status { return v.status }
|
||||
func (v *Vtx) Accept() error { v.status = choices.Accepted; return nil }
|
||||
|
|
|
@ -121,6 +121,12 @@ func (vtx *uniqueVertex) Parents() []avalanche.Vertex {
|
|||
return vtx.v.parents
|
||||
}
|
||||
|
||||
func (vtx *uniqueVertex) Height() uint64 {
|
||||
vtx.refresh()
|
||||
|
||||
return vtx.v.vtx.height
|
||||
}
|
||||
|
||||
func (vtx *uniqueVertex) Txs() []snowstorm.Tx {
|
||||
vtx.refresh()
|
||||
|
||||
|
|
|
@ -2167,6 +2167,9 @@ func TestEngineBootstrappingIntoConsensus(t *testing.T) {
|
|||
|
||||
vm.Default(true)
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
utxos := []ids.ID{GenerateID(), GenerateID()}
|
||||
|
||||
txID0 := GenerateID()
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
package avalanche
|
||||
|
||||
import (
|
||||
"container/heap"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/consensus/avalanche"
|
||||
)
|
||||
|
||||
// A vertexItem is a Vertex managed by the priority queue.
|
||||
type vertexItem struct {
|
||||
vertex avalanche.Vertex
|
||||
index int // The index of the item in the heap.
|
||||
}
|
||||
|
||||
// A priorityQueue implements heap.Interface and holds vertexItems.
|
||||
type priorityQueue []*vertexItem
|
||||
|
||||
func (pq priorityQueue) Len() int { return len(pq) }
|
||||
|
||||
// Returns true if the vertex at index i has greater height than the vertex at
|
||||
// index j.
|
||||
func (pq priorityQueue) Less(i, j int) bool {
|
||||
statusI := pq[i].vertex.Status()
|
||||
statusJ := pq[j].vertex.Status()
|
||||
|
||||
// Put unknown vertices at the front of the heap to ensure once we have made
|
||||
// it below a certain height in DAG traversal we do not need to reset
|
||||
if !statusI.Fetched() {
|
||||
return true
|
||||
}
|
||||
if !statusJ.Fetched() {
|
||||
return false
|
||||
}
|
||||
return pq[i].vertex.Height() > pq[j].vertex.Height()
|
||||
}
|
||||
|
||||
func (pq priorityQueue) Swap(i, j int) {
|
||||
pq[i], pq[j] = pq[j], pq[i]
|
||||
pq[i].index = i
|
||||
pq[j].index = j
|
||||
}
|
||||
|
||||
// Push adds an item to this priority queue. x must have type *vertexItem
|
||||
func (pq *priorityQueue) Push(x interface{}) {
|
||||
n := len(*pq)
|
||||
item := x.(*vertexItem)
|
||||
item.index = n
|
||||
*pq = append(*pq, item)
|
||||
}
|
||||
|
||||
// Pop returns the last item in this priorityQueue
|
||||
func (pq *priorityQueue) Pop() interface{} {
|
||||
old := *pq
|
||||
n := len(old)
|
||||
item := old[n-1]
|
||||
old[n-1] = nil
|
||||
item.index = -1
|
||||
*pq = old[0 : n-1]
|
||||
return item
|
||||
}
|
||||
|
||||
// vertexHeap defines the functionality of a heap of vertices
|
||||
// with unique VertexIDs ordered by height
|
||||
type vertexHeap interface {
|
||||
Clear()
|
||||
Push(avalanche.Vertex)
|
||||
Pop() avalanche.Vertex // Requires that there be at least one element
|
||||
Contains(avalanche.Vertex) bool
|
||||
Len() int
|
||||
}
|
||||
|
||||
type maxHeightVertexHeap struct {
|
||||
heap *priorityQueue
|
||||
elementIDs ids.Set
|
||||
}
|
||||
|
||||
func newMaxVertexHeap() *maxHeightVertexHeap {
|
||||
return &maxHeightVertexHeap{
|
||||
heap: &priorityQueue{},
|
||||
elementIDs: ids.Set{},
|
||||
}
|
||||
}
|
||||
|
||||
func (vh *maxHeightVertexHeap) Clear() {
|
||||
vh.heap = &priorityQueue{}
|
||||
vh.elementIDs.Clear()
|
||||
}
|
||||
|
||||
// Push adds an element to this heap. Returns true if the element was added.
|
||||
// Returns false if it was already in the heap.
|
||||
func (vh *maxHeightVertexHeap) Push(vtx avalanche.Vertex) bool {
|
||||
vtxID := vtx.ID()
|
||||
if vh.elementIDs.Contains(vtxID) {
|
||||
return false
|
||||
}
|
||||
|
||||
vh.elementIDs.Add(vtxID)
|
||||
item := &vertexItem{
|
||||
vertex: vtx,
|
||||
}
|
||||
heap.Push(vh.heap, item)
|
||||
return true
|
||||
}
|
||||
|
||||
// If there are any vertices in this heap with status Unknown, removes one such
|
||||
// vertex and returns it. Otherwise, removes and returns the vertex in this heap
|
||||
// with the greatest height.
|
||||
func (vh *maxHeightVertexHeap) Pop() avalanche.Vertex {
|
||||
vtx := heap.Pop(vh.heap).(*vertexItem).vertex
|
||||
vh.elementIDs.Remove(vtx.ID())
|
||||
return vtx
|
||||
}
|
||||
|
||||
func (vh *maxHeightVertexHeap) Len() int { return vh.heap.Len() }
|
||||
|
||||
func (vh *maxHeightVertexHeap) Contains(vtxID ids.ID) bool { return vh.elementIDs.Contains(vtxID) }
|
|
@ -0,0 +1,130 @@
|
|||
package avalanche
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/snow/choices"
|
||||
"github.com/ava-labs/gecko/snow/consensus/avalanche"
|
||||
)
|
||||
|
||||
// This example inserts several ints into an IntHeap, checks the minimum,
|
||||
// and removes them in order of priority.
|
||||
func TestUniqueVertexHeapReturnsOrdered(t *testing.T) {
|
||||
h := newMaxVertexHeap()
|
||||
|
||||
vtx0 := &Vtx{
|
||||
id: GenerateID(),
|
||||
height: 0,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
vtx1 := &Vtx{
|
||||
id: GenerateID(),
|
||||
height: 1,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
vtx2 := &Vtx{
|
||||
id: GenerateID(),
|
||||
height: 1,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
vtx3 := &Vtx{
|
||||
id: GenerateID(),
|
||||
height: 3,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
vtx4 := &Vtx{
|
||||
id: GenerateID(),
|
||||
status: choices.Unknown,
|
||||
}
|
||||
|
||||
vts := []avalanche.Vertex{vtx0, vtx1, vtx2, vtx3, vtx4}
|
||||
|
||||
for _, vtx := range vts {
|
||||
h.Push(vtx)
|
||||
}
|
||||
|
||||
vtxZ := h.Pop()
|
||||
if !vtxZ.ID().Equals(vtx4.ID()) {
|
||||
t.Fatalf("Heap did not pop unknown element first")
|
||||
}
|
||||
|
||||
vtxA := h.Pop()
|
||||
if vtxA.Height() != 3 {
|
||||
t.Fatalf("First height from heap was incorrect")
|
||||
} else if !vtxA.ID().Equals(vtx3.ID()) {
|
||||
t.Fatalf("Incorrect ID on vertex popped from heap")
|
||||
}
|
||||
|
||||
vtxB := h.Pop()
|
||||
if vtxB.Height() != 1 {
|
||||
t.Fatalf("First height from heap was incorrect")
|
||||
} else if !vtxB.ID().Equals(vtx1.ID()) && !vtxB.ID().Equals(vtx2.ID()) {
|
||||
t.Fatalf("Incorrect ID on vertex popped from heap")
|
||||
}
|
||||
|
||||
vtxC := h.Pop()
|
||||
if vtxC.Height() != 1 {
|
||||
t.Fatalf("First height from heap was incorrect")
|
||||
} else if !vtxC.ID().Equals(vtx1.ID()) && !vtxC.ID().Equals(vtx2.ID()) {
|
||||
t.Fatalf("Incorrect ID on vertex popped from heap")
|
||||
}
|
||||
|
||||
if vtxB.ID().Equals(vtxC.ID()) {
|
||||
t.Fatalf("Heap returned same element more than once")
|
||||
}
|
||||
|
||||
vtxD := h.Pop()
|
||||
if vtxD.Height() != 0 {
|
||||
t.Fatalf("Last height returned was incorrect")
|
||||
} else if !vtxD.ID().Equals(vtx0.ID()) {
|
||||
t.Fatalf("Last item from heap had incorrect ID")
|
||||
}
|
||||
|
||||
if h.Len() != 0 {
|
||||
t.Fatalf("Heap was not empty after popping all of its elements")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUniqueVertexHeapRemainsUnique(t *testing.T) {
|
||||
h := newMaxVertexHeap()
|
||||
|
||||
vtx0 := &Vtx{
|
||||
height: 0,
|
||||
id: GenerateID(),
|
||||
status: choices.Processing,
|
||||
}
|
||||
vtx1 := &Vtx{
|
||||
height: 1,
|
||||
id: GenerateID(),
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
sharedID := GenerateID()
|
||||
vtx2 := &Vtx{
|
||||
height: 1,
|
||||
id: sharedID,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
vtx3 := &Vtx{
|
||||
height: 2,
|
||||
id: sharedID,
|
||||
status: choices.Processing,
|
||||
}
|
||||
|
||||
pushed1 := h.Push(vtx0)
|
||||
pushed2 := h.Push(vtx1)
|
||||
pushed3 := h.Push(vtx2)
|
||||
pushed4 := h.Push(vtx3)
|
||||
if h.Len() != 3 {
|
||||
t.Fatalf("Unique Vertex Heap has incorrect length: %d", h.Len())
|
||||
} else if !(pushed1 && pushed2 && pushed3) {
|
||||
t.Fatalf("Failed to push a new unique element")
|
||||
} else if pushed4 {
|
||||
t.Fatalf("Pushed non-unique element to the unique vertex heap")
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@ package avalanche
|
|||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/consensus/avalanche"
|
||||
"github.com/ava-labs/gecko/snow/consensus/snowstorm"
|
||||
)
|
||||
|
||||
|
@ -60,36 +59,41 @@ func (v *voter) Update() {
|
|||
}
|
||||
|
||||
if v.t.Consensus.Quiesce() {
|
||||
v.t.Config.Context.Log.Verbo("Avalanche engine can quiesce")
|
||||
v.t.Config.Context.Log.Debug("Avalanche engine can quiesce")
|
||||
return
|
||||
}
|
||||
|
||||
v.t.Config.Context.Log.Verbo("Avalanche engine can't quiesce")
|
||||
v.t.Config.Context.Log.Debug("Avalanche engine can't quiesce")
|
||||
v.t.errs.Add(v.t.repoll())
|
||||
}
|
||||
|
||||
func (v *voter) bubbleVotes(votes ids.UniqueBag) ids.UniqueBag {
|
||||
bubbledVotes := ids.UniqueBag{}
|
||||
vertexHeap := newMaxVertexHeap()
|
||||
for _, vote := range votes.List() {
|
||||
set := votes.GetSet(vote)
|
||||
vtx, err := v.t.Config.State.GetVertex(vote)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
vts := []avalanche.Vertex{vtx}
|
||||
for len(vts) > 0 {
|
||||
vtx := vts[0]
|
||||
vts = vts[1:]
|
||||
vertexHeap.Push(vtx)
|
||||
}
|
||||
|
||||
for vertexHeap.Len() > 0 {
|
||||
vtx := vertexHeap.Pop()
|
||||
vtxID := vtx.ID()
|
||||
set := votes.GetSet(vtxID)
|
||||
status := vtx.Status()
|
||||
|
||||
if !status.Fetched() {
|
||||
v.t.Config.Context.Log.Verbo("Dropping %d vote(s) for %s because the vertex is unknown", set.Len(), vtx.ID())
|
||||
v.t.Config.Context.Log.Verbo("Dropping %d vote(s) for %s because the vertex is unknown", set.Len(), vtxID)
|
||||
bubbledVotes.RemoveSet(vtx.ID())
|
||||
continue
|
||||
}
|
||||
|
||||
if status.Decided() {
|
||||
v.t.Config.Context.Log.Verbo("Dropping %d vote(s) for %s because the vertex is decided", set.Len(), vtx.ID())
|
||||
v.t.Config.Context.Log.Verbo("Dropping %d vote(s) for %s because the vertex is decided", set.Len(), vtxID)
|
||||
bubbledVotes.RemoveSet(vtx.ID())
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -98,9 +102,13 @@ func (v *voter) bubbleVotes(votes ids.UniqueBag) ids.UniqueBag {
|
|||
bubbledVotes.UnionSet(vtx.ID(), set)
|
||||
} else {
|
||||
v.t.Config.Context.Log.Verbo("Bubbling %d vote(s) for %s because the vertex isn't issued", set.Len(), vtx.ID())
|
||||
vts = append(vts, vtx.Parents()...)
|
||||
bubbledVotes.RemoveSet(vtx.ID()) // Remove votes for this vertex because it hasn't been issued
|
||||
for _, parentVtx := range vtx.Parents() {
|
||||
bubbledVotes.UnionSet(parentVtx.ID(), set)
|
||||
vertexHeap.Push(parentVtx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bubbledVotes
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ var (
|
|||
type VMTest struct {
|
||||
T *testing.T
|
||||
|
||||
CantInitialize, CantShutdown, CantCreateHandlers, CantCreateStaticHandlers bool
|
||||
CantInitialize, CantBootstrapping, CantBootstrapped, CantShutdown, CantCreateHandlers, CantCreateStaticHandlers bool
|
||||
|
||||
InitializeF func(*snow.Context, database.Database, []byte, chan<- Message, []*Fx) error
|
||||
ShutdownF func() error
|
||||
BootstrappingF, BootstrappedF, ShutdownF func() error
|
||||
CreateHandlersF func() map[string]*HTTPHandler
|
||||
CreateStaticHandlersF func() map[string]*HTTPHandler
|
||||
}
|
||||
|
@ -30,8 +30,11 @@ type VMTest struct {
|
|||
// Default ...
|
||||
func (vm *VMTest) Default(cant bool) {
|
||||
vm.CantInitialize = cant
|
||||
vm.CantBootstrapping = cant
|
||||
vm.CantBootstrapped = cant
|
||||
vm.CantShutdown = cant
|
||||
vm.CantCreateHandlers = cant
|
||||
vm.CantCreateStaticHandlers = cant
|
||||
}
|
||||
|
||||
// Initialize ...
|
||||
|
@ -45,6 +48,32 @@ func (vm *VMTest) Initialize(ctx *snow.Context, db database.Database, initState
|
|||
return errInitialize
|
||||
}
|
||||
|
||||
// Bootstrapping ...
|
||||
func (vm *VMTest) Bootstrapping() error {
|
||||
if vm.BootstrappingF != nil {
|
||||
return vm.BootstrappingF()
|
||||
} else if vm.CantBootstrapping {
|
||||
if vm.T != nil {
|
||||
vm.T.Fatalf("Unexpectedly called Bootstrapping")
|
||||
}
|
||||
return errors.New("Unexpectedly called Bootstrapping")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bootstrapped ...
|
||||
func (vm *VMTest) Bootstrapped() error {
|
||||
if vm.BootstrappedF != nil {
|
||||
return vm.BootstrappedF()
|
||||
} else if vm.CantBootstrapped {
|
||||
if vm.T != nil {
|
||||
vm.T.Fatalf("Unexpectedly called Bootstrapped")
|
||||
}
|
||||
return errors.New("Unexpectedly called Bootstrapped")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown ...
|
||||
func (vm *VMTest) Shutdown() error {
|
||||
if vm.ShutdownF != nil {
|
||||
|
|
|
@ -12,8 +12,7 @@ import (
|
|||
type VM interface {
|
||||
// Initialize this VM.
|
||||
// [ctx]: Metadata about this VM.
|
||||
// [ctx.networkID]: The ID of the network this VM's chain is running
|
||||
// on.
|
||||
// [ctx.networkID]: The ID of the network this VM's chain is running on.
|
||||
// [ctx.chainID]: The unique ID of the chain this VM is running on.
|
||||
// [ctx.Log]: Used to log messages
|
||||
// [ctx.NodeID]: The unique staker ID of this node.
|
||||
|
@ -37,6 +36,12 @@ type VM interface {
|
|||
fxs []*Fx,
|
||||
) error
|
||||
|
||||
// Bootstrapping is called when the node is starting to bootstrap this chain.
|
||||
Bootstrapping() error
|
||||
|
||||
// Bootstrapped is called when the node is done bootstrapping this chain.
|
||||
Bootstrapped() error
|
||||
|
||||
// Shutdown is called when the node is shutting down.
|
||||
Shutdown() error
|
||||
|
||||
|
|
|
@ -84,6 +84,11 @@ func (b *bootstrapper) FilterAccepted(containerIDs ids.Set) ids.Set {
|
|||
|
||||
// ForceAccepted ...
|
||||
func (b *bootstrapper) ForceAccepted(acceptedContainerIDs ids.Set) error {
|
||||
if err := b.VM.Bootstrapping(); err != nil {
|
||||
return fmt.Errorf("failed to notify VM that bootstrapping has started: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
for _, blkID := range acceptedContainerIDs.List() {
|
||||
if blk, err := b.VM.GetBlock(blkID); err == nil {
|
||||
if err := b.process(blk); err != nil {
|
||||
|
@ -219,11 +224,17 @@ func (b *bootstrapper) finish() error {
|
|||
if b.finished {
|
||||
return nil
|
||||
}
|
||||
b.BootstrapConfig.Context.Log.Info("bootstrapping finished fetching blocks. executing state transitions...")
|
||||
|
||||
if err := b.executeAll(b.Blocked, b.numBlocked); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := b.VM.Bootstrapped(); err != nil {
|
||||
return fmt.Errorf("failed to notify VM that bootstrapping has finished: %w",
|
||||
err)
|
||||
}
|
||||
|
||||
// Start consensus
|
||||
if err := b.onFinished(); err != nil {
|
||||
return err
|
||||
|
|
|
@ -52,7 +52,13 @@ func newConfig(t *testing.T) (BootstrapConfig, ids.ShortID, *common.SenderTest,
|
|||
peerID := peer.ID()
|
||||
peers.Add(peer)
|
||||
|
||||
handler.Initialize(engine, make(chan common.Message), 1)
|
||||
handler.Initialize(
|
||||
engine,
|
||||
make(chan common.Message),
|
||||
1,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
timeouts.Initialize(0)
|
||||
router.Initialize(ctx.Log, timeouts, time.Hour, time.Second)
|
||||
|
||||
|
@ -127,6 +133,9 @@ func TestBootstrapperSingleFrontier(t *testing.T) {
|
|||
return nil, errUnknownBlock
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should finish
|
||||
t.Fatal(err)
|
||||
} else if !*finished {
|
||||
|
@ -225,6 +234,7 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) {
|
|||
}
|
||||
*requestID = reqID
|
||||
}
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request blk1
|
||||
t.Fatal(err)
|
||||
|
@ -249,6 +259,8 @@ func TestBootstrapperUnknownByzantineResponse(t *testing.T) {
|
|||
t.Fatal("should have sent new request")
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes1}); err != nil { // respond with right block
|
||||
t.Fatal(err)
|
||||
} else if !*finished {
|
||||
|
@ -370,6 +382,8 @@ func TestBootstrapperPartialFetch(t *testing.T) {
|
|||
requested = vtxID
|
||||
}
|
||||
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
if err := bs.ForceAccepted(acceptedIDs); err != nil { // should request blk2
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -380,6 +394,8 @@ func TestBootstrapperPartialFetch(t *testing.T) {
|
|||
t.Fatal("should have requested blk1")
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes1}); err != nil { // respond with blk1
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(blkID1) {
|
||||
|
@ -438,6 +454,7 @@ func TestBootstrapperMultiPut(t *testing.T) {
|
|||
status: choices.Processing,
|
||||
bytes: blkBytes3,
|
||||
}
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
bs := bootstrapper{}
|
||||
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
|
||||
|
@ -509,6 +526,8 @@ func TestBootstrapperMultiPut(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
|
||||
vm.CantBootstrapped = false
|
||||
|
||||
if err := bs.MultiPut(peerID, *requestID, [][]byte{blkBytes2, blkBytes1}); err != nil { // respond with blk2 and blk1
|
||||
t.Fatal(err)
|
||||
} else if !requested.Equals(blkID2) {
|
||||
|
@ -586,6 +605,7 @@ func TestBootstrapperFilterAccepted(t *testing.T) {
|
|||
t.Fatal(errUnknownBlock)
|
||||
return nil, errUnknownBlock
|
||||
}
|
||||
vm.CantBootstrapping = false
|
||||
|
||||
accepted := bs.FilterAccepted(blkIDs)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ func (v *voter) Update() {
|
|||
// must be bubbled to the nearest valid block
|
||||
results = v.bubbleVotes(results)
|
||||
|
||||
v.t.Config.Context.Log.Verbo("Finishing poll [%d] with:\n%s", v.requestID, &results)
|
||||
v.t.Config.Context.Log.Debug("Finishing poll [%d] with:\n%s", v.requestID, &results)
|
||||
if err := v.t.Consensus.RecordPoll(results); err != nil {
|
||||
v.t.errs.Add(err)
|
||||
return
|
||||
|
@ -54,11 +54,11 @@ func (v *voter) Update() {
|
|||
v.t.Config.VM.SetPreference(v.t.Consensus.Preference())
|
||||
|
||||
if v.t.Consensus.Finalized() {
|
||||
v.t.Config.Context.Log.Verbo("Snowman engine can quiesce")
|
||||
v.t.Config.Context.Log.Debug("Snowman engine can quiesce")
|
||||
return
|
||||
}
|
||||
|
||||
v.t.Config.Context.Log.Verbo("Snowman engine can't quiesce")
|
||||
v.t.Config.Context.Log.Debug("Snowman engine can't quiesce")
|
||||
v.t.repoll()
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,19 @@
|
|||
package router
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
// Handler passes incoming messages from the network to the consensus engine
|
||||
// (Actually, it receives the incoming messages from a ChainRouter, but same difference)
|
||||
type Handler struct {
|
||||
metrics
|
||||
|
||||
msgs chan message
|
||||
closed chan struct{}
|
||||
engine common.Engine
|
||||
|
@ -21,7 +26,14 @@ type Handler struct {
|
|||
}
|
||||
|
||||
// Initialize this consensus handler
|
||||
func (h *Handler) Initialize(engine common.Engine, msgChan <-chan common.Message, bufferSize int) {
|
||||
func (h *Handler) Initialize(
|
||||
engine common.Engine,
|
||||
msgChan <-chan common.Message,
|
||||
bufferSize int,
|
||||
namespace string,
|
||||
metrics prometheus.Registerer,
|
||||
) {
|
||||
h.metrics.Initialize(namespace, metrics)
|
||||
h.msgs = make(chan message, bufferSize)
|
||||
h.closed = make(chan struct{})
|
||||
h.engine = engine
|
||||
|
@ -47,6 +59,7 @@ func (h *Handler) Dispatch() {
|
|||
if !ok {
|
||||
return
|
||||
}
|
||||
h.metrics.pending.Dec()
|
||||
if closing {
|
||||
log.Debug("dropping message due to closing:\n%s", msg)
|
||||
continue
|
||||
|
@ -73,6 +86,7 @@ func (h *Handler) Dispatch() {
|
|||
// Returns true iff this consensus handler (and its associated engine) should shutdown
|
||||
// (due to receipt of a shutdown message)
|
||||
func (h *Handler) dispatchMsg(msg message) bool {
|
||||
startTime := time.Now()
|
||||
ctx := h.engine.Context()
|
||||
|
||||
ctx.Lock.Lock()
|
||||
|
@ -86,42 +100,61 @@ func (h *Handler) dispatchMsg(msg message) bool {
|
|||
switch msg.messageType {
|
||||
case getAcceptedFrontierMsg:
|
||||
err = h.engine.GetAcceptedFrontier(msg.validatorID, msg.requestID)
|
||||
h.getAcceptedFrontier.Observe(float64(time.Now().Sub(startTime)))
|
||||
case acceptedFrontierMsg:
|
||||
err = h.engine.AcceptedFrontier(msg.validatorID, msg.requestID, msg.containerIDs)
|
||||
h.acceptedFrontier.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getAcceptedFrontierFailedMsg:
|
||||
err = h.engine.GetAcceptedFrontierFailed(msg.validatorID, msg.requestID)
|
||||
h.getAcceptedFrontierFailed.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getAcceptedMsg:
|
||||
err = h.engine.GetAccepted(msg.validatorID, msg.requestID, msg.containerIDs)
|
||||
h.getAccepted.Observe(float64(time.Now().Sub(startTime)))
|
||||
case acceptedMsg:
|
||||
err = h.engine.Accepted(msg.validatorID, msg.requestID, msg.containerIDs)
|
||||
h.accepted.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getAcceptedFailedMsg:
|
||||
err = h.engine.GetAcceptedFailed(msg.validatorID, msg.requestID)
|
||||
case getMsg:
|
||||
err = h.engine.Get(msg.validatorID, msg.requestID, msg.containerID)
|
||||
h.getAcceptedFailed.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getAncestorsMsg:
|
||||
err = h.engine.GetAncestors(msg.validatorID, msg.requestID, msg.containerID)
|
||||
case getFailedMsg:
|
||||
err = h.engine.GetFailed(msg.validatorID, msg.requestID)
|
||||
h.getAncestors.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getAncestorsFailedMsg:
|
||||
err = h.engine.GetAncestorsFailed(msg.validatorID, msg.requestID)
|
||||
case putMsg:
|
||||
err = h.engine.Put(msg.validatorID, msg.requestID, msg.containerID, msg.container)
|
||||
h.getAncestorsFailed.Observe(float64(time.Now().Sub(startTime)))
|
||||
case multiPutMsg:
|
||||
err = h.engine.MultiPut(msg.validatorID, msg.requestID, msg.containers)
|
||||
h.multiPut.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getMsg:
|
||||
err = h.engine.Get(msg.validatorID, msg.requestID, msg.containerID)
|
||||
h.get.Observe(float64(time.Now().Sub(startTime)))
|
||||
case getFailedMsg:
|
||||
err = h.engine.GetFailed(msg.validatorID, msg.requestID)
|
||||
h.getFailed.Observe(float64(time.Now().Sub(startTime)))
|
||||
case putMsg:
|
||||
err = h.engine.Put(msg.validatorID, msg.requestID, msg.containerID, msg.container)
|
||||
h.put.Observe(float64(time.Now().Sub(startTime)))
|
||||
case pushQueryMsg:
|
||||
err = h.engine.PushQuery(msg.validatorID, msg.requestID, msg.containerID, msg.container)
|
||||
h.pushQuery.Observe(float64(time.Now().Sub(startTime)))
|
||||
case pullQueryMsg:
|
||||
err = h.engine.PullQuery(msg.validatorID, msg.requestID, msg.containerID)
|
||||
h.pullQuery.Observe(float64(time.Now().Sub(startTime)))
|
||||
case queryFailedMsg:
|
||||
err = h.engine.QueryFailed(msg.validatorID, msg.requestID)
|
||||
h.queryFailed.Observe(float64(time.Now().Sub(startTime)))
|
||||
case chitsMsg:
|
||||
err = h.engine.Chits(msg.validatorID, msg.requestID, msg.containerIDs)
|
||||
h.chits.Observe(float64(time.Now().Sub(startTime)))
|
||||
case notifyMsg:
|
||||
err = h.engine.Notify(msg.notification)
|
||||
h.notify.Observe(float64(time.Now().Sub(startTime)))
|
||||
case gossipMsg:
|
||||
err = h.engine.Gossip()
|
||||
h.gossip.Observe(float64(time.Now().Sub(startTime)))
|
||||
case shutdownMsg:
|
||||
err = h.engine.Shutdown()
|
||||
h.shutdown.Observe(float64(time.Now().Sub(startTime)))
|
||||
done = true
|
||||
}
|
||||
|
||||
|
@ -134,6 +167,7 @@ func (h *Handler) dispatchMsg(msg message) bool {
|
|||
// GetAcceptedFrontier passes a GetAcceptedFrontier message received from the
|
||||
// network to the consensus engine.
|
||||
func (h *Handler) GetAcceptedFrontier(validatorID ids.ShortID, requestID uint32) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getAcceptedFrontierMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -144,6 +178,7 @@ func (h *Handler) GetAcceptedFrontier(validatorID ids.ShortID, requestID uint32)
|
|||
// AcceptedFrontier passes a AcceptedFrontier message received from the network
|
||||
// to the consensus engine.
|
||||
func (h *Handler) AcceptedFrontier(validatorID ids.ShortID, requestID uint32, containerIDs ids.Set) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: acceptedFrontierMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -155,6 +190,7 @@ func (h *Handler) AcceptedFrontier(validatorID ids.ShortID, requestID uint32, co
|
|||
// GetAcceptedFrontierFailed passes a GetAcceptedFrontierFailed message received
|
||||
// from the network to the consensus engine.
|
||||
func (h *Handler) GetAcceptedFrontierFailed(validatorID ids.ShortID, requestID uint32) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getAcceptedFrontierFailedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -165,6 +201,7 @@ func (h *Handler) GetAcceptedFrontierFailed(validatorID ids.ShortID, requestID u
|
|||
// GetAccepted passes a GetAccepted message received from the
|
||||
// network to the consensus engine.
|
||||
func (h *Handler) GetAccepted(validatorID ids.ShortID, requestID uint32, containerIDs ids.Set) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getAcceptedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -176,6 +213,7 @@ func (h *Handler) GetAccepted(validatorID ids.ShortID, requestID uint32, contain
|
|||
// Accepted passes a Accepted message received from the network to the consensus
|
||||
// engine.
|
||||
func (h *Handler) Accepted(validatorID ids.ShortID, requestID uint32, containerIDs ids.Set) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: acceptedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -187,6 +225,7 @@ func (h *Handler) Accepted(validatorID ids.ShortID, requestID uint32, containerI
|
|||
// GetAcceptedFailed passes a GetAcceptedFailed message received from the
|
||||
// network to the consensus engine.
|
||||
func (h *Handler) GetAcceptedFailed(validatorID ids.ShortID, requestID uint32) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getAcceptedFailedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -196,6 +235,7 @@ func (h *Handler) GetAcceptedFailed(validatorID ids.ShortID, requestID uint32) {
|
|||
|
||||
// Get passes a Get message received from the network to the consensus engine.
|
||||
func (h *Handler) Get(validatorID ids.ShortID, requestID uint32, containerID ids.ID) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -216,6 +256,7 @@ func (h *Handler) GetAncestors(validatorID ids.ShortID, requestID uint32, contai
|
|||
|
||||
// Put passes a Put message received from the network to the consensus engine.
|
||||
func (h *Handler) Put(validatorID ids.ShortID, requestID uint32, containerID ids.ID, container []byte) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: putMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -237,6 +278,7 @@ func (h *Handler) MultiPut(validatorID ids.ShortID, requestID uint32, containers
|
|||
|
||||
// GetFailed passes a GetFailed message to the consensus engine.
|
||||
func (h *Handler) GetFailed(validatorID ids.ShortID, requestID uint32) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: getFailedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -255,6 +297,7 @@ func (h *Handler) GetAncestorsFailed(validatorID ids.ShortID, requestID uint32)
|
|||
|
||||
// PushQuery passes a PushQuery message received from the network to the consensus engine.
|
||||
func (h *Handler) PushQuery(validatorID ids.ShortID, requestID uint32, blockID ids.ID, block []byte) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: pushQueryMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -266,6 +309,7 @@ func (h *Handler) PushQuery(validatorID ids.ShortID, requestID uint32, blockID i
|
|||
|
||||
// PullQuery passes a PullQuery message received from the network to the consensus engine.
|
||||
func (h *Handler) PullQuery(validatorID ids.ShortID, requestID uint32, blockID ids.ID) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: pullQueryMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -276,6 +320,7 @@ func (h *Handler) PullQuery(validatorID ids.ShortID, requestID uint32, blockID i
|
|||
|
||||
// Chits passes a Chits message received from the network to the consensus engine.
|
||||
func (h *Handler) Chits(validatorID ids.ShortID, requestID uint32, votes ids.Set) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: chitsMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -286,6 +331,7 @@ func (h *Handler) Chits(validatorID ids.ShortID, requestID uint32, votes ids.Set
|
|||
|
||||
// QueryFailed passes a QueryFailed message received from the network to the consensus engine.
|
||||
func (h *Handler) QueryFailed(validatorID ids.ShortID, requestID uint32) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: queryFailedMsg,
|
||||
validatorID: validatorID,
|
||||
|
@ -294,13 +340,20 @@ func (h *Handler) QueryFailed(validatorID ids.ShortID, requestID uint32) {
|
|||
}
|
||||
|
||||
// Gossip passes a gossip request to the consensus engine
|
||||
func (h *Handler) Gossip() { h.msgs <- message{messageType: gossipMsg} }
|
||||
func (h *Handler) Gossip() {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{messageType: gossipMsg}
|
||||
}
|
||||
|
||||
// Shutdown shuts down the dispatcher
|
||||
func (h *Handler) Shutdown() { h.msgs <- message{messageType: shutdownMsg} }
|
||||
func (h *Handler) Shutdown() {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{messageType: shutdownMsg}
|
||||
}
|
||||
|
||||
// Notify ...
|
||||
func (h *Handler) Notify(msg common.Message) {
|
||||
h.metrics.pending.Inc()
|
||||
h.msgs <- message{
|
||||
messageType: notifyMsg,
|
||||
notification: msg,
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/ava-labs/gecko/utils/timer"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
)
|
||||
|
||||
func initHistogram(namespace, name string, registerer prometheus.Registerer, errs *wrappers.Errs) prometheus.Histogram {
|
||||
histogram := prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
Help: "Time spent processing this request in nanoseconds",
|
||||
Buckets: timer.NanosecondsBuckets,
|
||||
})
|
||||
|
||||
if err := registerer.Register(histogram); err != nil {
|
||||
errs.Add(fmt.Errorf("failed to register %s statistics due to %s", name, err))
|
||||
}
|
||||
return histogram
|
||||
}
|
||||
|
||||
type metrics struct {
|
||||
pending prometheus.Gauge
|
||||
|
||||
getAcceptedFrontier, acceptedFrontier, getAcceptedFrontierFailed,
|
||||
getAccepted, accepted, getAcceptedFailed,
|
||||
getAncestors, multiPut, getAncestorsFailed,
|
||||
get, put, getFailed,
|
||||
pushQuery, pullQuery, chits, queryFailed,
|
||||
notify,
|
||||
gossip,
|
||||
shutdown prometheus.Histogram
|
||||
}
|
||||
|
||||
// Initialize implements the Engine interface
|
||||
func (m *metrics) Initialize(namespace string, registerer prometheus.Registerer) error {
|
||||
errs := wrappers.Errs{}
|
||||
|
||||
m.pending = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Namespace: namespace,
|
||||
Name: "pending",
|
||||
Help: "Number of pending events",
|
||||
})
|
||||
|
||||
if err := registerer.Register(m.pending); err != nil {
|
||||
errs.Add(fmt.Errorf("failed to register pending statistics due to %s", err))
|
||||
}
|
||||
|
||||
m.getAcceptedFrontier = initHistogram(namespace, "get_accepted_frontier", registerer, &errs)
|
||||
m.acceptedFrontier = initHistogram(namespace, "accepted_frontier", registerer, &errs)
|
||||
m.getAcceptedFrontierFailed = initHistogram(namespace, "get_accepted_frontier_failed", registerer, &errs)
|
||||
m.getAccepted = initHistogram(namespace, "get_accepted", registerer, &errs)
|
||||
m.accepted = initHistogram(namespace, "accepted", registerer, &errs)
|
||||
m.getAcceptedFailed = initHistogram(namespace, "get_accepted_failed", registerer, &errs)
|
||||
m.getAncestors = initHistogram(namespace, "get_ancestors", registerer, &errs)
|
||||
m.multiPut = initHistogram(namespace, "multi_put", registerer, &errs)
|
||||
m.getAncestorsFailed = initHistogram(namespace, "get_ancestors_failed", registerer, &errs)
|
||||
m.get = initHistogram(namespace, "get", registerer, &errs)
|
||||
m.put = initHistogram(namespace, "put", registerer, &errs)
|
||||
m.getFailed = initHistogram(namespace, "get_failed", registerer, &errs)
|
||||
m.pushQuery = initHistogram(namespace, "push_query", registerer, &errs)
|
||||
m.pullQuery = initHistogram(namespace, "pull_query", registerer, &errs)
|
||||
m.chits = initHistogram(namespace, "chits", registerer, &errs)
|
||||
m.queryFailed = initHistogram(namespace, "query_failed", registerer, &errs)
|
||||
m.notify = initHistogram(namespace, "notify", registerer, &errs)
|
||||
m.gossip = initHistogram(namespace, "gossip", registerer, &errs)
|
||||
m.shutdown = initHistogram(namespace, "shutdown", registerer, &errs)
|
||||
|
||||
return errs.Err
|
||||
}
|
|
@ -15,6 +15,7 @@ import (
|
|||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
"github.com/ava-labs/gecko/snow/networking/timeout"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
func TestSenderContext(t *testing.T) {
|
||||
|
@ -58,7 +59,13 @@ func TestTimeout(t *testing.T) {
|
|||
}
|
||||
|
||||
handler := router.Handler{}
|
||||
handler.Initialize(&engine, nil, 1)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
nil,
|
||||
1,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
go handler.Dispatch()
|
||||
|
||||
chainRouter.AddChain(&handler)
|
||||
|
|
|
@ -3,9 +3,13 @@
|
|||
|
||||
package timer
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Useful latency buckets
|
||||
var (
|
||||
Buckets = []float64{
|
||||
MillisecondsBuckets = []float64{
|
||||
10, // 10 ms is ~ instant
|
||||
100, // 100 ms
|
||||
250, // 250 ms
|
||||
|
@ -18,4 +22,15 @@ var (
|
|||
10000, // 10 seconds
|
||||
// anything larger than 10 seconds will be bucketed together
|
||||
}
|
||||
NanosecondsBuckets = []float64{
|
||||
float64(100 * time.Nanosecond),
|
||||
float64(time.Microsecond),
|
||||
float64(10 * time.Microsecond),
|
||||
float64(100 * time.Microsecond),
|
||||
float64(time.Millisecond),
|
||||
float64(10 * time.Millisecond),
|
||||
float64(100 * time.Millisecond),
|
||||
float64(time.Second),
|
||||
// anything larger than a second will be bucketed together
|
||||
}
|
||||
)
|
||||
|
|
|
@ -840,6 +840,16 @@ func TestBaseTxSemanticVerifyUnauthorizedFx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cr := codecRegistry{
|
||||
index: 1,
|
||||
typeToFxIndex: vm.typeToFxIndex,
|
||||
|
@ -1386,6 +1396,16 @@ func TestBaseTxSemanticVerifyPendingUnauthorizedFx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cr := codecRegistry{
|
||||
index: 1,
|
||||
typeToFxIndex: vm.typeToFxIndex,
|
||||
|
@ -1538,6 +1558,16 @@ func TestBaseTxSemanticVerifyPendingInvalidSignature(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
cr := codecRegistry{
|
||||
index: 1,
|
||||
typeToFxIndex: vm.typeToFxIndex,
|
||||
|
|
|
@ -151,6 +151,16 @@ func TestIssueExportTx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key := keys[0]
|
||||
|
||||
tx := &Tx{UnsignedTx: &ExportTx{
|
||||
|
@ -297,6 +307,16 @@ func TestClearForceAcceptedExportTx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key := keys[0]
|
||||
|
||||
tx := &Tx{UnsignedTx: &ExportTx{
|
||||
|
|
|
@ -19,6 +19,12 @@ type Fx interface {
|
|||
// return an error if the VM is incompatible.
|
||||
Initialize(vm interface{}) error
|
||||
|
||||
// Notify this Fx that the VM is in bootstrapping
|
||||
Bootstrapping() error
|
||||
|
||||
// Notify this Fx that the VM is bootstrapped
|
||||
Bootstrapped() error
|
||||
|
||||
// VerifyTransfer verifies that the specified transaction can spend the
|
||||
// provided utxo with no restrictions on the destination. If the transaction
|
||||
// can't spend the output based on the input and credential, a non-nil error
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
package avm
|
||||
|
||||
type testFx struct {
|
||||
initialize, verifyTransfer, verifyOperation error
|
||||
initialize, bootstrapping, bootstrapped, verifyTransfer, verifyOperation error
|
||||
}
|
||||
|
||||
func (fx *testFx) Initialize(_ interface{}) error { return fx.initialize }
|
||||
func (fx *testFx) Bootstrapping() error { return fx.bootstrapping }
|
||||
func (fx *testFx) Bootstrapped() error { return fx.bootstrapped }
|
||||
func (fx *testFx) VerifyTransfer(_, _, _, _ interface{}) error { return fx.verifyTransfer }
|
||||
func (fx *testFx) VerifyOperation(_, _, _ interface{}, _ []interface{}) error {
|
||||
return fx.verifyOperation
|
||||
|
|
|
@ -140,6 +140,16 @@ func TestIssueImportTx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key := keys[0]
|
||||
|
||||
utxoID := ava.UTXOID{
|
||||
|
@ -288,6 +298,16 @@ func TestForceAcceptImportTx(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
key := keys[0]
|
||||
|
||||
genesisTx := GetFirstTxFromGenesisTest(genesisBytes, t)
|
||||
|
|
|
@ -45,6 +45,7 @@ var (
|
|||
errGenesisAssetMustHaveState = errors.New("genesis asset must have non-empty state")
|
||||
errInvalidAddress = errors.New("invalid address")
|
||||
errWrongBlockchainID = errors.New("wrong blockchain ID")
|
||||
errBootstrapping = errors.New("chain is currently bootstrapping")
|
||||
)
|
||||
|
||||
// VM implements the avalanche.DAGVM interface
|
||||
|
@ -67,6 +68,9 @@ type VM struct {
|
|||
// State management
|
||||
state *prefixedState
|
||||
|
||||
// Set to true once this VM is marked as `Bootstrapped` by the engine
|
||||
bootstrapped bool
|
||||
|
||||
// Transaction issuing
|
||||
timer *timer.Timer
|
||||
batchTimeout time.Duration
|
||||
|
@ -197,6 +201,29 @@ func (vm *VM) Initialize(
|
|||
return vm.db.Commit()
|
||||
}
|
||||
|
||||
// Bootstrapping is called by the consensus engine when it starts bootstrapping
|
||||
// this chain
|
||||
func (vm *VM) Bootstrapping() error {
|
||||
for _, fx := range vm.fxs {
|
||||
if err := fx.Fx.Bootstrapping(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Bootstrapped is called by the consensus engine when it is done bootstrapping
|
||||
// this chain
|
||||
func (vm *VM) Bootstrapped() error {
|
||||
for _, fx := range vm.fxs {
|
||||
if err := fx.Fx.Bootstrapped(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
vm.bootstrapped = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Shutdown implements the avalanche.DAGVM interface
|
||||
func (vm *VM) Shutdown() error {
|
||||
if vm.timer == nil {
|
||||
|
@ -272,6 +299,9 @@ func (vm *VM) GetTx(txID ids.ID) (snowstorm.Tx, error) {
|
|||
// either accepted or rejected with the appropriate status. This function will
|
||||
// go out of scope when the transaction is removed from memory.
|
||||
func (vm *VM) IssueTx(b []byte, onDecide func(choices.Status)) (ids.ID, error) {
|
||||
if !vm.bootstrapped {
|
||||
return ids.ID{}, errBootstrapping
|
||||
}
|
||||
tx, err := vm.parseTx(b)
|
||||
if err != nil {
|
||||
return ids.ID{}, err
|
||||
|
|
|
@ -178,6 +178,14 @@ func GenesisVM(t *testing.T) ([]byte, chan common.Message, *VM) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
if err := vm.Bootstrapping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := vm.Bootstrapped(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return genesisBytes, issuer, vm
|
||||
}
|
||||
|
||||
|
@ -678,6 +686,16 @@ func TestIssueNFT(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
createAssetTx := &Tx{UnsignedTx: &CreateAssetTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
|
@ -841,6 +859,16 @@ func TestIssueProperty(t *testing.T) {
|
|||
}
|
||||
vm.batchTimeout = 0
|
||||
|
||||
err = vm.Bootstrapping()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = vm.Bootstrapped()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
createAssetTx := &Tx{UnsignedTx: &CreateAssetTx{
|
||||
BaseTx: BaseTx{
|
||||
NetID: networkID,
|
||||
|
|
|
@ -81,6 +81,12 @@ func (svm *SnowmanVM) GetBlock(ID ids.ID) (snowman.Block, error) {
|
|||
return nil, errBadData // Should never happen
|
||||
}
|
||||
|
||||
// Bootstrapping marks this VM as bootstrapping
|
||||
func (svm *SnowmanVM) Bootstrapping() error { return nil }
|
||||
|
||||
// Bootstrapped marks this VM as bootstrapped
|
||||
func (svm *SnowmanVM) Bootstrapped() error { return nil }
|
||||
|
||||
// Shutdown this vm
|
||||
func (svm *SnowmanVM) Shutdown() error {
|
||||
if svm.DB == nil {
|
||||
|
|
|
@ -399,6 +399,12 @@ func (vm *VM) createChain(tx *CreateChainTx) {
|
|||
vm.chainManager.CreateChain(chainParams)
|
||||
}
|
||||
|
||||
// Bootstrapping marks this VM as bootstrapping
|
||||
func (vm *VM) Bootstrapping() error { return nil }
|
||||
|
||||
// Bootstrapped marks this VM as bootstrapped
|
||||
func (vm *VM) Bootstrapped() error { return nil }
|
||||
|
||||
// Shutdown this blockchain
|
||||
func (vm *VM) Shutdown() error {
|
||||
if vm.timer == nil {
|
||||
|
|
|
@ -1598,7 +1598,13 @@ func TestBootstrapPartiallyAccepted(t *testing.T) {
|
|||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(&engine, msgChan, 1000)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
1000,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
|
||||
// Allow incoming messages to be routed to the new chain
|
||||
chainRouter.AddChain(handler)
|
||||
|
|
|
@ -129,6 +129,18 @@ func (vm *VMClient) startMessengerServer(opts []grpc.ServerOption) *grpc.Server
|
|||
return server
|
||||
}
|
||||
|
||||
// Bootstrapping ...
|
||||
func (vm *VMClient) Bootstrapping() error {
|
||||
_, err := vm.client.Bootstrapping(context.Background(), &vmproto.BootstrappingRequest{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Bootstrapped ...
|
||||
func (vm *VMClient) Bootstrapped() error {
|
||||
_, err := vm.client.Bootstrapped(context.Background(), &vmproto.BootstrappedRequest{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Shutdown ...
|
||||
func (vm *VMClient) Shutdown() error {
|
||||
vm.lock.Lock()
|
||||
|
|
|
@ -84,8 +84,18 @@ func (vm *VMServer) Initialize(_ context.Context, req *vmproto.InitializeRequest
|
|||
return &vmproto.InitializeResponse{}, nil
|
||||
}
|
||||
|
||||
// Bootstrapping ...
|
||||
func (vm *VMServer) Bootstrapping(context.Context, *vmproto.BootstrappingRequest) (*vmproto.BootstrappingResponse, error) {
|
||||
return &vmproto.BootstrappingResponse{}, vm.vm.Bootstrapping()
|
||||
}
|
||||
|
||||
// Bootstrapped ...
|
||||
func (vm *VMServer) Bootstrapped(context.Context, *vmproto.BootstrappedRequest) (*vmproto.BootstrappedResponse, error) {
|
||||
return &vmproto.BootstrappedResponse{}, vm.vm.Bootstrapped()
|
||||
}
|
||||
|
||||
// Shutdown ...
|
||||
func (vm *VMServer) Shutdown(_ context.Context, _ *vmproto.ShutdownRequest) (*vmproto.ShutdownResponse, error) {
|
||||
func (vm *VMServer) Shutdown(context.Context, *vmproto.ShutdownRequest) (*vmproto.ShutdownResponse, error) {
|
||||
vm.lock.Lock()
|
||||
defer vm.lock.Unlock()
|
||||
|
||||
|
|
|
@ -110,6 +110,130 @@ func (m *InitializeResponse) XXX_DiscardUnknown() {
|
|||
|
||||
var xxx_messageInfo_InitializeResponse proto.InternalMessageInfo
|
||||
|
||||
type BootstrappingRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BootstrappingRequest) Reset() { *m = BootstrappingRequest{} }
|
||||
func (m *BootstrappingRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BootstrappingRequest) ProtoMessage() {}
|
||||
func (*BootstrappingRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{2}
|
||||
}
|
||||
|
||||
func (m *BootstrappingRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BootstrappingRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BootstrappingRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BootstrappingRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BootstrappingRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BootstrappingRequest.Merge(m, src)
|
||||
}
|
||||
func (m *BootstrappingRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_BootstrappingRequest.Size(m)
|
||||
}
|
||||
func (m *BootstrappingRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BootstrappingRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BootstrappingRequest proto.InternalMessageInfo
|
||||
|
||||
type BootstrappingResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BootstrappingResponse) Reset() { *m = BootstrappingResponse{} }
|
||||
func (m *BootstrappingResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BootstrappingResponse) ProtoMessage() {}
|
||||
func (*BootstrappingResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{3}
|
||||
}
|
||||
|
||||
func (m *BootstrappingResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BootstrappingResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BootstrappingResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BootstrappingResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BootstrappingResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BootstrappingResponse.Merge(m, src)
|
||||
}
|
||||
func (m *BootstrappingResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_BootstrappingResponse.Size(m)
|
||||
}
|
||||
func (m *BootstrappingResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BootstrappingResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BootstrappingResponse proto.InternalMessageInfo
|
||||
|
||||
type BootstrappedRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BootstrappedRequest) Reset() { *m = BootstrappedRequest{} }
|
||||
func (m *BootstrappedRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BootstrappedRequest) ProtoMessage() {}
|
||||
func (*BootstrappedRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{4}
|
||||
}
|
||||
|
||||
func (m *BootstrappedRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BootstrappedRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BootstrappedRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BootstrappedRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BootstrappedRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BootstrappedRequest.Merge(m, src)
|
||||
}
|
||||
func (m *BootstrappedRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_BootstrappedRequest.Size(m)
|
||||
}
|
||||
func (m *BootstrappedRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BootstrappedRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BootstrappedRequest proto.InternalMessageInfo
|
||||
|
||||
type BootstrappedResponse struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BootstrappedResponse) Reset() { *m = BootstrappedResponse{} }
|
||||
func (m *BootstrappedResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BootstrappedResponse) ProtoMessage() {}
|
||||
func (*BootstrappedResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{5}
|
||||
}
|
||||
|
||||
func (m *BootstrappedResponse) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BootstrappedResponse.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BootstrappedResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BootstrappedResponse.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BootstrappedResponse) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BootstrappedResponse.Merge(m, src)
|
||||
}
|
||||
func (m *BootstrappedResponse) XXX_Size() int {
|
||||
return xxx_messageInfo_BootstrappedResponse.Size(m)
|
||||
}
|
||||
func (m *BootstrappedResponse) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BootstrappedResponse.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BootstrappedResponse proto.InternalMessageInfo
|
||||
|
||||
type ShutdownRequest struct {
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
@ -120,7 +244,7 @@ func (m *ShutdownRequest) Reset() { *m = ShutdownRequest{} }
|
|||
func (m *ShutdownRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ShutdownRequest) ProtoMessage() {}
|
||||
func (*ShutdownRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{2}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{6}
|
||||
}
|
||||
|
||||
func (m *ShutdownRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -151,7 +275,7 @@ func (m *ShutdownResponse) Reset() { *m = ShutdownResponse{} }
|
|||
func (m *ShutdownResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ShutdownResponse) ProtoMessage() {}
|
||||
func (*ShutdownResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{3}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{7}
|
||||
}
|
||||
|
||||
func (m *ShutdownResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -182,7 +306,7 @@ func (m *CreateHandlersRequest) Reset() { *m = CreateHandlersRequest{} }
|
|||
func (m *CreateHandlersRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateHandlersRequest) ProtoMessage() {}
|
||||
func (*CreateHandlersRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{4}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{8}
|
||||
}
|
||||
|
||||
func (m *CreateHandlersRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -214,7 +338,7 @@ func (m *CreateHandlersResponse) Reset() { *m = CreateHandlersResponse{}
|
|||
func (m *CreateHandlersResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateHandlersResponse) ProtoMessage() {}
|
||||
func (*CreateHandlersResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{5}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{9}
|
||||
}
|
||||
|
||||
func (m *CreateHandlersResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -255,7 +379,7 @@ func (m *Handler) Reset() { *m = Handler{} }
|
|||
func (m *Handler) String() string { return proto.CompactTextString(m) }
|
||||
func (*Handler) ProtoMessage() {}
|
||||
func (*Handler) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{6}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{10}
|
||||
}
|
||||
|
||||
func (m *Handler) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -307,7 +431,7 @@ func (m *BuildBlockRequest) Reset() { *m = BuildBlockRequest{} }
|
|||
func (m *BuildBlockRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BuildBlockRequest) ProtoMessage() {}
|
||||
func (*BuildBlockRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{7}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{11}
|
||||
}
|
||||
|
||||
func (m *BuildBlockRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -341,7 +465,7 @@ func (m *BuildBlockResponse) Reset() { *m = BuildBlockResponse{} }
|
|||
func (m *BuildBlockResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BuildBlockResponse) ProtoMessage() {}
|
||||
func (*BuildBlockResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{8}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{12}
|
||||
}
|
||||
|
||||
func (m *BuildBlockResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -394,7 +518,7 @@ func (m *ParseBlockRequest) Reset() { *m = ParseBlockRequest{} }
|
|||
func (m *ParseBlockRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ParseBlockRequest) ProtoMessage() {}
|
||||
func (*ParseBlockRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{9}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{13}
|
||||
}
|
||||
|
||||
func (m *ParseBlockRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -435,7 +559,7 @@ func (m *ParseBlockResponse) Reset() { *m = ParseBlockResponse{} }
|
|||
func (m *ParseBlockResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*ParseBlockResponse) ProtoMessage() {}
|
||||
func (*ParseBlockResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{10}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{14}
|
||||
}
|
||||
|
||||
func (m *ParseBlockResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -488,7 +612,7 @@ func (m *GetBlockRequest) Reset() { *m = GetBlockRequest{} }
|
|||
func (m *GetBlockRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetBlockRequest) ProtoMessage() {}
|
||||
func (*GetBlockRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{11}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{15}
|
||||
}
|
||||
|
||||
func (m *GetBlockRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -529,7 +653,7 @@ func (m *GetBlockResponse) Reset() { *m = GetBlockResponse{} }
|
|||
func (m *GetBlockResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetBlockResponse) ProtoMessage() {}
|
||||
func (*GetBlockResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{12}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{16}
|
||||
}
|
||||
|
||||
func (m *GetBlockResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -582,7 +706,7 @@ func (m *SetPreferenceRequest) Reset() { *m = SetPreferenceRequest{} }
|
|||
func (m *SetPreferenceRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetPreferenceRequest) ProtoMessage() {}
|
||||
func (*SetPreferenceRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{13}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{17}
|
||||
}
|
||||
|
||||
func (m *SetPreferenceRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -620,7 +744,7 @@ func (m *SetPreferenceResponse) Reset() { *m = SetPreferenceResponse{} }
|
|||
func (m *SetPreferenceResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetPreferenceResponse) ProtoMessage() {}
|
||||
func (*SetPreferenceResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{14}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{18}
|
||||
}
|
||||
|
||||
func (m *SetPreferenceResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -651,7 +775,7 @@ func (m *LastAcceptedRequest) Reset() { *m = LastAcceptedRequest{} }
|
|||
func (m *LastAcceptedRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*LastAcceptedRequest) ProtoMessage() {}
|
||||
func (*LastAcceptedRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{15}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{19}
|
||||
}
|
||||
|
||||
func (m *LastAcceptedRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -683,7 +807,7 @@ func (m *LastAcceptedResponse) Reset() { *m = LastAcceptedResponse{} }
|
|||
func (m *LastAcceptedResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*LastAcceptedResponse) ProtoMessage() {}
|
||||
func (*LastAcceptedResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{16}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{20}
|
||||
}
|
||||
|
||||
func (m *LastAcceptedResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -722,7 +846,7 @@ func (m *BlockVerifyRequest) Reset() { *m = BlockVerifyRequest{} }
|
|||
func (m *BlockVerifyRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockVerifyRequest) ProtoMessage() {}
|
||||
func (*BlockVerifyRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{17}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{21}
|
||||
}
|
||||
|
||||
func (m *BlockVerifyRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -760,7 +884,7 @@ func (m *BlockVerifyResponse) Reset() { *m = BlockVerifyResponse{} }
|
|||
func (m *BlockVerifyResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockVerifyResponse) ProtoMessage() {}
|
||||
func (*BlockVerifyResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{18}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{22}
|
||||
}
|
||||
|
||||
func (m *BlockVerifyResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -792,7 +916,7 @@ func (m *BlockAcceptRequest) Reset() { *m = BlockAcceptRequest{} }
|
|||
func (m *BlockAcceptRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockAcceptRequest) ProtoMessage() {}
|
||||
func (*BlockAcceptRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{19}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{23}
|
||||
}
|
||||
|
||||
func (m *BlockAcceptRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -830,7 +954,7 @@ func (m *BlockAcceptResponse) Reset() { *m = BlockAcceptResponse{} }
|
|||
func (m *BlockAcceptResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockAcceptResponse) ProtoMessage() {}
|
||||
func (*BlockAcceptResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{20}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{24}
|
||||
}
|
||||
|
||||
func (m *BlockAcceptResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -862,7 +986,7 @@ func (m *BlockRejectRequest) Reset() { *m = BlockRejectRequest{} }
|
|||
func (m *BlockRejectRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockRejectRequest) ProtoMessage() {}
|
||||
func (*BlockRejectRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{21}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{25}
|
||||
}
|
||||
|
||||
func (m *BlockRejectRequest) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -900,7 +1024,7 @@ func (m *BlockRejectResponse) Reset() { *m = BlockRejectResponse{} }
|
|||
func (m *BlockRejectResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*BlockRejectResponse) ProtoMessage() {}
|
||||
func (*BlockRejectResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{22}
|
||||
return fileDescriptor_cab246c8c7c5372d, []int{26}
|
||||
}
|
||||
|
||||
func (m *BlockRejectResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -924,6 +1048,10 @@ var xxx_messageInfo_BlockRejectResponse proto.InternalMessageInfo
|
|||
func init() {
|
||||
proto.RegisterType((*InitializeRequest)(nil), "vmproto.InitializeRequest")
|
||||
proto.RegisterType((*InitializeResponse)(nil), "vmproto.InitializeResponse")
|
||||
proto.RegisterType((*BootstrappingRequest)(nil), "vmproto.BootstrappingRequest")
|
||||
proto.RegisterType((*BootstrappingResponse)(nil), "vmproto.BootstrappingResponse")
|
||||
proto.RegisterType((*BootstrappedRequest)(nil), "vmproto.BootstrappedRequest")
|
||||
proto.RegisterType((*BootstrappedResponse)(nil), "vmproto.BootstrappedResponse")
|
||||
proto.RegisterType((*ShutdownRequest)(nil), "vmproto.ShutdownRequest")
|
||||
proto.RegisterType((*ShutdownResponse)(nil), "vmproto.ShutdownResponse")
|
||||
proto.RegisterType((*CreateHandlersRequest)(nil), "vmproto.CreateHandlersRequest")
|
||||
|
@ -950,46 +1078,49 @@ func init() {
|
|||
func init() { proto.RegisterFile("vm.proto", fileDescriptor_cab246c8c7c5372d) }
|
||||
|
||||
var fileDescriptor_cab246c8c7c5372d = []byte{
|
||||
// 617 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x6d, 0x6f, 0xd2, 0x50,
|
||||
0x14, 0x4e, 0x21, 0x32, 0x3c, 0xc0, 0x06, 0x17, 0xd8, 0xb0, 0x6e, 0x13, 0x1b, 0xb3, 0x60, 0x62,
|
||||
0xf8, 0x30, 0x7f, 0xc0, 0x22, 0x8a, 0x6e, 0xf1, 0x6d, 0x96, 0x84, 0x98, 0xe8, 0x97, 0x42, 0x0f,
|
||||
0x5b, 0x95, 0xb5, 0xf5, 0xde, 0x0b, 0x73, 0xfe, 0x23, 0xff, 0xa5, 0xa1, 0xbd, 0x6d, 0xef, 0xbd,
|
||||
0xb4, 0x59, 0xe2, 0xb7, 0x9e, 0x73, 0x9e, 0xf3, 0x9c, 0x97, 0x7b, 0x9e, 0x42, 0x75, 0x7d, 0x33,
|
||||
0x0c, 0x69, 0xc0, 0x03, 0xb2, 0xb3, 0xbe, 0x89, 0x3e, 0xac, 0x5b, 0x68, 0x5d, 0xf8, 0x1e, 0xf7,
|
||||
0x9c, 0xa5, 0xf7, 0x07, 0x6d, 0xfc, 0xb5, 0x42, 0xc6, 0x89, 0x09, 0x55, 0x77, 0x36, 0x41, 0xba,
|
||||
0x46, 0xda, 0x33, 0xfa, 0xc6, 0xa0, 0x61, 0xa7, 0x36, 0xb1, 0xa0, 0x7e, 0x85, 0x3e, 0x32, 0x8f,
|
||||
0x8d, 0xee, 0x38, 0xb2, 0x5e, 0xa9, 0x6f, 0x0c, 0xea, 0xb6, 0xe2, 0xdb, 0x60, 0xd0, 0xbf, 0xf2,
|
||||
0x7c, 0x14, 0x1c, 0xe5, 0x88, 0x43, 0xf1, 0x59, 0x1d, 0x20, 0x72, 0x61, 0x16, 0x06, 0x3e, 0x43,
|
||||
0xab, 0x05, 0x7b, 0x93, 0xeb, 0x15, 0x77, 0x83, 0x5b, 0x5f, 0x34, 0x63, 0x11, 0x68, 0x66, 0x2e,
|
||||
0x01, 0x3b, 0x80, 0xee, 0x6b, 0x8a, 0x0e, 0xc7, 0x73, 0xc7, 0x77, 0x97, 0x48, 0x59, 0x02, 0x7e,
|
||||
0x0b, 0xfb, 0x7a, 0x20, 0x4e, 0x21, 0x2f, 0xa0, 0x7a, 0x2d, 0x7c, 0x3d, 0xa3, 0x5f, 0x1e, 0xd4,
|
||||
0x4e, 0x9b, 0x43, 0xb1, 0x84, 0xa1, 0x00, 0xdb, 0x29, 0xc2, 0xfa, 0x06, 0x3b, 0xc2, 0x49, 0xf6,
|
||||
0xa1, 0x12, 0x52, 0x5c, 0x78, 0xbf, 0xa3, 0x55, 0x3c, 0xb4, 0x85, 0x45, 0xfa, 0x50, 0x5b, 0x06,
|
||||
0xf3, 0x9f, 0x9f, 0x43, 0xee, 0x05, 0x7e, 0xbc, 0x87, 0x86, 0x2d, 0xbb, 0x36, 0x99, 0x4c, 0x5e,
|
||||
0x80, 0xb0, 0xac, 0x36, 0xb4, 0x46, 0x2b, 0x6f, 0xe9, 0x8e, 0x36, 0xe0, 0xa4, 0xf3, 0x29, 0x10,
|
||||
0xd9, 0x29, 0xba, 0xde, 0x85, 0x92, 0xe7, 0x46, 0x85, 0xeb, 0x76, 0xc9, 0x73, 0x37, 0x2f, 0x13,
|
||||
0x3a, 0x14, 0x7d, 0x7e, 0xf1, 0x46, 0x6c, 0x3e, 0xb5, 0x49, 0x07, 0x1e, 0xcc, 0xa2, 0x27, 0x29,
|
||||
0x47, 0x81, 0xd8, 0xb0, 0x9e, 0x43, 0xeb, 0xd2, 0xa1, 0x0c, 0xe5, 0x62, 0x19, 0xd4, 0x90, 0xa1,
|
||||
0x5f, 0x81, 0xc8, 0xd0, 0xff, 0x68, 0x61, 0x33, 0x31, 0x77, 0xf8, 0x8a, 0xa5, 0x13, 0x47, 0x96,
|
||||
0xf5, 0x14, 0xf6, 0xde, 0x21, 0x57, 0x5a, 0xd0, 0x68, 0xad, 0xef, 0xd0, 0xcc, 0x20, 0xa2, 0xb4,
|
||||
0x5c, 0xca, 0x28, 0x9a, 0xb6, 0x24, 0x8d, 0x50, 0xd8, 0xc0, 0x09, 0x74, 0x26, 0xc8, 0x2f, 0x29,
|
||||
0x2e, 0x90, 0xa2, 0x3f, 0xc7, 0xa2, 0x2e, 0x0e, 0xa0, 0xab, 0xe1, 0xc4, 0xc5, 0x75, 0xa1, 0xfd,
|
||||
0xc1, 0x61, 0xfc, 0xd5, 0x7c, 0x8e, 0x21, 0x47, 0x37, 0x79, 0xb5, 0x13, 0xe8, 0xa8, 0xee, 0xfc,
|
||||
0xa5, 0x59, 0xcf, 0x80, 0x44, 0xa3, 0x4d, 0x91, 0x7a, 0x8b, 0xbb, 0xa2, 0xea, 0x5d, 0x68, 0x2b,
|
||||
0x28, 0x51, 0x3b, 0x49, 0x8e, 0xab, 0xdc, 0x97, 0x9c, 0xa0, 0xb4, 0x64, 0x1b, 0x7f, 0xe0, 0xfc,
|
||||
0xde, 0xe4, 0x04, 0x15, 0x27, 0x9f, 0xfe, 0xad, 0x40, 0x69, 0xfa, 0x91, 0x8c, 0x01, 0x32, 0xad,
|
||||
0x12, 0x33, 0xd5, 0xcd, 0xd6, 0x9f, 0xc3, 0x7c, 0x9c, 0x1b, 0x13, 0x4b, 0x39, 0x83, 0x6a, 0xa2,
|
||||
0x64, 0xd2, 0x4b, 0x81, 0x9a, 0xde, 0xcd, 0x47, 0x39, 0x11, 0x41, 0xf0, 0x05, 0x76, 0x55, 0x75,
|
||||
0x93, 0xe3, 0x14, 0x9c, 0xfb, 0x3f, 0x30, 0x9f, 0x14, 0xc6, 0x05, 0xe5, 0x18, 0x20, 0x93, 0x9d,
|
||||
0x34, 0xda, 0x96, 0x40, 0xa5, 0xd1, 0x72, 0x74, 0x3a, 0x06, 0xc8, 0xa4, 0x23, 0xd1, 0x6c, 0x49,
|
||||
0x4f, 0xa2, 0xc9, 0xd1, 0xda, 0x19, 0x54, 0x13, 0x11, 0x48, 0x1b, 0xd2, 0xa4, 0x23, 0x6d, 0x68,
|
||||
0x4b, 0x31, 0x9f, 0xa0, 0xa1, 0xdc, 0x2f, 0x39, 0xca, 0xb6, 0x99, 0x73, 0xff, 0xe6, 0x71, 0x51,
|
||||
0x58, 0xf0, 0xbd, 0x87, 0xba, 0x7c, 0xdf, 0xe4, 0x30, 0xc5, 0xe7, 0xa8, 0xc1, 0x3c, 0x2a, 0x88,
|
||||
0x0a, 0xb2, 0x73, 0xa8, 0x49, 0xe7, 0x4d, 0xa4, 0x85, 0x6e, 0x49, 0xc3, 0x3c, 0xcc, 0x0f, 0x6a,
|
||||
0x4c, 0x71, 0x09, 0x9d, 0x49, 0xd1, 0x89, 0xce, 0xa4, 0xca, 0x23, 0x65, 0x8a, 0x0f, 0x5f, 0x67,
|
||||
0x52, 0x44, 0xa3, 0x33, 0xa9, 0x5a, 0x99, 0x55, 0xa2, 0xd0, 0xcb, 0x7f, 0x01, 0x00, 0x00, 0xff,
|
||||
0xff, 0xbb, 0xac, 0x5b, 0xc8, 0x65, 0x07, 0x00, 0x00,
|
||||
// 672 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x54, 0x61, 0x4f, 0x13, 0x41,
|
||||
0x10, 0x4d, 0x4b, 0x84, 0x3a, 0xb4, 0x40, 0x97, 0x16, 0xea, 0x09, 0x5a, 0x2f, 0x86, 0x60, 0x62,
|
||||
0xf8, 0x80, 0x3f, 0x80, 0x58, 0x45, 0x21, 0x2a, 0xe2, 0x91, 0x10, 0x13, 0xfd, 0x72, 0xf4, 0x06,
|
||||
0x38, 0x2d, 0x77, 0xe7, 0xee, 0xb6, 0x88, 0x3f, 0xd0, 0xdf, 0x65, 0xee, 0x6e, 0xef, 0x6e, 0x76,
|
||||
0xbb, 0x17, 0x12, 0xbf, 0x75, 0x67, 0xde, 0xbc, 0x99, 0x9b, 0xe9, 0x7b, 0xd0, 0x9a, 0xdd, 0xec,
|
||||
0x25, 0x3c, 0x96, 0x31, 0x5b, 0x9a, 0xdd, 0x64, 0x3f, 0xdc, 0x5b, 0xe8, 0x1e, 0x47, 0xa1, 0x0c,
|
||||
0xfd, 0x49, 0xf8, 0x07, 0x3d, 0xfc, 0x35, 0x45, 0x21, 0x99, 0x03, 0xad, 0xe0, 0xe2, 0x0c, 0xf9,
|
||||
0x0c, 0xf9, 0xa0, 0x31, 0x6c, 0xec, 0x76, 0xbc, 0xf2, 0xcd, 0x5c, 0x68, 0x5f, 0x61, 0x84, 0x22,
|
||||
0x14, 0xa3, 0x3b, 0x89, 0x62, 0xd0, 0x1c, 0x36, 0x76, 0xdb, 0x9e, 0x16, 0x4b, 0x31, 0x18, 0x5d,
|
||||
0x85, 0x11, 0x2a, 0x8e, 0x85, 0x8c, 0x43, 0x8b, 0xb9, 0x3d, 0x60, 0xb4, 0xb1, 0x48, 0xe2, 0x48,
|
||||
0xa0, 0xbb, 0x01, 0xbd, 0x51, 0x1c, 0x4b, 0x21, 0xb9, 0x9f, 0x24, 0x61, 0x74, 0xa5, 0x26, 0x72,
|
||||
0x37, 0xa1, 0x6f, 0xc4, 0x55, 0x41, 0x1f, 0xd6, 0xab, 0x04, 0x06, 0x05, 0x5e, 0xe3, 0x49, 0xc3,
|
||||
0x0a, 0xde, 0x85, 0xd5, 0xb3, 0xeb, 0xa9, 0x0c, 0xe2, 0xdb, 0xa8, 0x80, 0x32, 0x58, 0xab, 0x42,
|
||||
0x0a, 0xb6, 0x09, 0xfd, 0x37, 0x1c, 0x7d, 0x89, 0x47, 0x7e, 0x14, 0x4c, 0x90, 0x8b, 0x02, 0xfc,
|
||||
0x0e, 0x36, 0xcc, 0x44, 0x5e, 0xc2, 0x5e, 0x42, 0xeb, 0x5a, 0xc5, 0x06, 0x8d, 0xe1, 0xc2, 0xee,
|
||||
0xf2, 0xfe, 0xda, 0x9e, 0x5a, 0xf2, 0x9e, 0x02, 0x7b, 0x25, 0xc2, 0xfd, 0x06, 0x4b, 0x2a, 0xc8,
|
||||
0x36, 0x60, 0x31, 0xe1, 0x78, 0x19, 0xfe, 0xce, 0x56, 0xfd, 0xd0, 0x53, 0x2f, 0x36, 0x84, 0xe5,
|
||||
0x49, 0x3c, 0xfe, 0xf9, 0x39, 0x91, 0x61, 0x1c, 0xe5, 0x7b, 0xee, 0x78, 0x34, 0x94, 0x56, 0x0a,
|
||||
0xba, 0x60, 0xf5, 0x72, 0xd7, 0xa1, 0x3b, 0x9a, 0x86, 0x93, 0x60, 0x94, 0x82, 0x8b, 0xc9, 0xcf,
|
||||
0x81, 0xd1, 0xa0, 0x9a, 0x7a, 0x05, 0x9a, 0x61, 0x90, 0x35, 0x6e, 0x7b, 0xcd, 0x30, 0x48, 0x2f,
|
||||
0x9f, 0xf8, 0x1c, 0x23, 0x79, 0xfc, 0x56, 0x5d, 0xb6, 0x7c, 0xb3, 0x1e, 0x3c, 0xb8, 0xc8, 0x4e,
|
||||
0xbe, 0x90, 0x25, 0xf2, 0x87, 0xfb, 0x02, 0xba, 0xa7, 0x3e, 0x17, 0x48, 0x9b, 0x55, 0xd0, 0x06,
|
||||
0x85, 0x7e, 0x05, 0x46, 0xa1, 0xff, 0x31, 0x42, 0xfa, 0xc5, 0xd2, 0x97, 0x53, 0x51, 0x7e, 0x71,
|
||||
0xf6, 0x72, 0x9f, 0xc1, 0xea, 0x7b, 0x94, 0xda, 0x08, 0x06, 0xad, 0xfb, 0x1d, 0xd6, 0x2a, 0x88,
|
||||
0x6a, 0x4d, 0x5b, 0x35, 0xea, 0xbe, 0xb6, 0x49, 0x3e, 0xa1, 0x76, 0x80, 0x1d, 0xe8, 0x9d, 0xa1,
|
||||
0x3c, 0xe5, 0x78, 0x89, 0x1c, 0xa3, 0x31, 0xd6, 0x4d, 0xb1, 0x09, 0x7d, 0x03, 0x57, 0xfd, 0x8f,
|
||||
0x3f, 0xfa, 0x42, 0xbe, 0x1e, 0x8f, 0x31, 0x91, 0xd5, 0xff, 0x78, 0x07, 0x7a, 0x7a, 0xd8, 0xbe,
|
||||
0x34, 0xf7, 0x39, 0xb0, 0xec, 0xd3, 0xce, 0x91, 0x87, 0x97, 0x77, 0x75, 0xdd, 0x53, 0xb1, 0x50,
|
||||
0x94, 0xea, 0x5d, 0x14, 0xe7, 0x5d, 0xee, 0x2b, 0x2e, 0x50, 0x46, 0xb1, 0x87, 0x3f, 0x70, 0x7c,
|
||||
0x6f, 0x71, 0x81, 0xca, 0x8b, 0xf7, 0xff, 0x2e, 0x41, 0xf3, 0xfc, 0x13, 0x3b, 0x04, 0xa8, 0xbc,
|
||||
0x80, 0x39, 0xa5, 0x6e, 0xe6, 0x9c, 0xc9, 0x79, 0x6c, 0xcd, 0xa9, 0xa5, 0x9c, 0x40, 0x47, 0x33,
|
||||
0x09, 0xb6, 0x5d, 0xa2, 0x6d, 0xa6, 0xe2, 0x3c, 0xa9, 0x4b, 0x2b, 0xbe, 0x0f, 0xd0, 0xa6, 0x26,
|
||||
0xc2, 0xb6, 0x2c, 0xf8, 0xf2, 0x54, 0xce, 0x76, 0x4d, 0x56, 0x91, 0x1d, 0x40, 0xab, 0xb0, 0x19,
|
||||
0x36, 0x28, 0xa1, 0x86, 0x19, 0x39, 0x8f, 0x2c, 0x19, 0x45, 0xf0, 0x05, 0x56, 0x74, 0xeb, 0x61,
|
||||
0xd5, 0xfc, 0x56, 0xb3, 0x72, 0x9e, 0xd6, 0xe6, 0x15, 0xe5, 0x21, 0x40, 0xe5, 0x09, 0x64, 0xef,
|
||||
0x73, 0xee, 0x41, 0xf6, 0x6e, 0x31, 0x91, 0x43, 0x80, 0x4a, 0xd7, 0x84, 0x66, 0xce, 0x17, 0x08,
|
||||
0x8d, 0xc5, 0x08, 0x0e, 0xa0, 0x55, 0x28, 0x94, 0x6c, 0xc8, 0xd0, 0x35, 0xd9, 0xd0, 0x9c, 0x9c,
|
||||
0x4f, 0xa0, 0xa3, 0x89, 0x8b, 0xdc, 0xdf, 0x26, 0x4e, 0x72, 0x7f, 0xab, 0x26, 0xd3, 0xfb, 0x53,
|
||||
0xf1, 0x91, 0xfb, 0x5b, 0xa4, 0x4a, 0xee, 0x6f, 0x55, 0xec, 0x11, 0x2c, 0x13, 0xed, 0x31, 0xb2,
|
||||
0xd0, 0x39, 0xdd, 0x3a, 0x5b, 0xf6, 0xa4, 0xc1, 0x94, 0xb7, 0x30, 0x99, 0x34, 0x11, 0x9b, 0x4c,
|
||||
0xba, 0x76, 0x4b, 0xa6, 0x5c, 0x95, 0x26, 0x93, 0xa6, 0x68, 0x93, 0x49, 0x17, 0xf2, 0xc5, 0x62,
|
||||
0x96, 0x7a, 0xf5, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x92, 0xa7, 0x99, 0xc8, 0x62, 0x08, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
|
@ -1005,6 +1136,8 @@ const _ = grpc.SupportPackageIsVersion6
|
|||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type VMClient interface {
|
||||
Initialize(ctx context.Context, in *InitializeRequest, opts ...grpc.CallOption) (*InitializeResponse, error)
|
||||
Bootstrapping(ctx context.Context, in *BootstrappingRequest, opts ...grpc.CallOption) (*BootstrappingResponse, error)
|
||||
Bootstrapped(ctx context.Context, in *BootstrappedRequest, opts ...grpc.CallOption) (*BootstrappedResponse, error)
|
||||
Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error)
|
||||
CreateHandlers(ctx context.Context, in *CreateHandlersRequest, opts ...grpc.CallOption) (*CreateHandlersResponse, error)
|
||||
BuildBlock(ctx context.Context, in *BuildBlockRequest, opts ...grpc.CallOption) (*BuildBlockResponse, error)
|
||||
|
@ -1034,6 +1167,24 @@ func (c *vMClient) Initialize(ctx context.Context, in *InitializeRequest, opts .
|
|||
return out, nil
|
||||
}
|
||||
|
||||
func (c *vMClient) Bootstrapping(ctx context.Context, in *BootstrappingRequest, opts ...grpc.CallOption) (*BootstrappingResponse, error) {
|
||||
out := new(BootstrappingResponse)
|
||||
err := c.cc.Invoke(ctx, "/vmproto.VM/Bootstrapping", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *vMClient) Bootstrapped(ctx context.Context, in *BootstrappedRequest, opts ...grpc.CallOption) (*BootstrappedResponse, error) {
|
||||
out := new(BootstrappedResponse)
|
||||
err := c.cc.Invoke(ctx, "/vmproto.VM/Bootstrapped", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *vMClient) Shutdown(ctx context.Context, in *ShutdownRequest, opts ...grpc.CallOption) (*ShutdownResponse, error) {
|
||||
out := new(ShutdownResponse)
|
||||
err := c.cc.Invoke(ctx, "/vmproto.VM/Shutdown", in, out, opts...)
|
||||
|
@ -1127,6 +1278,8 @@ func (c *vMClient) BlockReject(ctx context.Context, in *BlockRejectRequest, opts
|
|||
// VMServer is the server API for VM service.
|
||||
type VMServer interface {
|
||||
Initialize(context.Context, *InitializeRequest) (*InitializeResponse, error)
|
||||
Bootstrapping(context.Context, *BootstrappingRequest) (*BootstrappingResponse, error)
|
||||
Bootstrapped(context.Context, *BootstrappedRequest) (*BootstrappedResponse, error)
|
||||
Shutdown(context.Context, *ShutdownRequest) (*ShutdownResponse, error)
|
||||
CreateHandlers(context.Context, *CreateHandlersRequest) (*CreateHandlersResponse, error)
|
||||
BuildBlock(context.Context, *BuildBlockRequest) (*BuildBlockResponse, error)
|
||||
|
@ -1146,6 +1299,12 @@ type UnimplementedVMServer struct {
|
|||
func (*UnimplementedVMServer) Initialize(ctx context.Context, req *InitializeRequest) (*InitializeResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Initialize not implemented")
|
||||
}
|
||||
func (*UnimplementedVMServer) Bootstrapping(ctx context.Context, req *BootstrappingRequest) (*BootstrappingResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Bootstrapping not implemented")
|
||||
}
|
||||
func (*UnimplementedVMServer) Bootstrapped(ctx context.Context, req *BootstrappedRequest) (*BootstrappedResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Bootstrapped not implemented")
|
||||
}
|
||||
func (*UnimplementedVMServer) Shutdown(ctx context.Context, req *ShutdownRequest) (*ShutdownResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Shutdown not implemented")
|
||||
}
|
||||
|
@ -1199,6 +1358,42 @@ func _VM_Initialize_Handler(srv interface{}, ctx context.Context, dec func(inter
|
|||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _VM_Bootstrapping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BootstrappingRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(VMServer).Bootstrapping(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vmproto.VM/Bootstrapping",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(VMServer).Bootstrapping(ctx, req.(*BootstrappingRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _VM_Bootstrapped_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(BootstrappedRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(VMServer).Bootstrapped(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/vmproto.VM/Bootstrapped",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(VMServer).Bootstrapped(ctx, req.(*BootstrappedRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _VM_Shutdown_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ShutdownRequest)
|
||||
if err := dec(in); err != nil {
|
||||
|
@ -1387,6 +1582,14 @@ var _VM_serviceDesc = grpc.ServiceDesc{
|
|||
MethodName: "Initialize",
|
||||
Handler: _VM_Initialize_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Bootstrapping",
|
||||
Handler: _VM_Bootstrapping_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Bootstrapped",
|
||||
Handler: _VM_Bootstrapped_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Shutdown",
|
||||
Handler: _VM_Shutdown_Handler,
|
||||
|
|
|
@ -9,6 +9,14 @@ message InitializeRequest {
|
|||
|
||||
message InitializeResponse {}
|
||||
|
||||
message BootstrappingRequest {}
|
||||
|
||||
message BootstrappingResponse {}
|
||||
|
||||
message BootstrappedRequest {}
|
||||
|
||||
message BootstrappedResponse {}
|
||||
|
||||
message ShutdownRequest {}
|
||||
|
||||
message ShutdownResponse {}
|
||||
|
@ -86,6 +94,8 @@ message BlockRejectResponse {}
|
|||
|
||||
service VM {
|
||||
rpc Initialize(InitializeRequest) returns (InitializeResponse);
|
||||
rpc Bootstrapping(BootstrappingRequest) returns (BootstrappingResponse);
|
||||
rpc Bootstrapped(BootstrappedRequest) returns (BootstrappedResponse);
|
||||
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse);
|
||||
rpc CreateHandlers(CreateHandlersRequest) returns (CreateHandlersResponse);
|
||||
rpc BuildBlock(BuildBlockRequest) returns (BuildBlockResponse);
|
||||
|
|
|
@ -36,6 +36,7 @@ var (
|
|||
type Fx struct {
|
||||
VM VM
|
||||
SECPFactory crypto.FactorySECP256K1R
|
||||
bootstrapped bool
|
||||
}
|
||||
|
||||
// Initialize ...
|
||||
|
@ -69,6 +70,12 @@ func (fx *Fx) InitializeVM(vmIntf interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Bootstrapping ...
|
||||
func (fx *Fx) Bootstrapping() error { return nil }
|
||||
|
||||
// Bootstrapped ...
|
||||
func (fx *Fx) Bootstrapped() error { fx.bootstrapped = true; return nil }
|
||||
|
||||
// VerifyOperation ...
|
||||
func (fx *Fx) VerifyOperation(txIntf, opIntf, credIntf interface{}, utxosIntf []interface{}) error {
|
||||
tx, ok := txIntf.(Tx)
|
||||
|
@ -156,6 +163,11 @@ func (fx *Fx) VerifyCredentials(tx Tx, in *Input, cred *Credential, out *OutputO
|
|||
return errInputCredentialSignersMismatch
|
||||
}
|
||||
|
||||
// disable signature verification during bootstrapping
|
||||
if !fx.bootstrapped {
|
||||
return nil
|
||||
}
|
||||
|
||||
txBytes := tx.UnsignedBytes()
|
||||
txHash := hashing.ComputeHash256(txBytes)
|
||||
|
||||
|
|
|
@ -76,6 +76,12 @@ func TestFxVerifyTransfer(t *testing.T) {
|
|||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := fx.Bootstrapping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := fx.Bootstrapped(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
|
@ -470,6 +476,9 @@ func TestFxVerifyTransferInvalidSignature(t *testing.T) {
|
|||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := fx.Bootstrapping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
|
@ -495,6 +504,14 @@ func TestFxVerifyTransferInvalidSignature(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := fx.Bootstrapped(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to an invalid signature")
|
||||
}
|
||||
|
@ -508,6 +525,9 @@ func TestFxVerifyTransferWrongSigner(t *testing.T) {
|
|||
if err := fx.Initialize(&vm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := fx.Bootstrapping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tx := &testTx{
|
||||
bytes: txBytes,
|
||||
}
|
||||
|
@ -533,6 +553,14 @@ func TestFxVerifyTransferWrongSigner(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := fx.Bootstrapped(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := fx.VerifyTransfer(tx, in, cred, out); err == nil {
|
||||
t.Fatalf("Should have errored due to a wrong signer")
|
||||
}
|
||||
|
|
|
@ -105,7 +105,13 @@ func ConsensusLeader(numBlocks, numTxsPerBlock int, b *testing.B) {
|
|||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(&engine, msgChan, 1000)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
1000,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
|
||||
// Allow incoming messages to be routed to the new chain
|
||||
chainRouter.AddChain(handler)
|
||||
|
@ -238,7 +244,13 @@ func ConsensusFollower(numBlocks, numTxsPerBlock int, b *testing.B) {
|
|||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(&engine, msgChan, 1000)
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
1000,
|
||||
"",
|
||||
prometheus.NewRegistry(),
|
||||
)
|
||||
|
||||
// Allow incoming messages to be routed to the new chain
|
||||
chainRouter.AddChain(handler)
|
||||
|
|
|
@ -116,6 +116,12 @@ func (vm *VM) Initialize(
|
|||
return nil
|
||||
}
|
||||
|
||||
// Bootstrapping marks this VM as bootstrapping
|
||||
func (vm *VM) Bootstrapping() error { return nil }
|
||||
|
||||
// Bootstrapped marks this VM as bootstrapped
|
||||
func (vm *VM) Bootstrapped() error { return nil }
|
||||
|
||||
// Shutdown implements the snowman.ChainVM interface
|
||||
func (vm *VM) Shutdown() error {
|
||||
if vm.timer == nil {
|
||||
|
|
|
@ -128,6 +128,12 @@ func (vm *VM) Initialize(
|
|||
return vm.db.Commit()
|
||||
}
|
||||
|
||||
// Bootstrapping marks this VM as bootstrapping
|
||||
func (vm *VM) Bootstrapping() error { return nil }
|
||||
|
||||
// Bootstrapped marks this VM as bootstrapped
|
||||
func (vm *VM) Bootstrapped() error { return nil }
|
||||
|
||||
// Shutdown implements the avalanche.DAGVM interface
|
||||
func (vm *VM) Shutdown() error {
|
||||
if vm.timer == nil {
|
||||
|
|
Loading…
Reference in New Issue