Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable API Before Sync and Return 503 When Not Synced #1155

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
27 changes: 20 additions & 7 deletions blockbook.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ var (
resyncMempoolPeriodMs = flag.Int("resyncmempoolperiod", 60017, "resync mempool period in milliseconds")

extendedIndex = flag.Bool("extendedindex", false, "if true, create index of input txids and spending transactions")

enableAPIBeforeSyncFlag = flag.Bool("enableapibeforesync", false, "enable API access before full synchronization is completed")
)

var (
Expand Down Expand Up @@ -328,13 +330,9 @@ func mainWithExitCode() int {
}
go storeInternalStateLoop()

if publicServer != nil {
if publicServer != nil && !*enableAPIBeforeSyncFlag {
// start full public interface
callbacksOnNewBlock = append(callbacksOnNewBlock, publicServer.OnNewBlock)
callbacksOnNewTxAddr = append(callbacksOnNewTxAddr, publicServer.OnNewTxAddr)
callbacksOnNewTx = append(callbacksOnNewTx, publicServer.OnNewTx)
callbacksOnNewFiatRatesTicker = append(callbacksOnNewFiatRatesTicker, publicServer.OnNewFiatRatesTicker)
publicServer.ConnectFullPublicInterface()
startFullPublicInterface(publicServer)
}

if *blockFrom >= 0 {
Expand Down Expand Up @@ -417,10 +415,16 @@ func startInternalServer() (*server.InternalServer, error) {

func startPublicServer() (*server.PublicServer, error) {
// start public server in limited functionality, extend it after sync is finished by calling ConnectFullPublicInterface
publicServer, err := server.NewPublicServer(*publicBinding, *certFiles, index, chain, mempool, txCache, *explorerURL, metrics, internalState, fiatRates, *debugMode)
publicServer, err := server.NewPublicServer(*publicBinding, *certFiles, index, chain, mempool, txCache, *explorerURL, metrics, internalState, fiatRates, *debugMode, *enableAPIBeforeSyncFlag)
if err != nil {
return nil, err
}

// Check if the API-before-sync flag is set
if *enableAPIBeforeSyncFlag {
startFullPublicInterface(publicServer)
}

go func() {
err = publicServer.Run()
if err != nil {
Expand All @@ -432,9 +436,18 @@ func startPublicServer() (*server.PublicServer, error) {
}
}
}()

return publicServer, err
}

func startFullPublicInterface(publicServer *server.PublicServer) {
callbacksOnNewBlock = append(callbacksOnNewBlock, publicServer.OnNewBlock)
callbacksOnNewTxAddr = append(callbacksOnNewTxAddr, publicServer.OnNewTxAddr)
callbacksOnNewTx = append(callbacksOnNewTx, publicServer.OnNewTx)
callbacksOnNewFiatRatesTicker = append(callbacksOnNewFiatRatesTicker, publicServer.OnNewFiatRatesTicker)
publicServer.ConnectFullPublicInterface()
}

func performRollback() error {
bestHeight, bestHash, err := index.GetBestBlock()
if err != nil {
Expand Down
17 changes: 16 additions & 1 deletion server/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,12 @@ type PublicServer struct {
is *common.InternalState
fiatRates *fiat.FiatRates
useSatsAmountFormat bool
enableAPIBeforeSync bool
}

// NewPublicServer creates new public server http interface to blockbook and returns its handle
// only basic functionality is mapped, to map all functions, call
func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, mempool bchain.Mempool, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState, fiatRates *fiat.FiatRates, debugMode bool) (*PublicServer, error) {
func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bchain.BlockChain, mempool bchain.Mempool, txCache *db.TxCache, explorerURL string, metrics *common.Metrics, is *common.InternalState, fiatRates *fiat.FiatRates, debugMode bool, enableAPIBeforeSync bool) (*PublicServer, error) {

api, err := api.NewWorker(db, chain, mempool, txCache, metrics, is, fiatRates)
if err != nil {
Expand Down Expand Up @@ -109,6 +110,7 @@ func NewPublicServer(binding string, certFiles string, db *db.RocksDB, chain bch
is: is,
fiatRates: fiatRates,
useSatsAmountFormat: chain.GetChainParser().GetChainType() == bchain.ChainBitcoinType && chain.GetChainParser().AmountDecimals() == 8,
enableAPIBeforeSync: enableAPIBeforeSync,
}
s.htmlTemplates.newTemplateData = s.newTemplateData
s.htmlTemplates.newTemplateDataWithError = s.newTemplateDataWithError
Expand Down Expand Up @@ -294,10 +296,23 @@ func (s *PublicServer) jsonHandler(handler func(r *http.Request, apiVersion int)
Text string `json:"error"`
HTTPStatus int `json:"-"`
}

handlerName := getFunctionName(handler)
return func(w http.ResponseWriter, r *http.Request) {
var data interface{}
var err error

systemInfo, err := s.api.GetSystemInfo(false)
if err != nil {
glog.Error("Failed to get system info: ", err)
json.NewEncoder(w).Encode(jsonError{Text: err.Error(), HTTPStatus: http.StatusInternalServerError})
return
} else if !systemInfo.Blockbook.InSync && !s.enableAPIBeforeSync {
w.WriteHeader(http.StatusServiceUnavailable)
json.NewEncoder(w).Encode(systemInfo.Blockbook)
return
}

defer func() {
if e := recover(); e != nil {
glog.Error(handlerName, " recovered from panic: ", e)
Expand Down