CirclesUBI / pathfinder2

MIT License
13 stars 9 forks source link

Max flow changes with the value sent #32

Open JacqueGM opened 1 year ago

JacqueGM commented 1 year ago

Describe the bug

To calculate the max flow we try to send a big amount e.g. 1000000000000000000000000000000000, this will return a max value of 20k, but when actually trying to send this amount the pathfinder recalculates the maxflow and it returns a lower value, making the transaction imposible with that amount and having to use a lower value

To Reproduce

Query

{"id":"7e59ed4c-2570-48ed-8be3-73d6046608e5","method":"compute_transfer","params":{"from":"0x3c89A829400Ea3B49F25738A1F4015A7961D0301","to":"0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c","value":"1000000000000000000000000000000000","max_transfers":30}}

Response

{"jsonrpc":"2.0","id":"7e59ed4c-2570-48ed-8be3-73d6046608e5","result":{"maxFlowValue":"2858665056346404962677","final":true,"transferSteps":[..],"value":"305207535700394770000"}]}}

When trying to send the maxflow

Query

{"id":"02c4928e-d632-4675-a3f4-bc1737c6e3c7","method":"compute_transfer","params":{"from":"0x3c89A829400Ea3B49F25738A1F4015A7961D0301","to":"0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c","value":"2766093611613873700000","max_transfers":30}}

Response

maxFlowValue":"1955148786991411924393"
"value":""2766093611613873700000""

As it can be seen the maxflow calculated is lower than the previous one Expected behavior

if the max value is 20k, when trying to send that amount we should be able to send up to that amount without this having to be recalculated (or yes but returning the real max flow)

llunaCreixent commented 1 year ago

Exactly, and for several rounds, trying to send a bit less than the previously reported maxFlow, I get an even lower maxFlow which makes my requested amount not valid. Here there are the requests attempted: First calculation of max flow:

{"id":"8cf11988-7453-40ba-a288-b46cb50069a2","method":"compute_transfer","params":{"from":"0x3c89A829400Ea3B49F25738A1F4015A7961D0301","to":"0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c","value":"1000000000000000000000000000000000","max_transfers":30}}

Response:

maxFlowValue: 2858665056346404962677

Attempt to send a lower amount:

{"id":"4e222803-cbc3-4242-87ad-cc649d124bfc","method":"compute_transfer","params":{"from":"0x3c89A829400Ea3B49F25738A1F4015A7961D0301","to":"0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c","value":"2858662330483210000000","max_transfers":30}}
maxFlowValue: 1959429606976730130623

The last max flow shows that I cannot make the transfer I want, and again for a lower value:

{"id":"370ffe33-d7f1-4587-b612-6bf7fccbd550","method":"compute_transfer","params":{"from":"0x3c89A829400Ea3B49F25738A1F4015A7961D0301","to":"0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c","value":"1959190210434714800000","max_transfers":30}}
maxFlowValue: 1552080726630599419064

Between and after each requests, the response using the first big big amount is the same.

chriseth commented 1 year ago

The flow computation has there input parameters:

With these, the process is as follows:

1) The theoretical max flow from source to destination is computed, while the graph is explored for at most max_distance hops from the source.

This max flow is the one printed on stdout.

2) edges are removed until the flow is reduced to requested_flow.

3) further edges are removed until the number of transfers is at most max_transfers. This can result in capacity loss. If that is the case, it is printed on stdout.

4) the transfer sequence is extracted and simplified by combining some transfers.

In all of the above, some values are only roughly right because intermediate nodes are introduced in the graph which only allows to compute approximate number of transfers and distances.

The maxFlowValue returned via the json interface is the final transfer amount, not the theoretical max flow.

llunaCreixent commented 1 year ago

I performed some tests running the server in local following the instructions in the README. Changing the "value" for every query.


branches: main, dev

curl -i --location --request POST 'http://localhost:1234' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id":"timestamp_value", 
    "method": "compute_transfer", 
    "params": {
        "from": "0x3c89A829400Ea3B49F25738A1F4015A7961D0301",
        "to": "0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c",
        "value": "1280116562130304744004",
        "max_transfers": 30
        }
    }'

Q: 1000000000000000000000000000000000 R: 1280116562130304744004 R: 1280116562130304744004

Q: 1280116562130304744004 R: 912080089122549633316 R: 912080089122549633316

Q: 1280000000000000000000 R: 912350918147240642707 912350918147240642707


branch: feature/server_only

curl -i --location --request POST 'http://localhost:1234' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id":"timestamp_value", 
    "method": "compute_transfer", 
    "params": {
        "from": "0x3c89A829400Ea3B49F25738A1F4015A7961D0301",
        "to": "0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c",
        "value": "1000000000000000000000000000000000",
        "max_transfers": 30,
        "prune": true
        }
    }'

Q: 1000000000000000000000000000000000 R: 6556106439487993740776 R: 6556106439487993740776 R: 6556106439487993740776 R: 6556106439487993740776

Q: 6556106439487993740776 R: 6556106439487993740776 R: 6556106439487993740776


branch: feature/server_only no prune (commenting lines 61 and 62 of pathfinder2/src/graph/flow.rs):

curl -i --location --request POST 'http://localhost:1234' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id":"timestamp_value", 
    "method": "compute_transfer", 
    "params": {
        "from": "0x3c89A829400Ea3B49F25738A1F4015A7961D0301",
        "to": "0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c",
        "value": "6556106439487993740776",
        "max_transfers": 30
        }
    }'

Q: 1000000000000000000000000000000000 R: 6556106439487993740776

Q: 6556106439487993740776 R: 6556106439487993740776 R: 6556106439487993740776


Production

curl -i --location --request POST 'https://pathfinder.circlesubi.id/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "id":"timestamp_value", 
    "method": "compute_transfer", 
    "params": {
        "from": "0x3c89A829400Ea3B49F25738A1F4015A7961D0301",
        "to": "0x9BA1Bcd88E99d6E1E03252A70A63FEa83Bf1208c",
        "value": "1147000000000000000000",
        "max_transfers": 30
        }
    }'

Q: 1000000000000000000000000000000000 R: 1147684776180813048132 R: 1153378830746580631870 R: 1147684776180813048132

Q: 1147684776180813048132 R: 758957868159499520147 R: 757278266120385655641 R: 780081643976411966706 R: 772481598654725431905

Q: 1147000000000000000000 R: 758273091978686472015 R: 779396867795598918574


conclusions:

jaensen commented 1 year ago

Hi! Yes, that looks like differences in the underlying data while the rest looks pretty consistent. Will need to check the data.