go: Path Finding Started to Return Invalid Paths in Horizon 1.4.0 (op_too_few_offers)

What version are you using?

Horizon 1.4.0

What did you do?

I’m obtaining paths from /paths/strict-receive and then use the most economic path in a path-payment-strict-receive operation. This has been working fine up until 1.3.0 but now we’re intermittently (and increasingly often) seeing op_too_few_offers when the best path is used. Looking at the returned paths from /paths/strict-receive they seem implausible actually. I think there might be an issue with pathfinder, which started with version 1.4.0.

What did you expect to see?

I’d expect paths given be the pathfinder to work fine and not result in op_too_few_offers when used in a path payment operation.

What did you see instead?

Tx fails with op_too_few_offers.

Example. /paths/strict-receive finds this path, which then results in op_too_few_offers if used:

{
   "sourceAssetType":"credit_alphanum4",
   "sourceAssetCode":"ETH",
   "sourceAssetIssuer":"GBDEVU63Y6NTHJQQZIKVTC23NWLQVP3WJ2RI2OTSJTNYOIGICST6DUXR",
   "sourceAmount":"0.0414144",
   "destinationAssetType":"credit_alphanum4",
   "destinationAssetCode":"USD",
   "destinationAssetIssuer":"GDUKMGUGDZQK6YHYA5Z6AY2G4XDSZPSZ3SW5UN3ARVMO6QSRDWP5YLEX",
   "destinationAmount":"10.0000000",
   "path":[
      {
         "assetType":"credit_alphanum4",
         "assetCode":"ETH",
         "assetIssuer":"GBVOL67TMUQBGL4TZYNMY3ZQ5WGQYFPFD5VJRWXR72VA33VFNL225PL5"
      },
      {
         "assetType":"credit_alphanum4",
         "assetCode":"ETH",
         "assetIssuer":"GCNSGHUCG5VMGLT5RIYYZSO7VQULQKAJ62QA33DBC5PPBSO57LFWVV6P"
      },
      {
         "assetType":"native",
         "assetCode":"XLM",
         "assetIssuer":null
      }
   ]
}

Upon manual inspection, this does not look like a plausible path: ETH -> {ETH -> ETH -> XLM} -> USD and correctly got rejected by the Network with tx_failed and op_too_few_offers.

Normally in 100% of the cases this would be a bad trade. Trading tethers horizontally across several issuers always is a loss of money. So it looks like pathfinder indeed finds invalid paths and then core rejects them because they don’t actually exist and the tx fails.

Please let me know if you need more info. @bartekn @abuiles

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 22 (22 by maintainers)

Most upvoted comments

@marcinx glad to hear this is not a Horizon bug. For the future, anything you can do to provide a repro out of the gate (e.g. exact Horizon call + failed txhash) would be awesome. We spent some time on this and turnaround could be a lot faster next time with a little more info up front.

Yeah, I can imagine. I feel bad for wasting your time. It seemed so obvious at first, considering that path finding gave wrong results in the very past. Contrary to that it looks very robust and fast now though 💯Will triple-check better and provide more meta out of the box next time I run into any issues. Thanks for helping to find the root cause of this!!

@marcinx no worries 😃

one tip which may be helpful:

you can log the transaction hash in your backend whenever a transaction fails. then, if you need to debug why the transaction failed, you will be able to easily look up the transaction details via horizon

@marcinx I just realized that I was using the default max-path-length which is 3 and you are using a max-path-length value of 4. After changing the configuration to match yours I’m able to observe the 0.0476752 ETH:GBDEVU63Y6NTHJQQZIKVTC23NWLQVP3WJ2RI2OTSJTNYOIGICST6DUXR path in my response

@marcinx you need to include_failed https://horizon.stellar.org/ledgers/30609467/transactions?limit=200&include_failed=true

On Wed, Jul 15, 2020 at 2:34 PM marcinx notifications@github.com wrote:

@tamirms https://github.com/tamirms PS: It’s more complicated than that. The tx is sent from a channel account (which can be any of these):

GBBMI477CH2XZQ53R5PLTB5PUUPZEARARRF5LFEYOUEVWIC6J3WXWTN5

GBGG4PZQFXZYF3OUPB5P4Z5SDYY6QS3YAB3EQPIOBTG4J3BGA3JMXDOR

GBIWIMXSMFXDK44VUNFUHSCUJVK7UJUAD5J7TUJOYQIKRGHAHPWLSYZ6

