mirror of
https://github.com/fullstack-cash/bch-api.git
synced 2026-09-22 09:12:05 -07:00
Merge pull request #37 from christroutner/unstable
Removed websockets and decreased rate limits
This commit is contained in:
Generated
+1068
-885
File diff suppressed because it is too large
Load Diff
+1
-5
@@ -23,10 +23,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@chris.troutner/bch-js": "^1.3.0",
|
||||
"@chris.troutner/bitbox-js": "^7.0.2",
|
||||
"apidoc": "^0.17.7",
|
||||
"axios": "^0.19.0",
|
||||
"bitcoincash-zmq-decoder": "0.1.5",
|
||||
"body-parser": "^1.18.3",
|
||||
"cookie-parser": "~1.4.3",
|
||||
"cors": "^2.8.3",
|
||||
@@ -48,11 +46,9 @@
|
||||
"pg-hstore": "^2.3.2",
|
||||
"slp-sdk": "^4.4.1",
|
||||
"slpjs": "0.21.1",
|
||||
"socket.io": "^2.1.1",
|
||||
"strftime": "^0.10.0",
|
||||
"winston": "^3.2.1",
|
||||
"winston-daily-rotate-file": "^3.8.0",
|
||||
"zeromq": "^5.1.0"
|
||||
"winston-daily-rotate-file": "^3.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bignumber.js": "^9.0.0",
|
||||
|
||||
-57
@@ -1,5 +1,4 @@
|
||||
"use strict"
|
||||
const { Socket } = require("net")
|
||||
|
||||
const express = require("express")
|
||||
|
||||
@@ -18,19 +17,6 @@ const http = require("http")
|
||||
const cors = require("cors")
|
||||
const AuthMW = require("./middleware/auth")
|
||||
|
||||
const BitcoinCashZMQDecoder = require("bitcoincash-zmq-decoder")
|
||||
|
||||
const zmq = require("zeromq")
|
||||
|
||||
const sock = zmq.socket("sub")
|
||||
/*
|
||||
const swStats = require("swagger-stats")
|
||||
let apiSpec
|
||||
if (process.env.NETWORK === "mainnet")
|
||||
apiSpec = require("./public/bitcoin-com-mainnet-rest-v2.json")
|
||||
else apiSpec = require("./public/bitcoin-com-testnet-rest-v2.json")
|
||||
*/
|
||||
|
||||
// v2
|
||||
const indexV2 = require("./routes/v2/index")
|
||||
const healthCheckV2 = require("./routes/v2/health-check")
|
||||
@@ -185,49 +171,6 @@ console.log(`bch-api started on port ${port}`)
|
||||
* Create HTTP server.
|
||||
*/
|
||||
const server = http.createServer(app)
|
||||
const io = require("socket.io").listen(server)
|
||||
io.on("connection", socket => {
|
||||
console.log("Socket Connected")
|
||||
|
||||
socket.on("disconnect", () => {
|
||||
console.log("Socket Disconnected")
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Setup ZMQ connections if ZMQ URL and port provided
|
||||
*/
|
||||
|
||||
if (process.env.ZEROMQ_URL && process.env.ZEROMQ_PORT) {
|
||||
console.log(
|
||||
`Connecting to BCH ZMQ at ${process.env.ZEROMQ_URL}:${process.env.ZEROMQ_PORT}`
|
||||
)
|
||||
const bitcoincashZmqDecoder = new BitcoinCashZMQDecoder(process.env.NETWORK)
|
||||
|
||||
sock.connect(`tcp://${process.env.ZEROMQ_URL}:${process.env.ZEROMQ_PORT}`)
|
||||
sock.subscribe("raw")
|
||||
|
||||
sock.on("message", (topic, message) => {
|
||||
try {
|
||||
const decoded = topic.toString("ascii")
|
||||
if (decoded === "rawtx") {
|
||||
const txd = bitcoincashZmqDecoder.decodeTransaction(message)
|
||||
io.emit("transactions", JSON.stringify(txd, null, 2))
|
||||
} else if (decoded === "rawblock") {
|
||||
const blck = bitcoincashZmqDecoder.decodeBlock(message)
|
||||
io.emit("blocks", JSON.stringify(blck, null, 2))
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMessage = "Error processing ZMQ message"
|
||||
console.log(errorMessage, error)
|
||||
wlogger.error(errorMessage, error)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log(
|
||||
"ZEROMQ_URL and ZEROMQ_PORT env vars missing. Skipping ZMQ connection."
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on provided port, on all network interfaces.
|
||||
|
||||
@@ -15,7 +15,7 @@ const RateLimit = require("express-rate-limit")
|
||||
// Set max requests per minute
|
||||
const maxRequests = process.env.RATE_LIMIT_MAX_REQUESTS
|
||||
? parseInt(process.env.RATE_LIMIT_MAX_REQUESTS)
|
||||
: 60
|
||||
: 6
|
||||
|
||||
// Pro-tier rate limits are 10x the freemium limits.
|
||||
const PRO_RPM = 10 * maxRequests
|
||||
@@ -33,6 +33,8 @@ const routeRateLimit = function(req, res, next) {
|
||||
// Current route
|
||||
const rateLimitTier = req.locals.proLimit ? "PRO" : "BASIC"
|
||||
const path = req.baseUrl + req.path
|
||||
|
||||
// Create a unique string as a route identifier.
|
||||
const route =
|
||||
rateLimitTier +
|
||||
req.method +
|
||||
@@ -40,6 +42,7 @@ const routeRateLimit = function(req, res, next) {
|
||||
.split("/")
|
||||
.slice(0, 4)
|
||||
.join("/")
|
||||
//console.log(`route identifier: ${JSON.stringify(route, null, 2)}`)
|
||||
|
||||
// This boolean value is passed from the auth.js middleware.
|
||||
const proRateLimits = req.locals.proLimit
|
||||
@@ -89,6 +92,8 @@ const routeRateLimit = function(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
//console.log(`calling uniqueRateLimits() on this route: ${route}`)
|
||||
|
||||
// Call rate limit for this route
|
||||
uniqueRateLimits[route](req, res, next)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ const axios = require("axios")
|
||||
const util = require("util")
|
||||
util.inspect.defaultOptions = { depth: 1 }
|
||||
|
||||
const SERVER = `https://rest.btctest.net/v2/`
|
||||
const SERVER = `http://192.168.0.36:12400/v3/`
|
||||
//const SERVER = `http://localhost:3000/v2/`
|
||||
|
||||
describe("#rate limits", () => {
|
||||
|
||||
@@ -79,6 +79,8 @@ const mockRes = {
|
||||
format: sinon.stub().returns({})
|
||||
}
|
||||
|
||||
// Dev-Note on Rate Limits: Since next() is mocked, I can call the Sinon untility
|
||||
// functions on it, like called(), to see if this stub was called.
|
||||
const mockNext = sinon.stub().returns()
|
||||
|
||||
module.exports = {
|
||||
|
||||
+23
-23
@@ -12,7 +12,7 @@ util.inspect.defaultOptions = { depth: 1 }
|
||||
const { mockReq, mockRes, mockNext } = require("./mocks/express-mocks")
|
||||
|
||||
// Libraries under test
|
||||
const rateLimitMiddleware = require("../../src/middleware/route-ratelimit")
|
||||
let rateLimitMiddleware = require("../../src/middleware/route-ratelimit")
|
||||
const controlRoute = require("../../src/routes/v3/control")
|
||||
|
||||
let req, res, next
|
||||
@@ -43,26 +43,28 @@ describe("#route-ratelimits", () => {
|
||||
})
|
||||
|
||||
describe("#routeRateLimit", () => {
|
||||
const routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
let routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
const getInfo = controlRoute.testableComponents.getInfo
|
||||
/*
|
||||
|
||||
it("should pass through rate-limit middleware", async () => {
|
||||
req.baseUrl = "/v2"
|
||||
req.path = "/control/getInfo"
|
||||
req.baseUrl = "/v3"
|
||||
req.path = "/control/getNetworkInfo"
|
||||
req.method = "GET"
|
||||
|
||||
// Call the route twice to trigger the rate handling.
|
||||
await routeRateLimit(req, res, next)
|
||||
await routeRateLimit(req, res, next)
|
||||
|
||||
// next() will be called if rate-limit is not triggered
|
||||
assert.equal(next.called, true)
|
||||
})
|
||||
|
||||
it("should trigger rate-limit handler if rate limits exceeds 60 request per minute", async () => {
|
||||
req.baseUrl = "/v2"
|
||||
req.path = "/control/getInfo"
|
||||
it("should trigger rate-limit handler if rate limits exceeds 15 request per minute", async () => {
|
||||
req.baseUrl = "/v3"
|
||||
req.path = "/control/getNetworkInfo"
|
||||
req.method = "GET"
|
||||
|
||||
for (let i = 0; i < 65; i++) {
|
||||
for (let i = 0; i < 15; i++) {
|
||||
next.reset() // reset the stubbed next() function.
|
||||
|
||||
await routeRateLimit(req, res, next)
|
||||
@@ -76,18 +78,17 @@ describe("#route-ratelimits", () => {
|
||||
`next should not be called if rate limit was triggered.`
|
||||
)
|
||||
})
|
||||
*/
|
||||
/*
|
||||
it("should NOT trigger rate-limit handler for pro-tier at 65 RPM", async () => {
|
||||
|
||||
it("should NOT trigger rate-limit handler for pro-tier at 20 RPM", async () => {
|
||||
// Clear the require cache before running this test.
|
||||
delete require.cache[
|
||||
require.resolve("../../dist/middleware/route-ratelimit")
|
||||
require.resolve("../../src/middleware/route-ratelimit")
|
||||
]
|
||||
rateLimitMiddleware = require("../../dist/middleware/route-ratelimit")
|
||||
rateLimitMiddleware = require("../../src/middleware/route-ratelimit")
|
||||
routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
|
||||
req.baseUrl = "/v2"
|
||||
req.path = "/control/getInfo"
|
||||
req.baseUrl = "/v3"
|
||||
req.path = "/control/getNetworkInfo"
|
||||
req.method = "GET"
|
||||
|
||||
req.locals.proLimit = true
|
||||
@@ -97,7 +98,7 @@ describe("#route-ratelimits", () => {
|
||||
// Prepare the authorization header
|
||||
//req.headers.authorization = generateAuthHeader("BITBOX")
|
||||
|
||||
for (let i = 0; i < 65; i++) {
|
||||
for (let i = 0; i < 20; i++) {
|
||||
next.reset() // reset the stubbed next() function.
|
||||
|
||||
await routeRateLimit(req, res, next)
|
||||
@@ -117,13 +118,13 @@ describe("#route-ratelimits", () => {
|
||||
it("rate-limiting should still kick in at a higher RPM for pro-tier", async () => {
|
||||
// Clear the require cache before running this test.
|
||||
delete require.cache[
|
||||
require.resolve("../../dist/middleware/route-ratelimit")
|
||||
require.resolve("../../src/middleware/route-ratelimit")
|
||||
]
|
||||
rateLimitMiddleware = require("../../dist/middleware/route-ratelimit")
|
||||
rateLimitMiddleware = require("../../src/middleware/route-ratelimit")
|
||||
routeRateLimit = rateLimitMiddleware.routeRateLimit
|
||||
|
||||
req.baseUrl = "/v2"
|
||||
req.path = "/control/getInfo"
|
||||
req.baseUrl = "/v3"
|
||||
req.path = "/control/getNetworkInfo"
|
||||
req.method = "GET"
|
||||
|
||||
req.locals.proLimit = true
|
||||
@@ -133,7 +134,7 @@ describe("#route-ratelimits", () => {
|
||||
// Prepare the authorization header
|
||||
//req.headers.authorization = generateAuthHeader("BITBOX")
|
||||
|
||||
for (let i = 0; i < 650; i++) {
|
||||
for (let i = 0; i < 100; i++) {
|
||||
next.reset() // reset the stubbed next() function.
|
||||
|
||||
await routeRateLimit(req, res, next)
|
||||
@@ -149,7 +150,6 @@ describe("#route-ratelimits", () => {
|
||||
`next should NOT be called if rate limit was triggered.`
|
||||
)
|
||||
})
|
||||
*/
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user