Skip to content

Outbound Gateway

Przemysław Rekucki edited this page Feb 14, 2023 · 43 revisions

Outbound Gateway

Goal

The Outbound Gateway functionality aims to provide the GOLEM network with the service of connecting to hosts on the internet.

Scenarios

UC1. VPN application on user's phone or desktop.

An application that:

  • allows you to rent a node in the golem network to terminate outgoing traffic
  • e.g. by country.
  • connections from the computer instead of directly to the Internet go through the p2p network to a specific node and there as connections from this node.

UC2. Application hosted on a provider with wide access.

When an application needs broad Internet access, it must either be hosted on nodes whose owners have opened wide Internet access, or buy gatweay and connect the container executing on one node with the outbound service on another.

REST API (for VPN case)

Create new network definition

=> POST /net-api/v2/net
=> Content-type: application/json
=>
=> {"ip": "192.168.8.0", "mask": "255.255.255.0","gateway":"192.168.8.7"}
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= {"id":"844bf7eaf8d44050839a6799ef258fb9",
<= "ip":"192.168.8.0/24",
<= "mask":"255.255.255.0",
<= "gateway":"192.168.8.7"}

Setting requestor address

=> POST /net-api/v2/net/844bf7eaf8d44050839a6799ef258fb9/addresses
=> Content-type: application/json
=>
=> {"ip": "192.168.8.12"}
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= null

Create Payment allocation

=> POST /payment-api/v1/allocations
=> Content-type: application/json
=>
=> {"paymentPlatform": "erc20-rinkeby-tglm", "totalAmount": "10", "makeDeposit": false}
<= HTTP/1.1 200 OK
<= content-type: application/json
<= {
<=  "allocationId": "ba126ca0-a98d-4211-9bd7-e213095d1f24",
<=  "address": "0x889ff52ece3d5368051f4f8216650a7843f8926b",
<=  "paymentPlatform": "erc20-rinkeby-tglm",
<=  "totalAmount": "10",
<=  "spentAmount": "0",
<=  "remainingAmount": "10",
<=  "timestamp": "2023-02-13T13:40:16.367Z",
<=  "makeDeposit": false
<= }

Allocation

Name Type Description In Out
allocationId String required
address String address from which the payment will be made optional required
paymentPlatform String network and token used for payment optional required
totalAmount String required required
spentAmount String required
remainingAmount String required
timestamp Date required
timeout Date optional required
makeDeposit Boolean required required

Finding provider on a market

Offer structure

{
  "properties": {
    "golem.com.payment.debit-notes.accept-timeout?": 240,
    "golem.com.payment.platform.erc20-rinkeby-tglm.address": "0x82251cbb5b1d882a7b3c8b7f5581212143a68505",
    "golem.com.payment.platform.zksync-rinkeby-tglm.address": "0x82251cbb5b1d882a7b3c8b7f5581212143a68505",
    "golem.com.pricing.model": "linear",
    "golem.com.pricing.model.linear.coeffs": [
      0.001,
      1e-7,
      1e-7,
      0.0
    ],
    "golem.com.scheme": "payu",
    "golem.com.scheme.payu.debit-note.interval-sec?": 120,
    "golem.com.scheme.payu.payment-timeout-sec?": 120,
    "golem.com.usage.vector": [
      "golem.usage.duration_sec",
      "golem.usage.network.in",
      "golem.usage.network.out"
    ],
    "golem.node.debug.subnet": "public",
    "golem.node.id.name": "nieznanysprawiciel-leopard-Provider-4",
    "golem.node.net.is-public": true,
    "golem.runtime.capabilities": [
      "vpn",
      "gateway"
    ],
    "golem.runtime.name": "outbound-gateway",
    "golem.runtime.version": "0.1.0",
  },
  "constraints": "(&\n  (golem.srv.comp.expiration>1675776137525)\n  (golem.node.debug.subnet=public)\n)"
}

Demand structure

{
   "properties":{
      "golem.com.payment.debit-notes.accept-timeout?": 240,
      "golem.node.debug.subnet": "public",
      "golem.com.payment.chosen-platform": "erc20-rinkeby-tglm",
      "golem.com.payment.platform.erc20-rinkeby-tglm.address": "0xa5ad3f81e283983b8e9705b2e31d0c138bb2b1b7",
      "golem.srv.comp.expiration": 1675717098879
   },
   "constraints":"(&(golem.node.debug.subnet=public)" + 
      "(golem.com.payment.platform.erc20-rinkeby-tglm.address=*)"+
      "(golem.com.pricing.model=linear)"+
      "(golem.runtime.name=outbound-gateway)"+
      "(golem.runtime.capabilities=gateway)"+
   ")"
}

Getting Demand payment attributes

GET /payment-api/v1/demandDecorations?allocationIds=ba126ca0-a98d-4211-9bd7-e213095d1f24
=>
<= HTTP/1.1 200 OK
<= content-type: application/json
<= 
<= {
<=   "properties": [
<=     {
<=       "key": "golem.com.payment.platform.erc20-rinkeby-tglm.address",
<=       "value": "0x889ff52ece3d5368051f4f8216650a7843f8926b"
<=     }
<=   ],
<=   "constraints": [
<=     "(golem.com.payment.platform.erc20-rinkeby-tglm.address=*)"
<=   ]
<=  }

Creating Demand

