Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 9 additions & 11 deletions bft/bft.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,35 +95,33 @@ func (b *BFT) Start() {
}
for {
select {
// PHASE TIMEOUT
// EXECUTE PHASE
// - This triggers when the phase's sleep time has expired, indicating that all expected messages for this phase should have already been received
case <-b.PhaseTimer.C:
func() {
b.Controller.Lock()
defer b.Controller.Unlock()
// handle the phase
b.HandlePhase()
}()

// RESET BFT
// - This triggers when receiving a new Commit Block (QC) from either root-chainId (a) or the Target-ChainId (b)
case resetBFT := <-b.ResetBFT:
func() {
defer lib.TimeTrack(fmt.Sprintf("BFT.Start.Reset(), %d", len(b.ResetBFT)), time.Now())
b.Controller.Lock()
defer b.Controller.Unlock()
// if is a root-chain update reset back to round 0 but maintain locks to prevent 'fork attacks'
// else increment the height and don't maintain locks
b.NewHeight(resetBFT.IsRootChainUpdate)
// if not a base chain update, reset the timers
if !resetBFT.IsRootChainUpdate {
b.log.Info("Reset BFT (NEW_HEIGHT)")
// start BFT over
b.NewHeight(false)
} else {
b.log.Info("Reset BFT (NEW_COMMITTEE)")
// start BFT over after sleeping RootChainPollMS
// add poll ms wait here to ensure ample time for all nested chains to be updated
b.NewHeight(true)
}
b.SetWaitTimers(time.Duration(b.Config.RootChainPollMS)*time.Millisecond, resetBFT.ProcessTime)
// set the wait timers to start consensus
b.SetWaitTimers(time.Duration(b.Config.NewHeightTimeoutMs)*time.Millisecond, resetBFT.ProcessTime)
}()
}
}
Expand Down Expand Up @@ -647,7 +645,7 @@ func (b *BFT) SetTimerForNextPhase(processTime time.Duration) {
default:
b.Phase++
case CommitProcess:
// no op
return // don't set a timer
case Pacemaker:
b.Phase = Election
}
Expand Down Expand Up @@ -755,7 +753,7 @@ func (b *BFT) SelfIsValidator() bool {
// RunVDF() runs the verifiable delay service
func (b *BFT) RunVDF(seed []byte) (err lib.ErrorI) {
if !b.Config.RunVDF {
b.log.Infof("RunVDF enabled in RunVDF")
b.log.Infof("VDF enabled")
return
}
// if the vdf seed is nil
Expand Down Expand Up @@ -885,5 +883,5 @@ const (
RoundInterrupt = lib.Phase_ROUND_INTERRUPT
Pacemaker = lib.Phase_PACEMAKER

BlockTimeToVDFTargetCoefficient = .65 // how much the commit process time is reduced for VDF processing
BlockTimeToVDFTargetCoefficient = .50 // how much the commit process time is reduced for VDF processing
)
2 changes: 0 additions & 2 deletions cmd/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ func Start() {
}
// initialize the rpc server
rpcServer := rpc.NewServer(app, config, l)
// set the remote callbacks
app.RootChainInfo.GetRemoteCallbacks = rpcServer.RemoteCallbacks
// start the metrics server
metrics.Start()
// start the application
Expand Down
14 changes: 10 additions & 4 deletions cmd/rpc/admin_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,18 +352,24 @@ func (s *Server) TransactionLockOrder(w http.ResponseWriter, r *http.Request, _
})
}