GC2AEFWNZJ6YFZO4HGQ5DW3P6DBHJ6QDTPFSOTWOTSSHJZD56VC3XOSK

GC4WSVHVHYWR2KF4Z7AMTOB7M3C2P67TQ4JWWW44DSS7LUFNUT2VF6RL

GD4XE5WQTJLFDY67XDN5SOIQVPLWUCLZ5UPOFFKOZKNAC6GV3WRHCS6M

GD776TFY6ECG6K2SZC3Q26RZDIXF7KLRRNKGOWGUDRSNK4CUITLUPPZU

GDRLNPHYGF3AYG2Q2NXHMXVWGMRA6KIMAL7UJ2O3CDHSFZ2TWOQNMDS5

GDV3ZOYWTAUR2VLHB2DM77AM5EDC5KU6UKLC5VDPAVDRNQJYKELPUNK5

GDXMVK2NJRND72NIJ2XF37VWLKP2YNA64IBSSGVTY7B5KAIVECZCM3LT

So when looking for the failed tx, it should have either of above as source account. The source account for the op should be GBDHWMSXQ24FA2LJTPUH3HNK3WR7BJW3DUUBLMSNSJ7ST4XZK7WJHPCQ .

However, horizon.stellar.org doesn’t seem to display failed transactions? When I go https://horizon.stellar.org/ledgers/30609467 it tells me that there are 31 successful and 10 failed txs. When I visit https://horizon.stellar.org/ledgers/30609467/transactions?limit=200 it only has the 31 successful txs but no fails.

I tried, but really don’t know how to find the failed one without doing a major database query operation, which I would have to research how to do in the first place 😃 ¯_(ツ)_/¯ Maybe there is another way to verify that the suspicious path actually existed?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/stellar/go/issues/2810#issuecomment-658964666, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAFKDG7KLULPW2XRWVABD3R3YACTANCNFSM4OYRVMHA .

Caught another such case today. Here is some extra info:

Request: GET /stardust/v1/paths/strict-receive?sourceAccount=GBDHWMSXQ24FA2LJTPUH3HNK3WR7BJW3DUUBLMSNSJ7ST4XZK7WJHPCQ&destinationAssetType=credit_alphanum4&destinationAssetCode=EURT&destinationAssetIssuer=GAP5LETOV6YIE62YAM56STDANPRDO7ZFDBGSNHJQIYGGKSMOZAHOOS2S&destinationAmount=10.0000000 (this proxies the params to Horizon)

Complete Horizon Response Body: https://gist.github.com/marcinx/f3b3fbfadf9535822f9e5ab6472f7bce

Most Economic Apay ETH -> Tempo EURT path:

{
   "sourceAssetType":"credit_alphanum4",
   "sourceAssetCode":"ETH",
   "sourceAssetIssuer":"GBDEVU63Y6NTHJQQZIKVTC23NWLQVP3WJ2RI2OTSJTNYOIGICST6DUXR",
   "sourceAmount":"0.0476752",
   "destinationAssetType":"credit_alphanum4",
   "destinationAssetCode":"EURT",
   "destinationAssetIssuer":"GAP5LETOV6YIE62YAM56STDANPRDO7ZFDBGSNHJQIYGGKSMOZAHOOS2S",
   "destinationAmount":"10.0000000",
   "path":[
      {
         "assetType":"credit_alphanum4",
         "assetCode":"ETH",
         "assetIssuer":"GBVOL67TMUQBGL4TZYNMY3ZQ5WGQYFPFD5VJRWXR72VA33VFNL225PL5"
      },
      {
         "assetType":"credit_alphanum4",
         "assetCode":"ETH",
         "assetIssuer":"GCNSGHUCG5VMGLT5RIYYZSO7VQULQKAJ62QA33DBC5PPBSO57LFWVV6P"
      },
      {
         "assetType":"native",
         "assetCode":"XLM",
         "assetIssuer":null
      }
   ]
}

Ledger from pathfinder http response headers: 'latest-ledger': '30609467'

When trying to use this path in ledger 30609468 with a path-payment-strict-receive, the response is: op_too_few_offers.

This happens intermittently.

Hope this helps. Please let me know when you have more questions. @bartekn @tamirms @abuiles

@marcinx I think it doesn’t count the source so the length is actually 4:

ETH -> {ETH -> ETH -> XLM} -> USD
        1      2      3       4