owned this note
owned this note
Published
Linked with GitHub
# Pathfinder Reloaded
### Changelog:
* **2023-02-25**
Renamed keys `transfers` to `transferSteps` and `flow` to `maxFlowValue` in the json response.
* **2022-12-21**
Added `max_transfers` option for `compute_transfers`.
* **2022-12-20**
Added `load_safes_binary`.
* **2022-11-08**
The function `update_edges` also uses the attribute `token_owner` instead of
`token` to be consistent with the change below.
Implementations might choose to accept both attributes.
It also returns the new number of edges.
Furthermore, added a note regarding concurrent calls to `update_edges`.
* **2022-10-07**
The edge binary now contains the token owner's address instead of the token's address.
This both saves some space (because we have fewer different addresses) and it's also how
the `transfer_through` function in the smart contract works.
The json response field name is also changed from `token` to `token_owner`.
### Main Architecture:
multithreaded process with json-rpc-via-http interface.
Open questions: Can we have multiple responsen to a single query in json-rpc-via-http?
Commandline:
`pathfinder --port <json-rpc-port>`
Opens an http server (no ssl) on the given port making available the json-rpc functions listed below.
Different json-rpc requests do not block each other and are executed in multiple threads if possible. The in-memory database is shared as much as possible to reduce the memory footprint.
### Interface functions
json-rpc request ID is implied (it is not part of the parameters).
#### `load_edges_binary({"file:" <path>})`
Replaces the full edge set by the one contained in the local file at the given path. Path queries might still use the old edge set until this request is completed.
File format of the edge file:
```
uint32: number_of_addresses
[ bytes20: address ] * number_of_addresses
uint32: number_of_edges
[
uint32: from_address_index
uint32: to_address_index
uint32: token_owner_address_index
uint256: capacity
] * number_of_edges
```
Here, all numbers are encoded in fixed-width big endian encoding, except for `uint256`:
These numbers are encoded as `<number of nonzero bytes as uint8><nonzero bytes>`, i.e. `1` is encoded as `0x0101` while `256` is encoded as `0x020100`.
Response: Number of edges.
#### `load_edges_csv({"file:" <path>})`
Same as `load_edges_binary` except that the file is expected to be in the following format:
```
<from (hex address)>,<to (hex address)>,<token_owner (hex address)>,<capacity (decimal integer)>
...
```
#### `load_safes_binary({"file:" <path>})`
Replaces the full edge set by the one computed from a binary file containing the complete safe data in the local file at the given path.
Path queries might still use the old edge set until this request is completed.
File format of the safe file:
```
uint32: number_of_addresses
[ bytes20: address ] * number_of_addresses
uint32: number_of_organizations
[ uint32: address_index ] * number_of_organizations
uint32: number_of_trust_edges
[
uint32: user_address_index
uint32: send_to_address_index
uint8: trust_limit_percentage
] * number_of_trust_edges
uint32: number_of_balances
[
uint32: user_address_index
uint32: token_owner_address_index
uint256: balance
] * number_of_balances
```
Here, all numbers are encoded in fixed-width big endian encoding, except for `uint256`:
These numbers are encoded as `<number of nonzero bytes as uint8><nonzero bytes>`, i.e. `1` is encoded as `0x0101` while `256` is encoded as `0x020100`.
Response: Number of edges.
#### `compute_transfer({from: <hex_address>, to: <hex_address>, value: <bigint>, iterative: <bool>, prune: <bool>, max_transfers: <int>})`
The parameters `iterative` and `prune` are optional and default to `false`.
The parameter `max_transfers` is optional and defailts to "unlimited".
Computes a multi-hop transfer flow from `from` to `to` trying to transfer `value` tokens.
If `iterative` is `true`, produces multiple responses where each response is an improvement over the previous one WRT amount transferred (increasing) or number of transfers (decreasing).
If `ee` is `true`, tries to reduce the number of transfers.
If `max_transfers` is provided, tries to remove individual transfers to stay below the limit, even if this results in less value being transferred.
The response is a sequence of the following objects, one in each line.
The last object has `final: true`. If `iterative` is `false` in the request, there is only a single response that has `final: true`.
```
{
maxFlowValue: <bigint>,
final: <bool>, // if true, there will be no further response to the query
transferSteps: [
{
from: <address>,
to: <address>,
token_owner: <address>
value: <bigint>
},
...
],
debug: <debug string, unspecified>
}
```
#### `cancel(id)`
Cancels the `compute_transfer` request with the given ID.
#### `update_edges([{from, to, token_owner, capacity}, ...])`
Updates the capacity of the given edges. A capacity of zero effectively deletes the edge.
The function returns the new number of edges.
It is important to note that concurrent calls to `update_edges` might not behave as expected.
Make sure to wait for the call to return before you make another call to `update_edges`.