2020-03-10 12:20:34 -07:00
|
|
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
|
|
|
|
package xputtest
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/ava-labs/gecko/ids"
|
|
|
|
"github.com/ava-labs/gecko/snow"
|
|
|
|
"github.com/ava-labs/gecko/snow/choices"
|
2020-03-13 14:31:23 -07:00
|
|
|
"github.com/ava-labs/gecko/utils/logging"
|
2020-03-10 12:20:34 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
type issuableVM interface {
|
|
|
|
IssueTx([]byte, func(choices.Status)) (ids.ID, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Issuer manages all the chain transaction flushing.
|
|
|
|
type Issuer struct {
|
2020-03-13 14:31:23 -07:00
|
|
|
lock sync.Mutex
|
|
|
|
log logging.Logger
|
|
|
|
vms map[[32]byte]issuableVM
|
|
|
|
locks map[[32]byte]sync.Locker
|
2020-03-10 12:20:34 -07:00
|
|
|
callbacks chan func()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialize this flusher
|
2020-03-13 14:31:23 -07:00
|
|
|
func (i *Issuer) Initialize(log logging.Logger) {
|
2020-03-10 12:20:34 -07:00
|
|
|
i.lock.Lock()
|
|
|
|
defer i.lock.Unlock()
|
2020-03-13 14:31:23 -07:00
|
|
|
i.log = log
|
2020-03-10 12:20:34 -07:00
|
|
|
i.vms = make(map[[32]byte]issuableVM)
|
|
|
|
i.locks = make(map[[32]byte]sync.Locker)
|
|
|
|
i.callbacks = make(chan func(), 1000)
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
for callback := range i.callbacks {
|
|
|
|
callback()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterChain implements the registrant
|
|
|
|
func (i *Issuer) RegisterChain(ctx *snow.Context, vm interface{}) {
|
|
|
|
i.lock.Lock()
|
|
|
|
defer i.lock.Unlock()
|
|
|
|
|
|
|
|
key := ctx.ChainID.Key()
|
|
|
|
|
|
|
|
switch vm := vm.(type) {
|
|
|
|
case issuableVM:
|
|
|
|
i.vms[key] = vm
|
|
|
|
i.locks[key] = &ctx.Lock
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// IssueTx issue the transaction to the chain and register the timeout.
|
|
|
|
func (i *Issuer) IssueTx(chainID ids.ID, tx []byte, finalized func(choices.Status)) {
|
|
|
|
i.lock.Lock()
|
|
|
|
defer i.lock.Unlock()
|
|
|
|
|
|
|
|
key := chainID.Key()
|
|
|
|
if lock, exists := i.locks[key]; exists {
|
|
|
|
i.callbacks <- func() {
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
|
|
|
if vm, exists := i.vms[key]; exists {
|
2020-03-13 14:31:23 -07:00
|
|
|
if _, err := vm.IssueTx(tx, finalized); err != nil {
|
|
|
|
i.log.Error("Issuing the tx returned with %s unexpectedly", err)
|
|
|
|
}
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
}
|
2020-03-13 14:31:23 -07:00
|
|
|
} else {
|
|
|
|
i.log.Warn("Attempted to issue a Tx to an unsupported chain %s", chainID)
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
}
|