// TransactionCloseOrder completes a swap
func (s *Server) TransactionCloseOrder(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
s.txHandler(w, r, func(p crypto.PrivateKeyI, ptr *txRequest) (lib.TransactionI, error) {
// Retrieve the fee required for this type of transaction
if err := s.getFeeFromState(w, ptr, fsm.MessageSendName, true); err != nil {
return nil, err
}
// If the remote callbacks not yet set
if s.remoteCallbacks == nil {
return nil, lib.ErrServerTimeout()
// create a variable for the root chain id
var rootChainId uint64
// get a read only state
if err := s.readOnlyState(0, func(s *fsm.StateMachine) (err lib.ErrorI) {
rootChainId, err = s.GetRootChainId()
return
}); err != nil {
return nil, err
}
// Execute rpc call to the root chain
order, err := s.remoteCallbacks.Order(0, ptr.OrderId, s.config.ChainId)
order, err := s.rcManager.GetOrder(rootChainId, 0, ptr.OrderId, s.config.ChainId)
if err != nil {
return nil, err
}
Expand Down
32 changes: 1 addition & 31 deletions cmd/rpc/query_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,37 +215,7 @@ func (s *Server) Checkpoint(w http.ResponseWriter, r *http.Request, _ httprouter
func (s *Server) RootChainInfo(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
// Invoke helper with the HTTP request, response writer and an inline callback
s.heightAndIdParams(w, r, func(s *fsm.StateMachine, id uint64) (interface{}, lib.ErrorI) {
// get the previous state machine height
lastSM, err := s.TimeMachine(s.Height() - 1)
if err != nil {
return nil, err
}
// get the committee
validatorSet, err := s.GetCommitteeMembers(id)
if err != nil {
return nil, err
}
// get the previous committee
// allow an error here to have size 0 validator sets
lastValidatorSet, _ := lastSM.GetCommitteeMembers(id)
// get the delegate lottery winner
lotteryWinner, err := s.LotteryWinner(id)
if err != nil {
return nil, err
}
// get the order book
orders, err := s.GetOrderBook(id)
if err != nil {
return nil, err
}
return &lib.RootChainInfo{
RootChainId: s.Config.ChainId,
Height: s.Height(),
ValidatorSet: validatorSet,
LastValidatorSet: lastValidatorSet,
LotteryWinner: lotteryWinner,
Orders: orders,
}, nil
return s.GetRootChainInfo(id)
})
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/rpc/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const (
RootChainInfoRoutePath = "/v1/query/root-Chain-info"
ValidatorSetRoutePath = "/v1/query/validator-set"
CheckpointRoutePath = "/v1/query/checkpoint"
SubscribeRCInfoPath = "/v1/subscribe-rc-info"
// debug
DebugBlockedRoutePath = "/debug/blocked"
DebugHeapRoutePath = "/debug/heap"
Expand Down Expand Up @@ -177,6 +178,7 @@ const (
LogsRouteName = "logs"
AddVoteRouteName = "add-vote"
DelVoteRouteName = "del-vote"
SubscribeRCInfoName = "subscribe-rc-info"
)

// routes contains the method and path for a canopy command
Expand Down Expand Up @@ -270,6 +272,7 @@ var routePaths = routes{
LogsRouteName: {Method: http.MethodGet, Path: LogsRoutePath},
AddVoteRouteName: {Method: http.MethodPost, Path: AddVoteRoutePath},
DelVoteRouteName: {Method: http.MethodPost, Path: DelVoteRoutePath},
SubscribeRCInfoName: {Method: http.MethodGet, Path: SubscribeRCInfoPath},
}

// httpRouteHandlers is a custom type that maps strings to httprouter handle functions
Expand Down Expand Up @@ -325,6 +328,7 @@ func createRouter(s *Server) *httprouter.Router {
RootChainInfoRouteName: s.RootChainInfo,
ValidatorSetRouteName: s.ValidatorSet,
CheckpointRouteName: s.Checkpoint,
SubscribeRCInfoName: s.WebSocket,
}

// Initialize a new router using the httprouter package.
Expand Down
112 changes: 9 additions & 103 deletions cmd/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const (
SoftwareVersion = "0.0.0-alpha"
ContentType = "Content-MessageType"
ApplicationJSON = "application/json; charset=utf-8"
localhost = "localhost"

walletStaticDir = "web/wallet/out"
explorerStaticDir = "web/explorer/out"
Expand All @@ -54,8 +53,8 @@ type Server struct {
// Mutex for Poll handler
pollMux *sync.RWMutex

// RemoteCallbacks to the root chain rpc
remoteCallbacks *lib.RemoteCallbacks
// handles interactions with the root chain rpc
rcManager *RCManager

logger lib.LoggerI
}
Expand All @@ -66,6 +65,7 @@ func NewServer(controller *controller.Controller, config lib.Config, logger lib.
controller: controller,
config: config,
logger: logger,
rcManager: NewRCManager(controller, config, logger),
poll: make(fsm.Poll),
pollMux: &sync.RWMutex{},
}
Expand All @@ -79,8 +79,7 @@ func (s *Server) Start() {

// Start tasks to update poll results and poll root chain information
go s.updatePollResults()
go s.pollRootChainInfo()

go s.rcManager.Start()
go func() { // TODO remove DEBUG ONLY
fileName := "heap1.out"
for range time.Tick(time.Second * 10) {
Expand Down Expand Up @@ -120,8 +119,11 @@ func (s *Server) startRPC(router *httprouter.Router, port string) {
// Start RPC server
s.logger.Infof("Starting RPC server at 0.0.0.0:%s", port)
s.logger.Fatal((&http.Server{
Addr: colon + port,
Handler: cor.Handler(http.TimeoutHandler(router, timeout, lib.ErrServerTimeout().Error())),
Addr: colon + port,
ReadHeaderTimeout: timeout,
Comment thread
andrewnguyen22 marked this conversation as resolved.
ReadTimeout: timeout,
WriteTimeout: timeout,
Handler: cor.Handler(router),
}).ListenAndServe().Error())
}

Expand Down Expand Up @@ -162,102 +164,6 @@ func (s *Server) updatePollResults() {
}
}

// updateRootChainHeight queries and updates the root chain height
func (s *Server) updateRootChainHeight(state *fsm.StateMachine, rootChainHeight *uint64) (err lib.ErrorI) {
// get the consensus params from the app
consParams, err := state.GetParamsCons()
if err != nil {
return
}
// get the remote callbacks for the root chain id
s.remoteCallbacks, err = s.RemoteCallbacks(consParams.RootChainId)
if err != nil {
s.logger.Errorf("callbacks failed with err: %s")
return err
}
// query the base chain height
height, err := s.remoteCallbacks.Height()
if err != nil {
s.logger.Errorf("GetRootChainHeight failed with err")
return err
}
// check if a new height was received
if *height <= *rootChainHeight {
return
}
// update the root chain height
*rootChainHeight = *height
// if a new height received
s.logger.Infof("New RootChain height %d detected!", *rootChainHeight)
// execute the requests to get the base chain information
for retry := lib.NewRetry(s.config.RootChainPollMS, 10); retry.WaitAndDoRetry(); {
s.logger.Infof("Retrieved root height info for %d!", *rootChainHeight)
// retrieve the root-Chain info
rootChainInfo, e := s.remoteCallbacks.RootChainInfo(*rootChainHeight, s.config.ChainId)
if e == nil && rootChainInfo != nil && rootChainInfo.ValidatorSet.NumValidators != 0 {
// update the controller with new root-Chain info
s.controller.UpdateRootChainInfo(rootChainInfo)
s.logger.Info("Updated RootChain information")
break
}
s.logger.Errorf("GetRootChainInfo failed with err %s", e.Error())
}
return
}

// pollRootChainInfo() retrieves information from the root-Chain required for consensus
func (s *Server) pollRootChainInfo() {
// Track the root chain height
rootChainHeight := uint64(0)
// execute the loop every conf.RootChainPollMS duration
ticker := time.NewTicker(time.Duration(s.config.RootChainPollMS) * time.Millisecond)
for range ticker.C {
if err := func() (err error) {
// Create a read-only state machine context
err = s.readOnlyState(0, func(state *fsm.StateMachine) (err lib.ErrorI) {
// Update the root chain height
return s.updateRootChainHeight(state, &rootChainHeight)
})
return
}(); err != nil {
s.logger.Warnf(err.Error())
}
}
}

// RemoteCallbacks() enables the retrieval of remote RPC API calls for a certain root chain id
func (s *Server) RemoteCallbacks(rootChainId uint64) (*lib.RemoteCallbacks, lib.ErrorI) {
// get the url for the root chain as set by the state
var rootChainUrl string
// for each item in the root chain config
for _, chain := range s.config.RootChain {
// if the chain id matches
if chain.ChainId == rootChainId {
// use that root chain url
rootChainUrl = chain.Url
}
}
// check if root chain url isn't empty
if rootChainUrl == "" {
s.logger.Errorf("Config.JSON missing RootChainID=%d failed with", rootChainId)
return nil, lib.ErrEmptyChainId()
}
// create a rpc client
rpcClient := NewClient(rootChainUrl, "")
// set the remote callbacks
return &lib.RemoteCallbacks{
Height: rpcClient.Height,
RootChainInfo: rpcClient.RootChainInfo,
ValidatorSet: rpcClient.ValidatorSet,
IsValidDoubleSigner: rpcClient.IsValidDoubleSigner,
Lottery: rpcClient.Lottery,
Orders: rpcClient.Orders,
Order: rpcClient.Order,
Checkpoint: rpcClient.Checkpoint,
Transaction: rpcClient.Transaction,
}, nil
}

// startStaticFileServers starts a file server for the wallet and explorer
func (s *Server) startStaticFileServers() {
s.logger.Infof("Starting Web Wallet 🔑 http://localhost:%s ⬅️", s.config.WalletPort)
Expand Down
Loading
Loading