diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f29e10793..38d27dbed 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -276,10 +276,12 @@ jobs:
FEE_TOKENS: '{ "1": "0x967da4048cD07aB37855c090aAF366e4ce1b9F48", "137": "0x282d8efCe846A88B159800bd4130ad77443Fa1A1", "80001": "0xd8992Ed72C445c35Cb4A2be468568Ed1079357c8", "56": "0xDCe07662CA8EbC241316a15B611c89711414Dd1a" }'
FEE_AMOUNT: '{ "amount": 1, "unit": "MB" }'
AUTHORIZED_DECRYPTERS: '["0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"]'
+ P2P_ENABLE_UPNP: 'false'
+ P2P_ENABLE_AUTONAT: 'false'
ALLOWED_ADMINS: '["0xe2DD09d719Da89e5a3D0F2549c7E24566e947260"]'
- name: Check Ocean Node is running
run: |
- for i in $(seq 1 30); do
+ for i in $(seq 1 90); do
if curl --output /dev/null --silent --head --fail "http://localhost:8001"; then
echo "Ocean Node is up"
exit 0
diff --git a/README.md b/README.md
index 0a5d23d67..a130f5f1d 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,11 @@ We recommend the following minimum requirements, although you may be be able to
## Option 1: Running Ocean Nodes in Docker (recommended)
+[This readme](deployment/README.md) is the recommended way to host a node and be eligible for incentives.
+The other options are more recommended towards deleveopers that want to tinker.
+
+## Option 2: Running local build of Ocean Nodes in Docker
+
Build and run the node using Docker:
```bash
@@ -25,7 +30,7 @@ docker build -t ocean-node:mybuild . # Build the Docker image
docker run -e PRIVATE_KEY=0x_your_private_key_here ocean-node:mybuild # Start container
```
-## Option 2: Running Ocean Nodes with PM2
+## Option 3: Running Ocean Nodes with PM2
PM2 is a process manager that makes it easy to manage and monitor your Node.js applications.
@@ -80,7 +85,7 @@ npm run build # Build the Project
#### Option 1: Automatic Setup (Recommended)
-Run the helper script to generate and set up the recommended environment variables:
+Run the helper script to generate and set up the minimum required environment variables:
```bash
./src/helpers/scripts/setupNodeEnv.sh
@@ -97,7 +102,7 @@ export PRIVATE_KEY="0x_your_private_key_here"
The `PRIVATE_KEY` is the only mandatory environmental variable, you must include the `0x` at the front of your private key. Additional configurations can be set as needed. For all available configurations, refer to the [Environment Variables](docs/env.md) documentation.
-### 5. Start the Node
+### 4. Start the Node
```bash
npm run start
diff --git a/dashboard/src/components/NodePeers/index.tsx b/dashboard/src/components/NodePeers/index.tsx
index f24eeacd5..af954fdf5 100644
--- a/dashboard/src/components/NodePeers/index.tsx
+++ b/dashboard/src/components/NodePeers/index.tsx
@@ -40,7 +40,7 @@ export default function NodePeers() {
return (
-
Connected Nodes
+
Connected Nodes (Total {nodePeers.length})
{isLoadingNodePeers && (
diff --git a/deployment/README.md b/deployment/README.md
index c2ca84d10..17bbd63dd 100644
--- a/deployment/README.md
+++ b/deployment/README.md
@@ -4,7 +4,7 @@ Note: For installing each of these prerequisites, a good starting point is the o
Before starting, confirm that the [system requirements](https://github.com/oceanprotocol/ocean-node?tab=readme-ov-file#system-requirements) are met.
-a) download the script `ocean-node-quickstart.sh` from the current directory
+a) download the script `ocean-node-quickstart.sh` from the current directory
b) run the script
@@ -20,11 +20,11 @@ Do you want me to create a private key for you [ y/n ]: y
Generating Private Key, please wait...
Generated Private Key: << redacted >>
Please provide the wallet address to be added as Ocean Node admin account: << redacted >>
-Provide the HTTP_API_PORT value or accept the default (press Enter) [8000]:
-Provide the P2P_ipV4BindTcpPort or accept the default (press Enter) [9000]:
-Provide the P2P_ipV4BindWsPort or accept the default (press Enter) [9001]:
-Provide the P2P_ipV6BindTcpPort or accept the default (press Enter) [9002]:
-Provide the P2P_ipV6BindWsPort or accept the default (press Enter) [9003]:
+Provide the HTTP_API_PORT value or accept the default (press Enter) [8000]:
+Provide the P2P_ipV4BindTcpPort or accept the default (press Enter) [9000]:
+Provide the P2P_ipV4BindWsPort or accept the default (press Enter) [9001]:
+Provide the P2P_ipV6BindTcpPort or accept the default (press Enter) [9002]:
+Provide the P2P_ipV6BindWsPort or accept the default (press Enter) [9003]:
Provide the public IPv4/IPv6 address or FQDN where this node will be accessible: << redacted >>
Docker Compose file has been generated successfully.
@@ -45,16 +45,12 @@ P2P IPv6 TCP Port: 9002
P2P IPv6 WebSocket Port: 9003
```
-
-
d) start your Ocean Node
```shell
$ docker-compose up -d
```
-
-
e) confirm that docker containers are running
```shell
@@ -64,8 +60,6 @@ CONTAINER ID IMAGE COMMAND CREATE
858a59502302 typesense/typesense:26.0 "/opt/typesense-serv…" 17 seconds ago Up 10 seconds 0.0.0.0:8108->8108/tcp, :::8108->8108/tcp typesense
```
-
-
Additional notes:
- the docker compose file generated will have the following format. For all available configurations, refer to the [Environment Variables](https://github.com/oceanprotocol/ocean-node/blob/main/docs/env.md) documentation
@@ -78,57 +72,57 @@ services:
container_name: ocean-node
restart: on-failure
ports:
- - "8000:8000"
- - "9000:9000"
- - "9001:9001"
- - "9002:9002"
- - "9003:9003"
+ - '8000:8000'
+ - '9000:9000'
+ - '9001:9001'
+ - '9002:9002'
+ - '9003:9003'
environment:
PRIVATE_KEY: '<>'
RPCS: '{"1":{"rpc":"https://ethereum-rpc.publicnode.com","fallbackRPCs":["https://rpc.ankr.com/eth","https://1rpc.io/eth","https://eth.api.onfinality.io/public"],"chainId":1,"network":"mainnet","chunkSize":100},"10":{"rpc":"https://mainnet.optimism.io","fallbackRPCs":["https://optimism-mainnet.public.blastapi.io","https://rpc.ankr.com/optimism","https://optimism-rpc.publicnode.com"],"chainId":10,"network":"optimism","chunkSize":100},"137":{"rpc":"https://polygon-rpc.com/","fallbackRPCs":["https://polygon-mainnet.public.blastapi.io","https://1rpc.io/matic","https://rpc.ankr.com/polygon"],"chainId":137,"network":"polygon","chunkSize":100},"23294":{"rpc":"https://sapphire.oasis.io","fallbackRPCs":["https://1rpc.io/oasis/sapphire"],"chainId":23294,"network":"sapphire","chunkSize":100},"23295":{"rpc":"https://testnet.sapphire.oasis.io","chainId":23295,"network":"sapphire-testnet","chunkSize":100},"11155111":{"rpc":"https://eth-sepolia.public.blastapi.io","fallbackRPCs":["https://1rpc.io/sepolia","https://eth-sepolia.g.alchemy.com/v2/demo"],"chainId":11155111,"network":"sepolia","chunkSize":100},"11155420":{"rpc":"https://sepolia.optimism.io","fallbackRPCs":["https://endpoints.omniatech.io/v1/op/sepolia/public","https://optimism-sepolia.blockpi.network/v1/rpc/public"],"chainId":11155420,"network":"optimism-sepolia","chunkSize":100}}'
DB_URL: 'http://typesense:8108/?apiKey=xyz'
IPFS_GATEWAY: 'https://ipfs.io/'
ARWEAVE_GATEWAY: 'https://arweave.net/'
- LOAD_INITIAL_DDOS: ''
- FEE_TOKENS: ''
- FEE_AMOUNT: ''
- ADDRESS_FILE: ''
- NODE_ENV: ''
- AUTHORIZED_DECRYPTERS: ''
- OPERATOR_SERVICE_URL: ''
- INTERFACES: ''
- ALLOWED_VALIDATORS: ''
- INDEXER_NETWORKS: '[]'
+ # LOAD_INITIAL_DDOS: ''
+ # FEE_TOKENS: ''
+ # FEE_AMOUNT: ''
+ # ADDRESS_FILE: ''
+ # NODE_ENV: ''
+ # AUTHORIZED_DECRYPTERS: ''
+ # OPERATOR_SERVICE_URL: ''
+ INTERFACES: '["HTTP","P2P"]'
+ # ALLOWED_VALIDATORS: ''
+ # INDEXER_NETWORKS: '[]'
ALLOWED_ADMINS: '["<>"]'
- INDEXER_INTERVAL: ''
+ # INDEXER_INTERVAL: ''
DASHBOARD: 'true'
- RATE_DENY_LIST: ''
- MAX_REQ_PER_SECOND: ''
- MAX_CHECKSUM_LENGTH: ''
- LOG_LEVEL: ''
+ # RATE_DENY_LIST: ''
+ # MAX_REQ_PER_SECOND: ''
+ # MAX_CHECKSUM_LENGTH: ''
+ # LOG_LEVEL: ''
HTTP_API_PORT: '8000'
- P2P_ENABLE_IPV4: ''
- P2P_ENABLE_IPV6: ''
- P2P_ipV4BindAddress: ''
+ P2P_ENABLE_IPV4: 'true'
+ P2P_ENABLE_IPV6: 'false'
+ P2P_ipV4BindAddress: '0.0.0.0'
P2P_ipV4BindTcpPort: '9000'
P2P_ipV4BindWsPort: '9001'
- P2P_ipV6BindAddress: ''
+ P2P_ipV6BindAddress: '::'
P2P_ipV6BindTcpPort: '9002'
P2P_ipV6BindWsPort: '9003'
P2P_ANNOUNCE_ADDRESSES: '["/dns4/<>/tcp/9000/p2p/", "/dns4/<>/ws/tcp/9001", "/dns6/<>/tcp/9002/p2p/", "/dns6/<>/ws/tcp/9003"]'
- P2P_ANNOUNCE_PRIVATE: ''
- P2P_pubsubPeerDiscoveryInterval: ''
- P2P_dhtMaxInboundStreams: ''
- P2P_dhtMaxOutboundStreams: ''
- P2P_mDNSInterval: ''
- P2P_connectionsMaxParallelDials: ''
- P2P_connectionsDialTimeout: ''
- P2P_ENABLE_UPNP: ''
- P2P_ENABLE_AUTONAT: ''
- P2P_ENABLE_CIRCUIT_RELAY_SERVER: ''
- P2P_ENABLE_CIRCUIT_RELAY_CLIENT: ''
- P2P_BOOTSTRAP_NODES: ''
- P2P_FILTER_ANNOUNCED_ADDRESSES: ''
+ # P2P_ANNOUNCE_PRIVATE: ''
+ # P2P_pubsubPeerDiscoveryInterval: ''
+ # P2P_dhtMaxInboundStreams: ''
+ # P2P_dhtMaxOutboundStreams: ''
+ # P2P_mDNSInterval: ''
+ # P2P_connectionsMaxParallelDials: ''
+ # P2P_connectionsDialTimeout: ''
+ # P2P_ENABLE_UPNP: ''
+ # P2P_ENABLE_AUTONAT: ''
+ # P2P_ENABLE_CIRCUIT_RELAY_SERVER: ''
+ # P2P_ENABLE_CIRCUIT_RELAY_CLIENT: ''
+ # P2P_BOOTSTRAP_NODES: ''
+ # P2P_FILTER_ANNOUNCED_ADDRESSES: ''
networks:
- ocean_network
depends_on:
@@ -138,7 +132,7 @@ services:
image: typesense/typesense:26.0
container_name: typesense
ports:
- - "8108:8108"
+ - '8108:8108'
networks:
- ocean_network
volumes:
diff --git a/deployment/ocean-node-quickstart.sh b/deployment/ocean-node-quickstart.sh
index a16f25dc9..4c3085338 100755
--- a/deployment/ocean-node-quickstart.sh
+++ b/deployment/ocean-node-quickstart.sh
@@ -141,46 +141,46 @@ services:
DB_URL: 'http://typesense:8108/?apiKey=xyz'
IPFS_GATEWAY: 'https://ipfs.io/'
ARWEAVE_GATEWAY: 'https://arweave.net/'
- LOAD_INITIAL_DDOS: ''
- FEE_TOKENS: ''
- FEE_AMOUNT: ''
- ADDRESS_FILE: ''
- NODE_ENV: ''
- AUTHORIZED_DECRYPTERS: ''
- OPERATOR_SERVICE_URL: ''
- INTERFACES: ''
- ALLOWED_VALIDATORS: ''
- INDEXER_NETWORKS: '[]'
+# LOAD_INITIAL_DDOS: ''
+# FEE_TOKENS: ''
+# FEE_AMOUNT: ''
+# ADDRESS_FILE: ''
+# NODE_ENV: ''
+# AUTHORIZED_DECRYPTERS: ''
+# OPERATOR_SERVICE_URL: ''
+ INTERFACES: '["HTTP","P2P"]'
+# ALLOWED_VALIDATORS: ''
+# INDEXER_NETWORKS: '[]'
ALLOWED_ADMINS: '["$ALLOWED_ADMINS"]'
- INDEXER_INTERVAL: ''
+# INDEXER_INTERVAL: ''
DASHBOARD: 'true'
- RATE_DENY_LIST: ''
- MAX_REQ_PER_SECOND: ''
- MAX_CHECKSUM_LENGTH: ''
- LOG_LEVEL: ''
+# RATE_DENY_LIST: ''
+# MAX_REQ_PER_SECOND: ''
+# MAX_CHECKSUM_LENGTH: ''
+# LOG_LEVEL: ''
HTTP_API_PORT: '$HTTP_API_PORT'
- P2P_ENABLE_IPV4: ''
- P2P_ENABLE_IPV6: ''
- P2P_ipV4BindAddress: ''
+ P2P_ENABLE_IPV4: 'true'
+ P2P_ENABLE_IPV6: 'false'
+ P2P_ipV4BindAddress: '0.0.0.0'
P2P_ipV4BindTcpPort: '$P2P_ipV4BindTcpPort'
P2P_ipV4BindWsPort: '$P2P_ipV4BindWsPort'
- P2P_ipV6BindAddress: ''
+ P2P_ipV6BindAddress: '::'
P2P_ipV6BindTcpPort: '$P2P_ipV6BindTcpPort'
P2P_ipV6BindWsPort: '$P2P_ipV6BindWsPort'
P2P_ANNOUNCE_ADDRESSES: '$P2P_ANNOUNCE_ADDRESSES'
- P2P_ANNOUNCE_PRIVATE: ''
- P2P_pubsubPeerDiscoveryInterval: ''
- P2P_dhtMaxInboundStreams: ''
- P2P_dhtMaxOutboundStreams: ''
- P2P_mDNSInterval: ''
- P2P_connectionsMaxParallelDials: ''
- P2P_connectionsDialTimeout: ''
- P2P_ENABLE_UPNP: ''
- P2P_ENABLE_AUTONAT: ''
- P2P_ENABLE_CIRCUIT_RELAY_SERVER: ''
- P2P_ENABLE_CIRCUIT_RELAY_CLIENT: ''
- P2P_BOOTSTRAP_NODES: ''
- P2P_FILTER_ANNOUNCED_ADDRESSES: ''
+# P2P_ANNOUNCE_PRIVATE: ''
+# P2P_pubsubPeerDiscoveryInterval: ''
+# P2P_dhtMaxInboundStreams: ''
+# P2P_dhtMaxOutboundStreams: ''
+# P2P_mDNSInterval: ''
+# P2P_connectionsMaxParallelDials: ''
+# P2P_connectionsDialTimeout: ''
+# P2P_ENABLE_UPNP: ''
+# P2P_ENABLE_AUTONAT: ''
+# P2P_ENABLE_CIRCUIT_RELAY_SERVER: ''
+# P2P_ENABLE_CIRCUIT_RELAY_CLIENT: ''
+# P2P_BOOTSTRAP_NODES: ''
+# P2P_FILTER_ANNOUNCED_ADDRESSES: ''
networks:
- ocean_network
depends_on:
diff --git a/dist/dashboard/404.html b/dist/dashboard/404.html
index f750a7cfb..826ee5487 100644
--- a/dist/dashboard/404.html
+++ b/dist/dashboard/404.html
@@ -1 +1 @@
-404: This page could not be found
404
This page could not be found.
\ No newline at end of file
+404: This page could not be found
404
This page could not be found.
diff --git a/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_buildManifest.js b/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_buildManifest.js
new file mode 100644
index 000000000..9a3e0370f
--- /dev/null
+++ b/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_buildManifest.js
@@ -0,0 +1 @@
+self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/":["static/chunks/2477-ff31ed06ca3bb6b0.js","static/css/a66f1c922ed6fd7f.css","static/chunks/pages/index-65a2360df4a5ce0c.js"],"/_error":["static/chunks/pages/_error-e4216aab802f5810.js"],sortedPages:["/","/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
\ No newline at end of file
diff --git a/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_ssgManifest.js b/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_ssgManifest.js
new file mode 100644
index 000000000..0511aa895
--- /dev/null
+++ b/dist/dashboard/_next/static/TKOP_tQWDQuagCxlBxyhs/_ssgManifest.js
@@ -0,0 +1 @@
+self.__SSG_MANIFEST=new Set,self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB();
\ No newline at end of file
diff --git a/dist/dashboard/_next/static/chunks/pages/index-65a2360df4a5ce0c.js b/dist/dashboard/_next/static/chunks/pages/index-65a2360df4a5ce0c.js
new file mode 100644
index 000000000..675ea490f
--- /dev/null
+++ b/dist/dashboard/_next/static/chunks/pages/index-65a2360df4a5ce0c.js
@@ -0,0 +1 @@
+(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[5405],{48312:function(e,n,t){(window.__NEXT_P=window.__NEXT_P||[]).push(["/",function(){return t(32323)}])},32323:function(e,n,t){"use strict";t.r(n),t.d(n,{default:function(){return Home}});var s,a,r=t(85893),i=t(9008),o=t.n(i),l=t(25675),d=t.n(l),c={src:"/_next/static/media/logo-nodes.249ea9ed.svg",height:283,width:425,blurWidth:0,blurHeight:0},h=t(30378),u=t.n(h),x=t(89192),Navigation=()=>(0,r.jsxs)("div",{className:u().navbarParent,children:[(0,r.jsx)("div",{className:u().logoWrapper,children:(0,r.jsx)(d(),{src:c,alt:"Ocean Node Logo",height:70})}),(0,r.jsx)("div",{className:u().connectButtonWrapper,children:(0,r.jsx)(x.NL,{})})]}),j=t(94428),m=t.n(j),components_Footer=()=>{let e=new Date().getFullYear();return(0,r.jsxs)("div",{className:m().footerContainer,children:[(0,r.jsxs)("p",{children:["@ ",e,", Ocean Nodes"]}),(0,r.jsxs)("div",{className:m().footerLinks,children:[(0,r.jsx)("a",{href:"https://oceanprotocol.com/",target:"_blank",children:"Website"}),(0,r.jsx)("a",{href:"https://github.com/oceanprotocol/ocean-node",target:"_blank",children:"GitHub"}),(0,r.jsx)("a",{href:"https://discord.com/invite/TnXjkR5",target:"_blank",children:"Discord"})]})]})},v=t(67294),p=t(93967),_=t.n(p),b=t(11706),N=t.n(b);let truncateString=function(e){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:6;if(e){let t=e.slice(0,2+n),s=e.slice(-n);return"".concat(t,"....").concat(s)}return e};var f=t(59581),g=t(46085),y=t.n(g),S=t(69417),C=t(94054),I=t(50135),w=t(33841),D=t(30638),k=t(23599),T=t(10586),E=t(50720),Z=t(93624),A=t(27484),P=t.n(A),O={src:"/_next/static/media/download.0a4876ec.svg",height:30,width:30,blurWidth:0,blurHeight:0};function DownloadButton(){let[e,n]=(0,v.useState)(!1),[t,s]=(0,v.useState)(!1),[a,i]=(0,v.useState)(P()()),[o,l]=(0,v.useState)(P()()),[c,h]=(0,v.useState)(""),[u,x]=(0,v.useState)(""),[j,m]=(0,v.useState)(""),{signature:p,expiryTimestamp:_}=(0,f.O)(),b=(0,v.useCallback)(async()=>{let e=a?"&startTime=".concat(a.toISOString()):"",n=o?"&endTime=".concat(o.toISOString()):"",t=c?"&maxLogs=".concat(c):"",r=u&&"all"!==u?"&moduleName=".concat(u):"",i=j&&"all"!==j?'&level="'.concat(j,'"'):"";s(!0);try{if(!_||!p){console.error("Missing expiryTimestamp or signature");return}let a=await fetch("/logs?".concat(e).concat(n).concat(t).concat(r).concat(i),{headers:{"Content-Type":"application/json"},method:"POST",body:JSON.stringify({expiryTimestamp:_,signature:p})}),o=await a.json();if(o){let e="data:application/json;charset=utf-8,"+encodeURIComponent(JSON.stringify(o)),n=document.createElement("a");n.setAttribute("href",e),n.setAttribute("download","LogsData.json"),document.body.appendChild(n),n.click(),n.remove()}s(!1)}catch(e){console.error(e),s(!1)}},[a,o,c,u,j]);return(0,r.jsxs)("div",{className:y().column,children:[(0,r.jsx)(S.Z,{type:"button",onClick:()=>n(!e),children:"Download Logs"}),e&&(0,r.jsxs)("div",{className:y().filters,children:[(0,r.jsxs)(E._,{dateAdapter:T.y,children:[(0,r.jsx)(C.Z,{fullWidth:!0,margin:"normal",children:(0,r.jsx)(Z.x,{label:"Start Date",value:a,onChange:e=>i(e)})}),(0,r.jsx)(C.Z,{fullWidth:!0,margin:"normal",children:(0,r.jsx)(Z.x,{label:"End Date",value:o,onChange:e=>l(e)})})]}),(0,r.jsx)(I.Z,{label:"Max Logs",type:"number",value:c,onChange:e=>h(e.target.value),fullWidth:!0,margin:"normal",variant:"outlined"}),(0,r.jsxs)(C.Z,{fullWidth:!0,margin:"normal",children:[(0,r.jsx)(w.Z,{id:"select-module-name-label",children:"Module Name"}),(0,r.jsxs)(D.Z,{labelId:"select-module-name-label",label:"Module Name",id:"module-name",value:u,onChange:e=>x(e.target.value),children:[(0,r.jsx)(k.Z,{value:"all",children:"all"}),(0,r.jsx)(k.Z,{value:"http",children:"http"}),(0,r.jsx)(k.Z,{value:"p2p",children:"p2p"}),(0,r.jsx)(k.Z,{value:"indexer",children:"indexer"}),(0,r.jsx)(k.Z,{value:"reindexer",children:"reindexer"}),(0,r.jsx)(k.Z,{value:"provider",children:"provider"}),(0,r.jsx)(k.Z,{value:"database",children:"database"}),(0,r.jsx)(k.Z,{value:"config",children:"config"}),(0,r.jsx)(k.Z,{value:"core",children:"core"}),(0,r.jsx)(k.Z,{value:"OceanNode",children:"OceanNode"})]})]}),(0,r.jsxs)(C.Z,{fullWidth:!0,margin:"normal",children:[(0,r.jsx)(w.Z,{id:"select-level-label",children:"Level"}),(0,r.jsxs)(D.Z,{labelId:"select-level-label",label:"Level",id:"level",value:j,onChange:e=>m(e.target.value),children:[(0,r.jsx)(k.Z,{value:"all",children:"all"}),(0,r.jsx)(k.Z,{value:"error",children:"error"}),(0,r.jsx)(k.Z,{value:"warn",children:"warn"}),(0,r.jsx)(k.Z,{value:"info",children:"info"}),(0,r.jsx)(k.Z,{value:"http",children:"http"}),(0,r.jsx)(k.Z,{value:"verbose",children:"verbose"}),(0,r.jsx)(k.Z,{value:"debug",children:"debug"}),(0,r.jsx)(k.Z,{value:"silly",children:"silly"})]})]}),(0,r.jsx)(S.Z,{type:"button",onClick:b,variant:"outlined",startIcon:(0,r.jsx)(d(),{src:O,alt:"download button",width:24,height:24}),disabled:t,children:"Download"})]})]})}function StopNode(){let[e,n]=(0,v.useState)(!1),{signature:t,expiryTimestamp:s}=(0,f.O)();async function stopNode(){n(!0);try{s&&t&&await fetch("/directCommand",{headers:{Accept:"application/json","Content-Type":"application/json"},method:"POST",body:JSON.stringify({command:"stopNode",expiryTimestamp:s,signature:t})}),alert("The node has been stopped. The dashboard will no longer be displayed."),window.location.reload()}catch(e){console.error("error",e)}finally{n(!1)}}return(0,r.jsx)(S.Z,{onClick:stopNode,variant:"outlined",color:"error",children:e?(0,r.jsx)(()=>(0,r.jsx)("span",{className:y().loader}),{}):(0,r.jsx)("div",{children:"Stop Node"})})}var R=t(92321),L=t(31536);function NetworkSelector(e){let{chainId:n,setChainId:t}=e,{networks:s}=(0,f.O)();return(0,r.jsxs)(C.Z,{fullWidth:!0,margin:"normal",variant:"outlined",children:[(0,r.jsx)(w.Z,{id:"network-select-label",children:"Network"}),(0,r.jsx)(D.Z,{labelId:"network-select-label",id:"network-select",value:n||"",onChange:e=>t(e.target.value),label:"Network",children:Object.values(s).map(e=>(0,r.jsx)(k.Z,{value:e.chainId.toString(),children:e.network},e.chainId))})]})}(s=a||(a={})).DELIVERED="DELIVERED",s.PENDING="PENDING",s.FAILURE="FAILURE",s.SUCCESS="SUCCESS";let checkJobPool=async function(e){try{let n=await fetch("/api/services/jobs/"+(e||""),{headers:{Accept:"application/json","Content-Type":"application/json"},method:"GET"}),t=await n.json();return t.jobs}catch(e){console.error(e)}return[]};function getSeverityFromStatus(e){switch(e){case a.DELIVERED:return"info";case a.SUCCESS:return"success";case a.PENDING:return"warning";default:return"error"}}function isJobDone(e){return[a.SUCCESS,a.FAILURE].includes(e)}var B=t(8434);function JobStatusPanel(e){let n=e.job?function(e){switch(e){case a.DELIVERED:return"DodgerBlue";case a.PENDING:return"LightSlateGrey";case a.SUCCESS:return"ForestGreen";case a.FAILURE:return"OrangeRed";default:return"black"}}(e.job.status):"black";return(0,r.jsx)("div",{children:null!==e.job&&(0,r.jsxs)(B.Z,{sx:{bgcolor:n},variant:"filled",severity:e.severity,onClose:()=>{},children:["Job with id ",(0,r.jsx)("strong",{children:e.job.jobId})," has status"," ",(0,r.jsx)("strong",{children:e.job.status})]})})}var W=t(602);function ReIndexChain(){let[e,n]=(0,v.useState)(!1),[t,s]=(0,v.useState)(!1),[i,o]=(0,v.useState)(),{signature:l,expiryTimestamp:d}=(0,f.O)(),[c,h]=(0,v.useState)("info"),[u,x]=(0,v.useState)(null),j=null;async function reIndex(){s(!0);try{if(d&&l&&i){let e=await fetch("/directCommand",{headers:{Accept:"application/json","Content-Type":"application/json"},method:"POST",body:JSON.stringify({command:"reindexChain",chainId:i,expiryTimestamp:d,signature:l})});if(200===e.status){let t=await e.json();h(t.status===a.DELIVERED?"info":"error"),x(t),alert("Chain with ID ".concat(i," is now being reindexed."));let s=!1;j=setInterval(async()=>{let e=await checkJobPool(t.jobId);if(1===e.length){let n=e[0];h(getSeverityFromStatus(n.status)),s=isJobDone(n.status),x(n)}else x(null)},3e3),s&&j&&(0,W.clearInterval)(j),n(!1)}else alert("Error reindexing chain. Please try again.")}}catch(e){console.error("error",e)}finally{s(!1)}}return(0,r.jsxs)("div",{className:y().column,children:[(0,r.jsx)(S.Z,{type:"button",onClick:()=>n(!e),children:"ReIndex Chain"}),e&&(0,r.jsxs)("div",{className:y().filters,children:[(0,r.jsx)(NetworkSelector,{chainId:i,setChainId:o}),(0,r.jsx)(S.Z,{type:"button",onClick:reIndex,variant:"outlined",disabled:t,children:"ReIndex Chain"})]}),(0,r.jsx)(JobStatusPanel,{job:u,severity:c})]})}function ReIndexTransaction(){let[e,n]=(0,v.useState)(!1),[t,s]=(0,v.useState)(!1),[i,o]=(0,v.useState)(),[l,d]=(0,v.useState)(),{signature:c,expiryTimestamp:h}=(0,f.O)(),[u,x]=(0,v.useState)("info"),[j,m]=(0,v.useState)(null),p=null;async function reIndexTx(){s(!0);try{if(h&&c&&i&&l){let e=await fetch("/directCommand",{headers:{Accept:"application/json","Content-Type":"application/json"},method:"POST",body:JSON.stringify({command:"reindexTx",chainId:i,txId:l,expiryTimestamp:h,signature:c})});if(200===e.status){let t=await e.json();x(t.status===a.DELIVERED?"info":"error"),m(t),alert("Transaction with TX ID ".concat(l," on chain ").concat(i," is now being reindexed."));let s=!1;p=setInterval(async()=>{let e=await checkJobPool(t.jobId);if(1===e.length){let n=e[0];x(getSeverityFromStatus(n.status)),s=isJobDone(n.status),m(n)}else m(null)},3e3),s&&p&&clearInterval(p),n(!1)}else alert("Error reindexing transaction. Please try again.")}}catch(e){console.error("error",e)}finally{s(!1)}}return(0,r.jsxs)("div",{className:y().column,children:[(0,r.jsx)(S.Z,{type:"button",onClick:()=>n(!e),children:"ReIndex Transaction"}),e&&(0,r.jsxs)("div",{className:y().filters,children:[(0,r.jsx)(NetworkSelector,{chainId:i,setChainId:o}),(0,r.jsx)(I.Z,{label:"Transaction ID",value:l,onChange:e=>d(e.target.value),fullWidth:!0,margin:"normal",variant:"outlined"}),(0,r.jsx)(S.Z,{type:"button",onClick:reIndexTx,variant:"outlined",disabled:t,children:"ReIndex Transaction"})]}),(0,r.jsx)(JobStatusPanel,{job:j,severity:u})]})}function AdminActions(){let{generateSignature:e,signature:n,validTimestamp:t,admin:s}=(0,f.O)(),{isConnected:a}=(0,R.m)();return(0,r.jsxs)("div",{className:y().root,children:[(0,r.jsx)("div",{className:y().title,children:"ADMIN ACTIONS"}),!a&&(0,r.jsx)(x.NL,{}),a&&!s&&(0,r.jsx)("div",{className:y().unauthorised,children:"Your account does not have admin access"}),(!n||!t)&&a&&s&&(0,r.jsx)("button",{type:"button",className:y().unlockButton,onClick:e,children:"Unlock"}),a&&n&&t&&a&&s&&(0,r.jsxs)(L.Z,{spacing:2,direction:"column",children:[(0,r.jsx)(DownloadButton,{}),(0,r.jsx)(ReIndexChain,{}),(0,r.jsx)(ReIndexTransaction,{}),(0,r.jsx)(StopNode,{})]})]})}var F=t(17044),J=t.n(F);function Spinner(){return(0,r.jsx)("span",{className:J().loader})}var U=t(85108),G=t.n(U),Q=t(75368),H=t.n(Q),M={src:"/_next/static/media/copy.63713a04.svg",height:16,width:15,blurWidth:0,blurHeight:0};function Copy(e){let{text:n}=e,[t,s]=(0,v.useState)(!1),copyToClipboard=e=>{let n=document.createElement("textarea");n.value=e,document.body.appendChild(n),n.select(),document.execCommand("copy"),document.body.removeChild(n)};return(0,v.useEffect)(()=>{if(!t)return;let e=setTimeout(()=>{s(!1)},1e3);return()=>clearTimeout(e)},[t]),(0,r.jsxs)("div",{className:H().action,onClick:()=>{copyToClipboard(n),s(!0)},children:[(0,r.jsx)(d(),{src:M,alt:"icont-copy",className:H().icon}),t&&(0,r.jsx)("div",{className:H().feedback,children:"Copied!"})]})}function NodePeers(){let[e,n]=(0,v.useState)([]),[t,s]=(0,v.useState)(!0),fetchNodePeers=async()=>{s(!0);try{let e=await fetch("/getOceanPeers",{headers:{Accept:"application/json","Content-Type":"application/json"},method:"GET"}),t=await e.json();n(t)}catch(e){console.error("error",e)}finally{s(!1)}};return(0,v.useEffect)(()=>{fetchNodePeers();let e=setInterval(()=>{fetchNodePeers()},12e4);return()=>clearInterval(e)},[]),(0,r.jsxs)("div",{className:G().nodes,children:[(0,r.jsxs)("div",{className:G().title24,children:["Connected Nodes (Total ",e.length,")"]}),t&&(0,r.jsx)("div",{className:G().loaderContainer,children:(0,r.jsx)(Spinner,{})}),e.length>0?e.map(e=>(0,r.jsxs)("div",{className:G().nodeAddress,children:[truncateString(e,12)," ",(0,r.jsx)(Copy,{text:e})]},e)):(0,r.jsx)("div",{children:"There are no nodes connected"})]})}function SupportedStorage(e){let{data:n}=e;return(0,r.jsxs)("div",{className:N().indexer,children:[(0,r.jsx)("div",{className:N().title29,children:"SUPPORTED STORAGE"}),(0,r.jsxs)("div",{className:N().provider,children:[(0,r.jsxs)("div",{className:N().providerRow,children:[(0,r.jsx)("div",{className:N().providerTitle,children:(0,r.jsx)("b",{children:"arwave:"})}),(0,r.jsxs)("div",{children:[null==n?void 0:n.supportedStorage.arwave.toString()," "]})]}),(0,r.jsxs)("div",{className:N().providerRow,children:[(0,r.jsx)("div",{className:N().providerTitle,children:(0,r.jsx)("b",{children:"ipfs:"})}),(0,r.jsxs)("div",{children:[null==n?void 0:n.supportedStorage.ipfs.toString()," "]})]}),(0,r.jsxs)("div",{className:N().providerRow,children:[(0,r.jsx)("div",{className:N().providerTitle,children:(0,r.jsx)("b",{children:"url:"})}),(0,r.jsxs)("div",{children:[null==n?void 0:n.supportedStorage.url.toString()," "]})]})]})]})}function SupportedNetworks_SupportedStorage(e){let{data:n}=e;return(0,r.jsxs)("div",{className:N().indexer,children:[(0,r.jsx)("div",{className:N().title29,children:"SUPPORTED Networks"}),(0,r.jsx)("div",{className:N().provider,children:null==n?void 0:n.provider.map(e=>(0,r.jsxs)("div",{className:N().providerRow,children:[(0,r.jsx)("div",{className:N().providerTitle,children:(0,r.jsx)("b",{children:e.chainId})}),(0,r.jsxs)("div",{children:[e.network," "]})]}))})]})}var q=t(72882),X=t(7906),V=t(53184),K=t(53816),Y=t(53252),z=t(295),$=t(27061);function IndexQueue(){let[e,n]=(0,v.useState)([]),{networks:t}=(0,f.O)(),[s,a]=(0,v.useState)(!1),i=null;return(0,v.useEffect)(()=>{let fetchQueue=()=>{fetch("/api/services/indexQueue").then(e=>{400===e.status?(console.warn("Cannot fetch queue: Node is not running Indexer"),a(!0),i&&clearInterval(i)):e.json().then(e=>{let s=e.queue.map(e=>{let n=t.find(n=>n.chainId===e.chainId);return{txId:e.txId,chainId:e.chainId,chain:n?n.network:"Unknown Network"}});n(s)})}).catch(e=>{console.error("Error fetching queue:",e)})};fetchQueue();let e=1e4;return $.env.INDEXER_INTERVAL&&(e=Number($.env.INDEXER_INTERVAL)),i=setInterval(fetchQueue,e),()=>{i&&clearInterval(i)}},[]),(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:N().title24,style:{paddingTop:"55px",paddingBottom:"55px"},children:"Indexing Queue"}),e.length>0?(0,r.jsx)(q.Z,{children:(0,r.jsxs)(X.Z,{"aria-label":"simple table",children:[(0,r.jsx)(V.Z,{children:(0,r.jsxs)(K.Z,{children:[(0,r.jsx)(Y.Z,{children:(0,r.jsx)("b",{children:"Transaction ID"})}),(0,r.jsx)(Y.Z,{align:"right",children:(0,r.jsx)("b",{children:"Network"})})]})}),(0,r.jsx)(z.Z,{children:e.map((e,n)=>(0,r.jsxs)(K.Z,{children:[(0,r.jsx)(Y.Z,{component:"th",scope:"row",children:e.txId}),(0,r.jsx)(Y.Z,{align:"right",children:e.chain})]},n))})]})}):(0,r.jsx)("p",{children:"Indexing queue is empty."}),s&&(0,r.jsx)(B.Z,{className:N().indexerQueueAlert,severity:"warning",onClose:()=>{a(!1)},children:"Node is not running Indexer. No need to get queue at this point!"})]})}var ee=t(86886),en=t(66242);function Indexer(e){let{data:n}=e;return(0,r.jsxs)("div",{className:_()([N().indexer,N().borderBottom]),children:[(0,r.jsx)("div",{className:N().title29,children:"INDEXER"}),(0,r.jsx)(ee.ZP,{container:!0,spacing:2,children:null==n?void 0:n.indexer.map(e=>(0,r.jsx)(ee.ZP,{item:!0,xs:12,sm:6,md:4,children:(0,r.jsxs)(en.Z,{className:_()([N().indexBlock,e.delayed&&N().delayed]),sx:{marginBottom:4,borderRadius:"8px",position:"relative"},children:[(0,r.jsx)("h5",{children:e.network}),(0,r.jsxs)("div",{children:["ChainID: ",e.chainId]}),(0,r.jsxs)("div",{children:["BLOCK: ",e.block]})]},e.block)},e.block))}),(0,r.jsx)(IndexQueue,{})]})}function AdminAccounts(){let{allAdmins:e}=(0,f.O)();return(0,r.jsxs)("div",{className:N().indexer,children:[(0,r.jsx)("div",{className:N().title29,children:"Admin Accounts"}),(0,r.jsx)("div",{className:N().provider,children:e.map((e,n)=>(0,r.jsx)("div",{className:N().providerRow,children:e},n))})]})}function NodePlatform(e){let{platformData:n}=e;return(0,r.jsxs)("div",{className:N().indexer,children:[(0,r.jsx)("div",{className:N().title29,children:"PLATFORM"}),(0,r.jsx)("div",{className:N().provider,children:n.map(e=>(0,r.jsxs)("div",{className:N().providerRow,children:[(0,r.jsx)("div",{className:N().providerTitle,children:(0,r.jsxs)("b",{children:[e.key,":"]})}),(0,r.jsxs)("div",{children:[e.value," "]})]},e.value))})]})}function Dashboard(){let[e,n]=(0,v.useState)(),[t,s]=(0,v.useState)(!0),[a,i]=(0,v.useState)(""),{setAllAdmins:o,setNetworks:l}=(0,f.O)();(0,v.useEffect)(()=>{s(!0);try{fetch("/directCommand",{headers:{Accept:"application/json","Content-Type":"application/json"},method:"POST",body:JSON.stringify({command:"status"})}).then(e=>e.json()).then(e=>{n(e),o(e.allowedAdmins),l(e.indexer),s(!1)})}catch(e){s(!1),console.error("error",e)}},[]),(0,v.useEffect)(()=>{fetch("https://api.ipify.org?format=json").then(e=>e.json()).then(e=>{i(e.ip)}).catch(e=>{console.error("Failed to fetch IP address:",e)})},[]);let d=[{id:null==e?void 0:e.id,ip:a,indexerData:null==e?void 0:e.indexer}],c=[];return e&&Object.keys(null==e?void 0:e.platform).forEach(n=>{let t={key:n,value:JSON.stringify(null==e?void 0:e.platform[n])};c.push(t)}),(0,r.jsxs)("div",{className:N().root,children:[(0,r.jsx)(AdminActions,{}),(0,r.jsx)("div",{className:N().bodyContainer,children:t?(0,r.jsx)("div",{className:N().loaderContainer,children:(0,r.jsx)(Spinner,{})}):(0,r.jsxs)("div",{className:N().body,children:[(0,r.jsx)(()=>(0,r.jsxs)("div",{children:[(0,r.jsx)("div",{className:N().title29,children:"NETWORK"}),(0,r.jsx)("div",{className:N().details,children:(0,r.jsxs)("div",{className:N().details,children:[(0,r.jsxs)("div",{className:N().columnP2P,children:[(0,r.jsxs)("div",{className:_()([N().title24,N().borderBottom]),children:["P2P - ",(null==e?void 0:e.p2p)?"UP":"DOWN"]}),(0,r.jsxs)("div",{className:N().nodes,children:[(0,r.jsx)("div",{className:N().title24,children:"NODE ID"}),d.map(e=>(0,r.jsxs)("div",{className:N().node,children:[(0,r.jsx)("div",{className:N().nodeAddress,children:(0,r.jsx)("div",{className:N().node,children:truncateString(e.id,12)})}),(0,r.jsx)(Copy,{text:null==e?void 0:e.id})]},e.id))]}),(0,r.jsxs)("div",{className:N().nodes,children:[(0,r.jsx)("div",{className:N().title24,children:"Address"}),(0,r.jsxs)("div",{className:N().node,children:[truncateString(null==e?void 0:e.address,12),(0,r.jsx)(Copy,{text:null==e?void 0:e.address})]})]}),(0,r.jsx)(NodePeers,{})]}),(0,r.jsxs)("div",{className:N().columnHTTP,children:[(0,r.jsxs)("div",{className:_()([N().title24,N().borderBottom]),children:["HTTP - ",(null==e?void 0:e.http)?"UP":"DOWN"]}),(0,r.jsx)("div",{className:N().nodes,children:(0,r.jsxs)("div",{className:N().nodeAddress,children:[(0,r.jsx)("h5",{className:N().title24,children:"IP : "}),(0,r.jsx)("div",{className:N().nodeAddress,children:a}),(0,r.jsx)(Copy,{text:a})]})})]})]})})]}),{}),(0,r.jsx)(Indexer,{data:e}),(0,r.jsx)(SupportedNetworks_SupportedStorage,{data:e}),(0,r.jsx)(SupportedStorage,{data:e}),(0,r.jsx)(AdminAccounts,{}),(0,r.jsx)(NodePlatform,{platformData:c})]})})]})}function Home(){return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(o(),{children:[(0,r.jsx)("title",{children:"Ocean nodes"}),(0,r.jsx)("meta",{name:"description",content:"Ocean nodes dashboard"}),(0,r.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1"}),(0,r.jsx)("link",{rel:"icon",href:"/favicon.ico"})]}),(0,r.jsx)("header",{children:(0,r.jsx)(Navigation,{})}),(0,r.jsx)("main",{children:(0,r.jsx)(Dashboard,{})}),(0,r.jsx)("footer",{children:(0,r.jsx)(components_Footer,{})})]})}},46085:function(e){e.exports={download:"Admin_download__ZZ4G0",unlockButton:"Admin_unlockButton__ke4Fn",buttonIcon:"Admin_buttonIcon___M4VS",loader:"Admin_loader__3WuLo",rotation:"Admin_rotation__lknWO",rotationBack:"Admin_rotationBack__qlWG_",root:"Admin_root__Q70by",title:"Admin_title__Xr7QQ",unauthorised:"Admin_unauthorised__6u5Bb"}},75368:function(e){e.exports={icon:"Copy_icon__BB7bs",feedback:"Copy_feedback__Wse_F",action:"Copy_action__IlKRq",button:"Copy_button__zsJoM"}},11706:function(e){e.exports={root:"Dashboard_root__SCu4R",bodyContainer:"Dashboard_bodyContainer__Fs5NF",body:"Dashboard_body__kpkou",details:"Dashboard_details__TI_cX",columnP2P:"Dashboard_columnP2P__0zKqU",columnHTTP:"Dashboard_columnHTTP__lhw_5",nodes:"Dashboard_nodes__7r0Ge",indexerQueueAlert:"Dashboard_indexerQueueAlert__iCMHE",borderBottom:"Dashboard_borderBottom__5pTDi",title29:"Dashboard_title29__TBf_2",title24:"Dashboard_title24__q5w52",nodeAddress:"Dashboard_nodeAddress__jgxgu",node:"Dashboard_node__UCu0_",indexer:"Dashboard_indexer__PpMWp",indexBlock:"Dashboard_indexBlock__Ng0C_",delayed:"Dashboard_delayed__3Tj7O",provider:"Dashboard_provider__wMZ4i",providerRow:"Dashboard_providerRow__k2QJ8",providerTitle:"Dashboard_providerTitle__5DXbm",loaderContainer:"Dashboard_loaderContainer__CAGjT",loader:"Dashboard_loader__p4KHC",rotation:"Dashboard_rotation__RIDl3"}},94428:function(e){e.exports={footerContainer:"style_footerContainer___mKsH",footerLinks:"style_footerLinks__1vBvO"}},30378:function(e){e.exports={navbarParent:"style_navbarParent__OgqE_",logoWrapper:"style_logoWrapper__ARfWA",connectButtonWrapper:"style_connectButtonWrapper__G4TF7"}},85108:function(e){e.exports={title24:"style_title24__8ssRQ",loaderContainer:"style_loaderContainer__dYPch",nodes:"style_nodes__ioZOx",nodeAddress:"style_nodeAddress__t2M8E"}},17044:function(e){e.exports={loader:"style_loader__s3fCW",rotation:"style_rotation__wALkg"}}},function(e){e.O(0,[2477,9774,2888,179],function(){return e(e.s=48312)}),_N_E=e.O()}]);
\ No newline at end of file
diff --git a/dist/dashboard/index.html b/dist/dashboard/index.html
index 477c3669f..efde4414f 100644
--- a/dist/dashboard/index.html
+++ b/dist/dashboard/index.html
@@ -1 +1 @@
-Ocean nodes
ADMIN ACTIONS
\ No newline at end of file
+Ocean nodes
ADMIN ACTIONS
diff --git a/docs/API.md b/docs/API.md
index 60c006bd1..968cd1070 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -404,32 +404,6 @@ returns list of logs
---
-## Broadcast Command
-
-### `HTTP` POST /broadcastCommand
-
-#### Description
-
-returns an empty if command is valid
-
-#### Parameters
-
-| name | type | required | description |
-| ------- | ------ | -------- | ---------------------------- |
-| command | string | v | command name |
-| ... | any | | any other command parameters |
-
-#### Request
-
-```json
-{
- "command": "echo",
- "...": "..."
-}
-```
-
----
-
## Advertise Did
### `HTTP` GET /advertiseDid/?did=did:op:123"
diff --git a/docs/env.md b/docs/env.md
index 363b94fc5..5f67034b1 100644
--- a/docs/env.md
+++ b/docs/env.md
@@ -50,17 +50,17 @@ Environmental variables are also tracked in `ENVIRONMENT_VARIABLES` within `src/
- `P2P_ipV6BindWsPort`: Port used on IPv6 WS connections. Defaults to `0` (Use whatever port is free. When running as docker, please set it explicitly). Example: `0`
- `P2P_ANNOUNCE_ADDRESSES`: List of addresses to announce to the network. Example: `"[\"/ip4/1.2.3.4/tcp/8000\"]"`
- `P2P_ANNOUNCE_PRIVATE`: Announce private IPs. Default: `True`
-- `P2P_pubsubPeerDiscoveryInterval`: Interval (in ms) for discovery using pubsub. Defaults to `3000` (three seconds). Example: `3000`
+- `P2P_pubsubPeerDiscoveryInterval`: Interval (in ms) for discovery using pubsub. Defaults to `10000` (three seconds). Example: `10000`
- `P2P_dhtMaxInboundStreams`: Maximum number of DHT inbound streams. Defaults to `500`. Example: `500`
- `P2P_dhtMaxOutboundStreams`: Maximum number of DHT outbound streams. Defaults to `500`. Example: `500`
+- `P2P_ENABLE_DHT_SERVER`: Enable DHT server mode. This should be enabled for bootstrapers & well established nodes. Default: `false`
- `P2P_mDNSInterval`: Interval (in ms) for discovery using mDNS. Defaults to `20000` (20 seconds). Example: `20000`
- `P2P_connectionsMaxParallelDials`: Maximum number of parallel dials. Defaults to `150`. Example: `150`
- `P2P_connectionsDialTimeout`: Timeout for dial commands. Defaults to `10000` (10 seconds). Example: `10000`
- `P2P_ENABLE_UPNP`: Enable UPNP gateway discovery. Default: `True`
- `P2P_ENABLE_AUTONAT`: Enable AutoNAT discovery. Default: `True`
- `P2P_ENABLE_CIRCUIT_RELAY_SERVER`: Enable Circuit Relay Server. It will help the network but increase your bandwidth usage. Should be disabled for edge nodes. Default: `True`
-- `P2P_ENABLE_CIRCUIT_RELAY_CLIENT`: Enable connections through relay servers. Default: `True`
-- `P2P_CIRCUIT_RELAYS`: Numbers of relay servers. Default: `1`
+- `P2P_CIRCUIT_RELAYS`: Numbers of relay servers. Default: `0`
- `P2P_BOOTSTRAP_NODES` : List of bootstrap nodes. Defults to OPF nodes. Example: ["/dns4/node3.oceanprotocol.com/tcp/9000/p2p/"]
- `P2P_FILTER_ANNOUNCED_ADDRESSES`: CIDR filters to filter announced addresses. Default: ["172.15.0.0/24"] (docker ip range). Example: ["192.168.0.1/27"]
- `P2P_MIN_CONNECTIONS`: The minimum number of connections below which libp2p will start to dial peers from the peer book. Setting this to 0 disables this behaviour. Default: 1
diff --git a/package-lock.json b/package-lock.json
index 2c8007b9f..286817a2b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "ocean-node",
- "version": "0.0.6",
+ "version": "0.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ocean-node",
- "version": "0.0.6",
+ "version": "0.1.0",
"license": "Apache-2.0",
"dependencies": {
"@chainsafe/libp2p-gossipsub": "^13.1.0",
diff --git a/package.json b/package.json
index 2f1d44455..49d194d01 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "ocean-node",
- "version": "0.0.6",
+ "version": "0.1.0",
"description": "Ocean Node is used to run all core services in the Ocean stack",
"author": "Ocean Protocol Foundation",
"license": "Apache-2.0",
diff --git a/scripts/dashboard.hash b/scripts/dashboard.hash
index 7ac741f00..8fef61f6a 100644
--- a/scripts/dashboard.hash
+++ b/scripts/dashboard.hash
@@ -1 +1 @@
-f33f1291f270efe8b0d53a541674225f73062aecaa9b1e97a304e124e13731b4
\ No newline at end of file
+c870a78421b1c4c5c9870fa7bec7947f64cb8574f166211814487c34be6cce34
diff --git a/src/@types/OceanNode.ts b/src/@types/OceanNode.ts
index 67ec48159..0109262df 100644
--- a/src/@types/OceanNode.ts
+++ b/src/@types/OceanNode.ts
@@ -34,6 +34,7 @@ export interface OceanNodeP2PConfig {
pubsubPeerDiscoveryInterval: number
dhtMaxInboundStreams: number
dhtMaxOutboundStreams: number
+ enableDHTServer: boolean
mDNSInterval: number
connectionsMaxParallelDials: number
connectionsDialTimeout: number
@@ -124,12 +125,6 @@ export interface OceanNodeStatus {
supportedSchemas?: Schema[]
}
-export interface P2PBroadcastResponse {
- command: string // original broadcast command
- message: any // original broadcast message
- response: any // the actual response to the original command and message
-}
-
export interface FindDDOResponse {
provider: string
id: string
diff --git a/src/@types/commands.ts b/src/@types/commands.ts
index 6384f0494..03f95de2c 100644
--- a/src/@types/commands.ts
+++ b/src/@types/commands.ts
@@ -137,11 +137,6 @@ export interface ICommandHandler {
validate(command: Command): ValidateParams
}
-export interface BroadcastCommand {
- command: string // the name of the command
- message: any // the message to broadcast
-}
-
export interface ComputeGetEnvironmentsCommand extends Command {
chainId?: number
}
diff --git a/src/components/P2P/handleBroadcasts.ts b/src/components/P2P/handleBroadcasts.ts
deleted file mode 100644
index 80a7872c8..000000000
--- a/src/components/P2P/handleBroadcasts.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { BroadcastCommand } from '../../@types/commands.js'
-import { LOG_LEVELS_STR, getLoggerLevelEmoji } from '../../utils/logging/Logger.js'
-import { P2P_LOGGER } from '../../utils/logging/common.js'
-
-export function handleBroadcasts(topic: string, _message: any) {
- // can only register one handler for the protocol
-
- if (_message.detail.topic === topic) {
- // 'broadcast from ', _message.detail.from
- P2P_LOGGER.logMessage('Received broadcast msg... ', true)
- const rawMessage = new TextDecoder('utf8').decode(_message.detail.data)
- P2P_LOGGER.logMessageWithEmoji(
- `Decoded broadcast: ${rawMessage}`,
- true,
- getLoggerLevelEmoji(LOG_LEVELS_STR.LEVEL_INFO),
- LOG_LEVELS_STR.LEVEL_INFO
- )
-
- const command: BroadcastCommand = JSON.parse(rawMessage) as BroadcastCommand
-
- P2P_LOGGER.log(
- LOG_LEVELS_STR.LEVEL_WARN,
- `Broadcast command "${command.command}" not implemented yet!`,
- true
- )
- } else {
- // console.log('Got some relays...', message.detail)
- }
-}
diff --git a/src/components/P2P/handlers.ts b/src/components/P2P/handlers.ts
index e4dde59cd..d6e0b86e1 100644
--- a/src/components/P2P/handlers.ts
+++ b/src/components/P2P/handlers.ts
@@ -1,2 +1 @@
-export * from './handleBroadcasts.js'
export * from './handleProtocolCommands.js'
diff --git a/src/components/P2P/index.ts b/src/components/P2P/index.ts
index 9a025e91e..c0b82ce56 100644
--- a/src/components/P2P/index.ts
+++ b/src/components/P2P/index.ts
@@ -4,7 +4,6 @@ import EventEmitter from 'node:events'
import clone from 'lodash.clonedeep'
import {
- handleBroadcasts,
// handlePeerConnect,
// handlePeerDiscovery,
// handlePeerDisconnect,
@@ -19,7 +18,7 @@ import { mdns } from '@libp2p/mdns'
import { yamux } from '@chainsafe/libp2p-yamux'
import { peerIdFromString } from '@libp2p/peer-id'
import { pipe } from 'it-pipe'
-import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
+// import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
import { tcp } from '@libp2p/tcp'
import { webSockets } from '@libp2p/websockets'
@@ -30,8 +29,8 @@ import { autoNAT } from '@libp2p/autonat'
import { uPnPNAT } from '@libp2p/upnp-nat'
import { ping } from '@libp2p/ping'
import { dcutr } from '@libp2p/dcutr'
-import { kadDHT } from '@libp2p/kad-dht'
-import { gossipsub } from '@chainsafe/libp2p-gossipsub'
+import { kadDHT, passthroughMapper } from '@libp2p/kad-dht'
+// import { gossipsub } from '@chainsafe/libp2p-gossipsub'
import { EVENTS, cidFromRawString } from '../../utils/index.js'
import { Transform } from 'stream'
@@ -40,15 +39,11 @@ import { OceanNodeConfig, FindDDOResponse } from '../../@types/OceanNode'
// eslint-disable-next-line camelcase
import is_ip_private from 'private-ip'
import ip from 'ip'
-import {
- GENERIC_EMOJIS,
- LOG_LEVELS_STR,
- getLoggerLevelEmoji
-} from '../../utils/logging/Logger.js'
+import { GENERIC_EMOJIS, LOG_LEVELS_STR } from '../../utils/logging/Logger.js'
import { INDEXER_DDO_EVENT_EMITTER } from '../Indexer/index.js'
import { P2P_LOGGER } from '../../utils/logging/common.js'
import { CoreHandlersRegistry } from '../core/handler/coreHandlersRegistry'
-import { multiaddr } from '@multiformats/multiaddr'
+import { type Multiaddr, multiaddr } from '@multiformats/multiaddr'
// import { getIPv4, getIPv6 } from '../../utils/ip.js'
const DEFAULT_OPTIONS = {
@@ -119,9 +114,10 @@ export class OceanP2P extends EventEmitter {
this._libp2p.addEventListener('peer:disconnect', (evt: any) => {
this.handlePeerDisconnect(evt)
})
- this._libp2p.addEventListener('peer:discovery', (evt: any) => {
- this.handlePeerDiscovery(evt)
+ this._libp2p.addEventListener('peer:discovery', (details: any) => {
+ this.handlePeerDiscovery(details)
})
+
this._options = Object.assign({}, clone(DEFAULT_OPTIONS), clone(options))
this._peers = []
this._connections = {}
@@ -161,9 +157,22 @@ export class OceanP2P extends EventEmitter {
P2P_LOGGER.debug('Connection closed to:' + peerId.toString()) // Emitted when a peer has been found
}
- handlePeerDiscovery(details: any) {
- const peerInfo = details.detail
- P2P_LOGGER.debug('Discovered new peer:' + peerInfo.id.toString())
+ async handlePeerDiscovery(details: any) {
+ try {
+ const peerInfo = details.detail
+ P2P_LOGGER.debug('Discovered new peer:' + peerInfo.id.toString())
+ if (peerInfo.multiaddrs) {
+ await this._libp2p.peerStore.save(peerInfo.id, {
+ multiaddrs: peerInfo.multiaddrs
+ })
+ await this._libp2p.peerStore.patch(peerInfo.id, {
+ multiaddrs: peerInfo.multiaddrs
+ })
+ }
+ } catch (e) {
+ // no panic if it failed
+ // console.error(e)
+ }
}
handlePeerJoined(details: any) {
@@ -233,13 +242,59 @@ export class OceanP2P extends EventEmitter {
this._privateKey = config.keys.privateKey
/** @type {import('libp2p').Libp2pOptions} */
// start with some default, overwrite based on config later
+ const bindInterfaces = []
+ if (config.p2pConfig.enableIPV4) {
+ P2P_LOGGER.info('Binding P2P sockets to IPV4')
+ bindInterfaces.push(
+ `/ip4/${config.p2pConfig.ipV4BindAddress}/tcp/${config.p2pConfig.ipV4BindTcpPort}`
+ )
+ bindInterfaces.push(
+ `/ip4/${config.p2pConfig.ipV4BindAddress}/tcp/${config.p2pConfig.ipV4BindWsPort}/ws`
+ )
+ }
+ if (config.p2pConfig.enableIPV6) {
+ P2P_LOGGER.info('Binding P2P sockets to IPV6')
+ bindInterfaces.push(
+ `/ip6/${config.p2pConfig.ipV6BindAddress}/tcp/${config.p2pConfig.ipV6BindTcpPort}`
+ )
+ bindInterfaces.push(
+ `/ip6/${config.p2pConfig.ipV6BindAddress}/tcp/${config.p2pConfig.ipV6BindWsPort}/ws`
+ )
+ }
+ let addresses = {}
+ if (
+ config.p2pConfig.announceAddresses &&
+ config.p2pConfig.announceAddresses.length > 0
+ ) {
+ addresses = {
+ listen: bindInterfaces,
+ announceFilter: (multiaddrs: any[]) =>
+ multiaddrs.filter((m) => this.shouldAnnounce(m)),
+ announce: config.p2pConfig.announceAddresses
+ }
+ } else {
+ addresses = {
+ listen: bindInterfaces,
+ announceFilter: (multiaddrs: any[]) =>
+ multiaddrs.filter((m) => this.shouldAnnounce(m))
+ }
+ }
let servicesConfig = {
identify: identify(),
+ /*
pubsub: gossipsub({
- allowPublishToZeroTopicPeers: true
+ fallbackToFloodsub: false,
+ batchPublish: false,
+ allowPublishToZeroTopicPeers: true,
+ asyncValidation: false,
+ // messageProcessingConcurrency: 5,
+ seenTTL: 10 * 1000,
+ runOnTransientConnection: true,
+ doPX: doPx,
// canRelayMessage: true,
// enabled: true
- }),
+ allowedTopics: ['oceanprotocol._peer-discovery._p2p._pubsub', 'oceanprotocol']
+ }), */
dht: kadDHT({
// this is necessary because this node is not connected to the public network
// it can be removed if, for example bootstrappers are configured
@@ -247,9 +302,10 @@ export class OceanP2P extends EventEmitter {
maxInboundStreams: config.p2pConfig.dhtMaxInboundStreams,
maxOutboundStreams: config.p2pConfig.dhtMaxOutboundStreams,
- clientMode: false, // this should be true for edge devices
+ clientMode: false,
kBucketSize: 20,
- protocol: '/ocean/nodes/1.0.0/kad/1.0.0'
+ protocol: '/ocean/nodes/1.0.0/kad/1.0.0',
+ peerInfoMapper: passthroughMapper
// protocolPrefix: '/ocean/nodes/1.0.0'
// randomWalk: {
// enabled: true, // Allows to disable discovery (enabled by default)
@@ -278,58 +334,17 @@ export class OceanP2P extends EventEmitter {
...{ autoNAT: autoNAT({ maxInboundStreams: 20, maxOutboundStreams: 20 }) }
}
}
- const bindInterfaces = []
- if (config.p2pConfig.enableIPV4) {
- P2P_LOGGER.info('Binding P2P sockets to IPV4')
- bindInterfaces.push(
- `/ip4/${config.p2pConfig.ipV4BindAddress}/tcp/${config.p2pConfig.ipV4BindTcpPort}`
- )
- bindInterfaces.push(
- `/ip4/${config.p2pConfig.ipV4BindAddress}/tcp/${config.p2pConfig.ipV4BindWsPort}/ws`
- )
- }
- if (config.p2pConfig.enableIPV6) {
- P2P_LOGGER.info('Binding P2P sockets to IPV6')
- bindInterfaces.push(
- `/ip6/${config.p2pConfig.ipV6BindAddress}/tcp/${config.p2pConfig.ipV6BindTcpPort}`
- )
- bindInterfaces.push(
- `/ip6/${config.p2pConfig.ipV6BindAddress}/tcp/${config.p2pConfig.ipV6BindWsPort}/ws`
- )
- }
+
let transports = []
- if (config.p2pConfig.enableCircuitRelayClient) {
- P2P_LOGGER.info('Enabling P2P Transports: websockets, tcp, circuitRelay')
- transports = [
- webSockets(),
- tcp(),
- circuitRelayTransport({
- discoverRelays: config.p2pConfig.circuitRelays
- })
- ]
- } else {
- P2P_LOGGER.info('Enabling P2P Transports: websockets, tcp')
- transports = [webSockets(), tcp()]
- }
+ P2P_LOGGER.info('Enabling P2P Transports: websockets, tcp, circuitRelay')
+ transports = [
+ webSockets(),
+ tcp(),
+ circuitRelayTransport({
+ discoverRelays: config.p2pConfig.circuitRelays
+ })
+ ]
- let addresses = {}
- if (
- config.p2pConfig.announceAddresses &&
- config.p2pConfig.announceAddresses.length > 0
- ) {
- addresses = {
- listen: bindInterfaces,
- announceFilter: (multiaddrs: any[]) =>
- multiaddrs.filter((m) => this.shouldAnnounce(m)),
- announce: config.p2pConfig.announceAddresses
- }
- } else {
- addresses = {
- listen: bindInterfaces,
- announceFilter: (multiaddrs: any[]) =>
- multiaddrs.filter((m) => this.shouldAnnounce(m))
- }
- }
let options = {
addresses,
peerId: config.keys.peerId,
@@ -365,7 +380,7 @@ export class OceanP2P extends EventEmitter {
}),
mdns({
interval: config.p2pConfig.mDNSInterval
- }),
+ }) /*,
pubsubPeerDiscovery({
interval: config.p2pConfig.pubsubPeerDiscoveryInterval,
topics: [
@@ -374,7 +389,7 @@ export class OceanP2P extends EventEmitter {
// '_peer-discovery._p2p._pubsub' // Include if you want to participate in the global space
],
listenOnly: false
- })
+ }) */
]
}
}
@@ -386,7 +401,7 @@ export class OceanP2P extends EventEmitter {
peerDiscovery: [
mdns({
interval: config.p2pConfig.mDNSInterval
- }),
+ }) /*,
pubsubPeerDiscovery({
interval: config.p2pConfig.pubsubPeerDiscoveryInterval,
topics: [
@@ -395,7 +410,7 @@ export class OceanP2P extends EventEmitter {
// '_peer-discovery._p2p._pubsub' // Include if you want to participate in the global space
],
listenOnly: false
- })
+ }) */
]
}
}
@@ -403,34 +418,18 @@ export class OceanP2P extends EventEmitter {
const node = await createLibp2p(options)
await node.start()
- // node.services.pubsub.addEventListener( 'peer joined', (evt:any) => {handlePeerJoined(evt)})
- // node.services.pubsub.addEventListener('peer left', (evt:any) => {handlePeerLeft(evt)})
- // node.services.pubsub.addEventListener('subscription-change', (evt:any) => { handleSubscriptionCHange(evt)})
-
- // this._libp2p.services.pubsub.on('peer joined', (peer:any) => {
- // console.log('New peer joined us:', peer)
- // })
- // this._libp2p.services.pubsub.addEventListener('peer left', (evt:any) => {
- // console.log('Peer left...', evt)
- // })
- // this._libp2p.services.pubsub.on('peer left', (peer:any) => {
- // console.log('Peer left...', peer)
- // })
- node.services.pubsub.addEventListener('message', (message: any) => {
- handleBroadcasts(this._topic, message)
- })
- // this._libp2p.services.pubsub.on('message', (message:any) => {
- // console.log('Received broadcast msg...', message)
- // console.log("Sending back 'who are you' to "+message.from.toString())
- // this.sendTo(message.from,'Who are you?',null)
- // })
- node.services.pubsub.subscribe(this._topic)
- node.services.pubsub.publish(this._topic, encoding('online'))
-
const upnpService = (node.services as any).upnpNAT
if (config.p2pConfig.upnp && upnpService) {
this._upnp_interval = setInterval(this.UPnpCron.bind(this), 3000)
}
+
+ if (config.p2pConfig.enableDHTServer) {
+ try {
+ await node.services.dht.setMode('server')
+ } catch (e) {
+ P2P_LOGGER.warn(`Failed to set mode server for DHT`)
+ }
+ }
return node
} catch (e) {
P2P_LOGGER.logMessageWithEmoji(
@@ -475,24 +474,24 @@ export class OceanP2P extends EventEmitter {
async getOceanPeers(running: boolean = true, known: boolean = true) {
const peers: string[] = []
- if (running) {
+ /* if (running) {
// get pubsub peers
const node = this._libp2p
const newPeers = (await node.services.pubsub.getSubscribers(this._topic)).sort()
for (const peer of newPeers.slice(0)) {
if (!peers.includes(peer.toString)) peers.push(peer.toString())
}
- }
+ } */
if (known) {
// get p2p peers and filter them by protocol
for (const peer of await this._libp2p.peerStore.all()) {
- if (peer && peer.protocols) {
- for (const protocol of peer.protocols) {
- if (protocol === this._protocol) {
- if (!peers.includes(peer.id.toString())) peers.push(peer.id.toString())
- }
- }
- }
+ // if (peer && peer.protocols) {
+ // for (const protocol of peer.protocols) {
+ // if (protocol === this._protocol) {
+ if (!peers.includes(peer.id.toString())) peers.push(peer.id.toString())
+ // }
+ // }
+ // }
}
}
@@ -504,18 +503,6 @@ export class OceanP2P extends EventEmitter {
return Boolean(s.find((p: any) => p.toString() === peer.toString()))
}
- async broadcast(_message: any) {
- P2P_LOGGER.logMessage('Broadcasting:', true)
- P2P_LOGGER.logMessageWithEmoji(
- _message,
- true,
- getLoggerLevelEmoji(LOG_LEVELS_STR.LEVEL_INFO),
- LOG_LEVELS_STR.LEVEL_INFO
- )
- const message = encoding(_message)
- await this._libp2p.services.pubsub.publish(this._topic, message)
- }
-
async getPeerDetails(peerName: string) {
try {
const peerId = peerIdFromString(peerName)
@@ -545,6 +532,75 @@ export class OceanP2P extends EventEmitter {
}
}
+ async getPeerMultiaddrs(
+ peerName: string,
+ searchPeerStore: boolean = true,
+ searchDHT: boolean = true
+ ): Promise {
+ const multiaddrs: Multiaddr[] = []
+ let peerId
+ try {
+ peerId = peerIdFromString(peerName)
+ } catch (e) {
+ return []
+ }
+ if (searchPeerStore) {
+ // search peerStore
+ try {
+ const peerData = await this._libp2p.peerStore.get(peerId, {
+ signal: AbortSignal.timeout(3000)
+ })
+ if (peerData) {
+ for (const x of peerData.addresses) {
+ multiaddrs.push(x.multiaddr)
+ }
+ }
+ } catch (e) {
+ // console.log(e)
+ }
+ }
+ if (searchDHT) {
+ try {
+ const peerData = await this._libp2p.peerRouting.findPeer(peerId, {
+ signal: AbortSignal.timeout(3000),
+ useCache: false
+ })
+ if (peerData) {
+ for (const index in peerData.multiaddrs) {
+ multiaddrs.push(peerData.multiaddrs[index])
+ }
+ }
+ } catch (e) {
+ // console.log(e)
+ }
+ }
+
+ // now we should have peer multiaddrs
+ // but there is a catch
+ // when dialing multiaddrs, either all of them have peerId, or none..
+ // so decide which one to use
+ let finalmultiaddrs: Multiaddr[] = []
+ const finalmultiaddrsWithAddress: Multiaddr[] = []
+ const finalmultiaddrsWithoutAddress: Multiaddr[] = []
+ for (const x of multiaddrs) {
+ if (x.toString().includes(peerName)) finalmultiaddrsWithAddress.push(x)
+ else {
+ let sd = x.toString()
+ if (x.toString().includes('p2p-circuit')) {
+ // because a p2p-circuit should always include peerId, if it's missing we will add it
+ sd = sd + '/p2p/' + peerName
+ finalmultiaddrsWithAddress.push(multiaddr(sd))
+ } else {
+ finalmultiaddrsWithoutAddress.push(multiaddr(sd))
+ }
+ }
+ }
+ if (finalmultiaddrsWithAddress.length > finalmultiaddrsWithoutAddress.length)
+ finalmultiaddrs = finalmultiaddrsWithAddress
+ else finalmultiaddrs = finalmultiaddrsWithoutAddress
+ return finalmultiaddrs
+ }
+
async sendTo(
peerName: string,
message: string,
@@ -559,7 +615,6 @@ export class OceanP2P extends EventEmitter {
let peerId: any
try {
peerId = peerIdFromString(peerName)
- await this._libp2p.peerStore.get(peerId)
} catch (e) {
P2P_LOGGER.logMessageWithEmoji(
'Invalid peer (for id): ' + peerId,
@@ -571,15 +626,26 @@ export class OceanP2P extends EventEmitter {
response.status.error = 'Invalid peer'
return response
}
+ const multiaddrs: Multiaddr[] = await this.getPeerMultiaddrs(peerName)
+ if (multiaddrs.length < 1) {
+ response.status.httpStatus = 404
+ response.status.error = `Cannot find any address to dial for peer: ${peerId}`
+ P2P_LOGGER.error(response.status.error)
+ return response
+ }
let stream
// dial/connect to the target node
try {
- stream = await this._libp2p.dialProtocol(peerId, this._protocol)
+ stream = await this._libp2p.dialProtocol(multiaddrs, this._protocol, {
+ signal: AbortSignal.timeout(3000),
+ priority: 100,
+ runOnTransientConnection: true
+ })
} catch (e) {
response.status.httpStatus = 404
- response.status.error = 'Cannot connect to peer'
- P2P_LOGGER.error(`Unable to connect to peer: ${peerId}`)
+ response.status.error = `Cannot connect to peer: ${peerId}`
+ P2P_LOGGER.error(response.status.error)
return response
}
@@ -920,11 +986,3 @@ export class OceanP2P extends EventEmitter {
this._upnp_interval = setInterval(this.UPnpCron.bind(this), 3000)
}
}
-
-function encoding(message: any) {
- if (!(message instanceof Uint8Array)) {
- return uint8ArrayFromString(message)
- }
-
- return message
-}
diff --git a/src/components/httpRoutes/commands.ts b/src/components/httpRoutes/commands.ts
index b8b395e05..49ca7558e 100644
--- a/src/components/httpRoutes/commands.ts
+++ b/src/components/httpRoutes/commands.ts
@@ -3,35 +3,10 @@ import express, { Request, Response } from 'express'
import { P2PCommandResponse } from '../../@types'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
-import { getDefaultLevel } from '../../utils/logging/Logger.js'
-
import { HTTP_LOGGER } from '../../utils/logging/common.js'
-import { hasP2PInterface, sendMissingP2PResponse } from './index.js'
+import { hasP2PInterface } from './index.js'
import { validateCommandParameters } from './validateCommands.js'
-export const broadcastCommandRoute = express.Router()
-
-broadcastCommandRoute.post(
- '/broadcastCommand',
- express.json(),
- async (req: Request, res: Response): Promise => {
- const validate = validateCommandParameters(req.body, [])
- if (!validate.valid) {
- res.status(validate.status).send(validate.reason)
- return
- }
-
- HTTP_LOGGER.log(getDefaultLevel(), `broadcastCommand received ${req.body}`, true)
-
- if (hasP2PInterface) {
- await req.oceanNode.getP2PNode().broadcast(JSON.stringify(req.body))
- res.sendStatus(200)
- } else {
- sendMissingP2PResponse(res)
- }
- }
-)
-
export const directCommandRoute = express.Router()
directCommandRoute.post(
'/directCommand',
diff --git a/src/components/httpRoutes/index.ts b/src/components/httpRoutes/index.ts
index aa4b80d5e..4a4a28b74 100644
--- a/src/components/httpRoutes/index.ts
+++ b/src/components/httpRoutes/index.ts
@@ -1,7 +1,7 @@
import express, { Response } from 'express'
import { getOceanPeersRoute, getP2PPeersRoute, getP2PPeerRoute } from './getOceanPeers.js'
import { advertiseDidRoute, getProvidersForDidRoute } from './dids.js'
-import { broadcastCommandRoute, directCommandRoute } from './commands.js'
+import { directCommandRoute } from './commands.js'
import { logRoutes } from './logs.js'
import { providerRoutes } from './provider.js'
import { aquariusRoutes } from './aquarius.js'
@@ -34,8 +34,6 @@ httpRoutes.use(getP2PPeerRoute)
httpRoutes.use(advertiseDidRoute)
// /getProvidersForDid
httpRoutes.use(getProvidersForDidRoute)
-// /broadcastCommand
-httpRoutes.use(broadcastCommandRoute)
// /directCommand
httpRoutes.use(directCommandRoute)
// /logs
diff --git a/src/components/httpRoutes/routeUtils.ts b/src/components/httpRoutes/routeUtils.ts
index f72c0e578..4843f5d0e 100644
--- a/src/components/httpRoutes/routeUtils.ts
+++ b/src/components/httpRoutes/routeUtils.ts
@@ -92,10 +92,6 @@ routesNames.set('directCommand', {
method: 'post'
})
-routesNames.set('broadcastCommand', {
- path: '/broadcastCommand',
- method: 'post'
-})
// fileInfo
routesNames.set('fileInfo', {
path: `${SERVICES_API_BASE_PATH}/fileInfo`,
diff --git a/src/components/httpRoutes/validateCommands.ts b/src/components/httpRoutes/validateCommands.ts
index f36e5dfcb..49850f496 100644
--- a/src/components/httpRoutes/validateCommands.ts
+++ b/src/components/httpRoutes/validateCommands.ts
@@ -10,12 +10,6 @@ export type ValidateParams = {
status?: number
}
-export function validateBroadcastParameters(requestBody: any): ValidateParams {
- // for now we can use the same validation function,
- // but later we might need to have separate validation functions
- // if we many different commands of each type
- return validateCommandParameters(requestBody, [])
-}
// add others when we add suppor
// request level validation, just check if we have a "command" field and its a supported one
diff --git a/src/helpers/scripts/setupNodeEnv.sh b/src/helpers/scripts/setupNodeEnv.sh
index 2e452a28d..e3727f7b8 100755
--- a/src/helpers/scripts/setupNodeEnv.sh
+++ b/src/helpers/scripts/setupNodeEnv.sh
@@ -146,19 +146,6 @@ setup_node_admin_wallet() {
fi
}
-ask_for_same_admin_wallet() {
-
- wallet_file_path=$wallet_file
- if [ -f $wallet_file_path ]; then
- read -p "Do you want to use the wallet associated with this key ( $wallet_file ) as a node admin account? [ y/n ]: " use_admin_wallet
- use_admin_wallet=${use_admin_wallet:-y}
- if [ "$use_admin_wallet" == 'y' ]; then
- ADMIN_WALLET=`cat $wallet_file_path`
- setup_node_admin_wallet
- fi
- fi
-}
-
#check if the private key file exists
if ! [ -f $pk_file_path ]; then
echo "Private Key File does not exist."
@@ -224,20 +211,12 @@ if [ $exists_env_file -eq 0 ]; then
#configure the pk key on the .env file
setup_private_key
#Use wallet address from file? only if we just created it
- if [ $created_pk_file -eq 1 ]; then
- ask_for_same_admin_wallet
- else
- #we entered a pk ourselves
- read -p "Do you want setup the wallet associated with this key, as a node admin account? [ y/n ]: " set_admin_wallet
- set_admin_wallet=${set_admin_wallet:-y}
- if [ "$set_admin_wallet" == 'y' ]; then
- read -p "Enter your admin wallet address: " ADMIN_WALLET
- check_wallet $ADMIN_WALLET
- setup_node_admin_wallet
- fi
- fi
+ read -p "Enter your admin wallet address: " ADMIN_WALLET
+ check_wallet $ADMIN_WALLET
+ setup_node_admin_wallet
+
fi
- else
+ else ``
echo "Creating .env file aborted!"
created_env_file=0
exit 1
diff --git a/src/utils/config.ts b/src/utils/config.ts
index 010a3cff5..3fd9591ca 100644
--- a/src/utils/config.ts
+++ b/src/utils/config.ts
@@ -508,10 +508,11 @@ async function getEnvConfig(isStartup?: boolean): Promise {
),
pubsubPeerDiscoveryInterval: getIntEnvValue(
process.env.P2P_pubsubPeerDiscoveryInterval,
- 3000 // every 3 seconds
+ 10000 // every 10 seconds
),
dhtMaxInboundStreams: getIntEnvValue(process.env.P2P_dhtMaxInboundStreams, 500),
dhtMaxOutboundStreams: getIntEnvValue(process.env.P2P_dhtMaxOutboundStreams, 500),
+ enableDHTServer: getBoolEnvValue(process.env.P2P_ENABLE_DHT_SERVER, false),
mDNSInterval: getIntEnvValue(process.env.P2P_mDNSInterval, 20e3), // 20 seconds
connectionsMaxParallelDials: getIntEnvValue(
process.env.P2P_connectionsMaxParallelDials,
@@ -525,7 +526,7 @@ async function getEnvConfig(isStartup?: boolean): Promise {
autoNat: getBoolEnvValue('P2P_ENABLE_AUTONAT', true),
enableCircuitRelayServer: getBoolEnvValue('P2P_ENABLE_CIRCUIT_RELAY_SERVER', false),
enableCircuitRelayClient: getBoolEnvValue('P2P_ENABLE_CIRCUIT_RELAY_CLIENT', false),
- circuitRelays: getIntEnvValue(process.env.P2P_CIRCUIT_RELAYS, 1),
+ circuitRelays: getIntEnvValue(process.env.P2P_CIRCUIT_RELAYS, 0),
announcePrivateIp: getBoolEnvValue('P2P_ANNOUNCE_PRIVATE', false),
filterAnnouncedAddresses: readListFromEnvVariable(
ENVIRONMENT_VARIABLES.P2P_FILTER_ANNOUNCED_ADDRESSES,