Compare commits
3 Commits
2bab58c6d2
...
17ca2b0e69
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17ca2b0e69 | ||
|
|
7f5474ef82 | ||
|
|
62358df198 |
@@ -93,7 +93,7 @@ type Options struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var version = "0.1.1" // set version number
|
var version = common.Version
|
||||||
|
|
||||||
opts := &Options{}
|
opts := &Options{}
|
||||||
flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9069", "the address to listen on")
|
flag.StringVar(&opts.bindAddr, "bind-addr", "127.0.0.1:9069", "the address to listen on")
|
||||||
|
|||||||
@@ -38,25 +38,32 @@ func GetSaplingInfo(rpcClient *rpcclient.Client) (int, int, string, string, int,
|
|||||||
return -1, -1, "", "", -1, -1, -1, errors.Wrap(err, "error reading JSON response")
|
return -1, -1, "", "", -1, -1, -1, errors.Wrap(err, "error reading JSON response")
|
||||||
}
|
}
|
||||||
|
|
||||||
chainName := f.(map[string]interface{})["chain"].(string)
|
// Assert the top-level object once, then read every field with the comma-ok
|
||||||
|
// form. These run on the block-ingestor goroutine, and nothing in this
|
||||||
|
// daemon or in grpc-go v1.24.0 recovers a panic, so one unexpected response
|
||||||
|
// shape would take the whole process down rather than fail one call.
|
||||||
|
fmap, ok := f.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
return -1, -1, "", "", -1, -1, -1, errors.New("getblockchaininfo: unexpected response shape")
|
||||||
|
}
|
||||||
|
chainName, _ := fmap["chain"].(string)
|
||||||
|
|
||||||
// DragonX has Sapling active from block 1 but sets NO_ACTIVATION_HEIGHT in
|
// DragonX has Sapling active from block 1 but sets NO_ACTIVATION_HEIGHT in
|
||||||
// chainparams, so dragonxd omits it from the upgrades map. Fall back to
|
// chainparams, so dragonxd omits it from the upgrades map. Fall back to
|
||||||
// height 1 when the key is absent.
|
// height 1 when the key is absent.
|
||||||
saplingHeight := float64(1)
|
saplingHeight := float64(1)
|
||||||
upgradeJSON, ok := f.(map[string]interface{})["upgrades"]
|
if upgradesMap, ok := fmap["upgrades"].(map[string]interface{}); ok {
|
||||||
if ok {
|
if saplingJSON, ok := upgradesMap["76b809bb"].(map[string]interface{}); ok {
|
||||||
if upgradesMap, ok := upgradeJSON.(map[string]interface{}); ok {
|
if h, ok := saplingJSON["activationheight"].(float64); ok {
|
||||||
if saplingJSON, ok := upgradesMap["76b809bb"]; ok {
|
saplingHeight = h
|
||||||
saplingHeight = saplingJSON.(map[string]interface{})["activationheight"].(float64)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blockHeight := f.(map[string]interface{})["headers"].(float64)
|
blockHeight, _ := fmap["headers"].(float64)
|
||||||
difficulty := f.(map[string]interface{})["difficulty"].(float64)
|
difficulty, _ := fmap["difficulty"].(float64)
|
||||||
longestchain := f.(map[string]interface{})["longestchain"].(float64)
|
longestchain, _ := fmap["longestchain"].(float64)
|
||||||
notarized := f.(map[string]interface{})["notarized"].(float64)
|
notarized, _ := fmap["notarized"].(float64)
|
||||||
|
|
||||||
// DragonX always uses Sapling consensus rules but CurrentEpochBranchId()
|
// DragonX always uses Sapling consensus rules but CurrentEpochBranchId()
|
||||||
// returns Sprout (0) for full nodes because the activation heights are
|
// returns Sprout (0) for full nodes because the activation heights are
|
||||||
|
|||||||
14
common/version.go
Normal file
14
common/version.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package common
|
||||||
|
|
||||||
|
// Version is the single source of truth for this daemon's version.
|
||||||
|
//
|
||||||
|
// It was previously duplicated as a literal in two places that could drift:
|
||||||
|
// cmd/server/main.go's --version output and the Version field of the LightdInfo
|
||||||
|
// gRPC reply in frontend/service.go. The gRPC one is the load-bearing copy --
|
||||||
|
// it is walletrpc/service.proto:48, so every client and every operator probe
|
||||||
|
// reads it, and it is the only way to tell from off-box which build a node is
|
||||||
|
// running.
|
||||||
|
const Version = "0.1.2"
|
||||||
|
|
||||||
|
// VersionString is what GetLightdInfo advertises to clients.
|
||||||
|
const VersionString = Version + "-dragonxlightd"
|
||||||
@@ -293,7 +293,26 @@ func (s *SqlStreamer) GetTransaction(ctx context.Context, txf *walletrpc.TxFilte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
txHeight = txinfo.(map[string]interface{})["height"].(float64)
|
// dragonxd emits "height" only for a transaction that is in a block:
|
||||||
|
// rawtransaction.cpp puts it inside `if (!hashBlock.IsNull())`. Every
|
||||||
|
// mempool transaction therefore comes back WITHOUT the key, and an
|
||||||
|
// unchecked assertion on the missing value panics -- which, with no
|
||||||
|
// recover() anywhere in grpc-go v1.24.0 or in this daemon, kills the
|
||||||
|
// whole process and every wallet connected to it. Any client can reach
|
||||||
|
// this by broadcasting a transaction and immediately asking for it, and
|
||||||
|
// GetMempoolStream hands out unconfirmed txids by design.
|
||||||
|
//
|
||||||
|
// Report an unconfirmed transaction as tip+1, matching what
|
||||||
|
// GetMempoolStream already advertises (mempool.go:109).
|
||||||
|
txmap, ok := txinfo.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("getrawtransaction: unexpected response shape")
|
||||||
|
}
|
||||||
|
if h, ok := txmap["height"].(float64); ok {
|
||||||
|
txHeight = h
|
||||||
|
} else {
|
||||||
|
txHeight = float64(s.cache.GetLatestBlock() + 1)
|
||||||
|
}
|
||||||
|
|
||||||
return &walletrpc.RawTransaction{Data: txBytes, Height: uint64(txHeight)}, nil
|
return &walletrpc.RawTransaction{Data: txBytes, Height: uint64(txHeight)}, nil
|
||||||
}
|
}
|
||||||
@@ -334,7 +353,7 @@ func (s *SqlStreamer) GetLightdInfo(ctx context.Context, in *walletrpc.Empty) (*
|
|||||||
// TODO these are called Error but they aren't at the moment.
|
// TODO these are called Error but they aren't at the moment.
|
||||||
// A success will return code 0 and message txhash.
|
// A success will return code 0 and message txhash.
|
||||||
return &walletrpc.LightdInfo{
|
return &walletrpc.LightdInfo{
|
||||||
Version: "0.1.1-dragonxlightd",
|
Version: common.VersionString,
|
||||||
Vendor: "DragonX LightWalletD",
|
Vendor: "DragonX LightWalletD",
|
||||||
TaddrSupport: true,
|
TaddrSupport: true,
|
||||||
ChainName: chainName,
|
ChainName: chainName,
|
||||||
|
|||||||
@@ -10,9 +10,10 @@ set -euo pipefail
|
|||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
LWD_BIN="$SCRIPT_DIR/lightwalletd"
|
LWD_BIN="$SCRIPT_DIR/lightwalletd"
|
||||||
LWD_ARGS="-bind-addr lite.dragonx.is:9069 -conf-file $HOME/.hush/DRAGONX/DRAGONX.conf -no-tls -lag-min 4 -lag-max 12 -lag-window 30"
|
LWD_ARGS="-bind-addr lite.dragonx.is:9069 -conf-file $HOME/.hush/DRAGONX/DRAGONX.conf -no-tls -lag-min 4 -lag-max 12 -lag-window 30 -cache-size 5000"
|
||||||
LOGFILE="$SCRIPT_DIR/lwd-monitor.log"
|
LOGFILE="$SCRIPT_DIR/lwd-monitor.log"
|
||||||
PIDFILE="/tmp/lwd-monitor.pid"
|
PIDFILE="/tmp/lwd-monitor.pid"
|
||||||
|
STOPPING=0
|
||||||
RESTART_DELAY=5 # seconds to wait before restarting after a crash
|
RESTART_DELAY=5 # seconds to wait before restarting after a crash
|
||||||
MAX_RAPID_RESTARTS=5 # max restarts within the rapid window before backing off
|
MAX_RAPID_RESTARTS=5 # max restarts within the rapid window before backing off
|
||||||
RAPID_WINDOW=120 # seconds — if this many restarts happen within this window, back off
|
RAPID_WINDOW=120 # seconds — if this many restarts happen within this window, back off
|
||||||
@@ -29,6 +30,7 @@ log() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
|
STOPPING=1
|
||||||
log "${YELLOW}Monitor shutting down...${NC}"
|
log "${YELLOW}Monitor shutting down...${NC}"
|
||||||
if [[ -n "${LWD_PID:-}" ]] && kill -0 "$LWD_PID" 2>/dev/null; then
|
if [[ -n "${LWD_PID:-}" ]] && kill -0 "$LWD_PID" 2>/dev/null; then
|
||||||
log "Stopping lightwalletd (PID $LWD_PID)..."
|
log "Stopping lightwalletd (PID $LWD_PID)..."
|
||||||
@@ -75,6 +77,7 @@ log "Args: $LWD_ARGS"
|
|||||||
|
|
||||||
restart_times=()
|
restart_times=()
|
||||||
LWD_PID=""
|
LWD_PID=""
|
||||||
|
STOPPING=0
|
||||||
|
|
||||||
while true; do
|
while true; do
|
||||||
# Start lightwalletd
|
# Start lightwalletd
|
||||||
@@ -84,12 +87,12 @@ while true; do
|
|||||||
log "lightwalletd started with PID $LWD_PID"
|
log "lightwalletd started with PID $LWD_PID"
|
||||||
|
|
||||||
# Wait for it to exit
|
# Wait for it to exit
|
||||||
wait "$LWD_PID" || true
|
EXIT_CODE=0
|
||||||
EXIT_CODE=$?
|
wait "$LWD_PID" || EXIT_CODE=$?
|
||||||
LWD_PID=""
|
LWD_PID=""
|
||||||
|
|
||||||
if [[ $EXIT_CODE -eq 0 ]]; then
|
if [[ $STOPPING -eq 1 ]]; then
|
||||||
log "${YELLOW}lightwalletd exited cleanly (code 0). Not restarting.${NC}"
|
log "${YELLOW}lightwalletd stopped on request (code $EXIT_CODE). Not restarting.${NC}"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user