=> POST /market-api/v1/demands HTTP/1.1
=> content-type: application/json
=>
=> {
=>   "properties":{
=>      "golem.com.payment.debit-notes.accept-timeout?": 240,
=>      "golem.node.debug.subnet": "vpn",
=>      "golem.com.payment.chosen-platform": "erc20-rinkeby-tglm",
=>      "golem.com.payment.platform.erc20-rinkeby-tglm.address": "0x889ff52ece3d5368051f4f8216650a7843f8926b",
=>      "golem.srv.comp.expiration": 1676308583462
=>   },
=>   "constraints":"(&(golem.node.debug.subnet=vpn)(golem.com.payment.platform.erc20-rinkeby-tglm.address=*)(golem.com.pricing.model=linear) (golem.runtime.name=outbound-gateway)(golem.runtime.capabilities=net-gateway))"
=> }
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= "d9ceb47fc54f456eb77fcfa710f1d429-7690168661d777d351339b5c17d616da8f3cd568a32d732ebf22d188a85546f2"

Getting Proposals

=> GET /market-api/v1/demands/d9ceb47fc54f456eb77fcfa710f1d429-7690168661d777d351339b5c17d616da8f3cd568a32d732ebf22d188a85546f2/events?maxEvents=5&pollTimeout=3000
=>
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= [
<=  {
<=    "eventType": "ProposalEvent",
<=    "eventDate": "2023-02-13T16:48:45.268Z",
<=    "proposal": {
<=     .....
<=     .....
<=     ....
<=  }
<=  ....
<= ]

Responding for proposal

=> POST /market-api/v1/demands/d9ceb47fc54f456eb77fcfa710f1d429-7690168661d777d351339b5c17d616da8f3cd568a32d732ebf22d188a85546f2/proposals/R-ecfd7d45039063d9c63f4a32b393cc30209f2ad3e3b6de97e68198440f56b446
=> content-type: application/json
=>
=> {
=>   "properties":{
=>      "golem.com.payment.debit-notes.accept-timeout?": 240,
=>      "golem.node.debug.subnet": "vpn",
=>      "golem.com.payment.chosen-platform": "erc20-rinkeby-tglm",
=>      "golem.com.payment.platform.erc20-rinkeby-tglm.address": "0x889ff52ece3d5368051f4f8216650a7843f8926b",
=>      "golem.srv.comp.expiration": 1676308583462
=>   },
=>   "constraints":"(&(golem.node.debug.subnet=vpn)(golem.com.payment.platform.erc20-rinkeby-tglm.address=*)(golem.com.pricing.model=linear) (golem.runtime.name=outbound-gateway)(golem.runtime.capabilities=net-gateway))"
=> }

<= HTTP/1.1 201 Created
<= content-type: application/json
<=
<= "R-1536e936bb888d9326fda9ed603ea37c826671b4ce730c82cba3514d895fea2f"

Getting Proposals

=> GET /market-api/v1/demands/d9ceb47fc54f456eb77fcfa710f1d429-7690168661d777d351339b5c17d616da8f3cd568a32d732ebf22d188a85546f2/events?maxEvents=5&pollTimeout=3000
=>
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= [
<=  {
<=    "eventType": "ProposalEvent",
<=    "eventDate": "2023-02-13T16:48:45.268Z",
<=    "proposal": {
<=     .....
<=     .....
<=     ....
<=  }
<=  ....
<= ]

Accepting proposal by creating Agreement

=> POST /market-api/v1/demands/agreements
=> content-type: application/json
=> 
=> {"proposalId": "R-1536e936bb888d9326fda9ed603ea37c826671b4ce730c82cba3514d895fea2f", "validTo": "2023-02-13T17:08:45.268Z" }
<= content-type: application/json
<=
<= HTTP/1.1 201 Created
<= content-type: application/json
<= 
<= "R-fe375e04bed66b5e9d2d30c57fbb9bcc620880c5f384ba745fa58dbe3d8e57b7"


### Creating activity

TODO

### Starting activity

```json
[
  {"deploy": {"net": {"id": "844bf7eaf8d44050839a6799ef258fb9", "ip": "192.168.8.0", "mask": "255.255.255.0", "nodeIp": "192.168.8.7" } } },
  {"start": {}}
]

Assinging Outbound Gateway

POST /net-api/v2/net/844bf7eaf8d44050839a6799ef258fb9/nodes
=> Content-type: application/json
=>
=> {
=>  "id": "0x1b12cecbfdecb13d80597fbe474059ed1938e0c3",
=>  "activityId": "PcXYukJ4/aZ...JQ1XDgdCyLRLEQtpW5lmFgwPhnGrBFdH9Jtb",
=>  "ip": "192.168.8.7"
=> }
<= HTTP/1.1 200 OK
<= content-type: application/json
<=
<= null

RX/TX packets on VPN

connect to websocket endpoint

// url = 'ws://<rpc>/net-api/v2/net/{net_id}/raw/from/{requestor-ip}/to/{dst-ip}';
url = 'ws://127.0.0.1:7465/net-api/v2/net/844bf7eaf8d44050839a6799ef258fb9/raw/from/192.168.8.12/to/192.168.8.7';
subprotocol = 'ipv4';

const ws = new WebSocket(url, [subprotocol]);

ws.addEventListener('message', (event) => {
	// some one sends packet to requestor on his 
	// ip address 192.168.8.12
});

ws.send(...<raw ipv4 paket>...)