cowprotocol / solver-rewards

Data Aggregation for Solver Reimbursement & Rewards Distributor
Other
8 stars 5 forks source link

Alternative Simulation Implementation #245

Closed bh2smith closed 1 year ago

bh2smith commented 1 year ago

We created a "generic" simulation interface in hopes that there would be alternative options (so not to depend so heavily on Tenderly). At the moment, it is unclear what alternatives we have. CoW Protocol's backend services run "semi-simulations" via estimateGas calls to ETH-RPC. However, this is insufficient since we require state updates and event logs from the simulation (and not just whether or not the transaction succeeds).

bh2smith commented 1 year ago

@fleupold suggested a few other options:

@sunce86 was also suggesting that it shouldn’t be hard to hack an existing client to serve events together with eth_call (maybe on top of RETH?). Could be a cool ecosystem friday project. I wonder, can we also get ETH balance differences?

bh2smith commented 1 year ago

Every time I try Alchemy it NEVER works properly

➜  ~ curl --location --request POST 'https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}' \   
--header 'Content-Type: application/json' \
--data-raw '{
  "jsonrpc": "2.0",
  "method": "alchemy_simulateAssetChanges",
  "id": 1,
  "params": [
    {
      "from": "0xb20b86c4e6deeb432a22d773a221898bbbd03036",
      "to": "0x9008d19f58aabd9ed0d60971565aa8510560ab41",
      "value": "0",
      "data": "0x13d79a0b000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000056fd409e1d7a124bd7017459dfea2f387b6d5cd000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000421b1f43250000000000000000000000000000000000000000000000000000000001b163c700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d474038cd18c1a2ce87dfcab635398c32379f6a000000000000000000000000000000000000000000000000000000421b1f43250000000000000000000000000000000000000000000000000000000001b15a0800000000000000000000000000000000000000000000000000000000643e661dee8205ef376013a542f973e5b9d13d65812daf35e516b56162e99a18832fbdfb00000000000000000000000000000000000000000000000000000000030dba240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000421b1f4325000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000412746c5eaa3bc43fd70ddc6244ae76a1059123eb9b7497ce3d118d3878e246dd24fc6eedaed49bc791640789ac9bc00ea4b7e439f8665cdd7d2d54ddcda0ecb2f1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000004a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000001111111254eeb25477b68fb85ed929f73a96058200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000034812aa3caf0000000000000000000000001136b25047e142fa3018184793aec68fbb173ce4000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000000000000000000000000056fd409e1d7a124bd7017459dfea2f387b6d5cd0000000000000000000000001136b25047e142fa3018184793aec68fbb173ce40000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41000000000000000000000000000000000000000000000000000000421b1f43250000000000000000000000000000000000000000000000000000000001b1430c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a800000000000000000000000000000000000000000000018a00015c0000fc00a007e5c0d20000000000000000000000000000000000000000000000d80000ca0000b05120bebc44782c7db0a1a60cb6fe97d0b483032ff1c7dac17f958d2ee523a2206206994597c13d831ec700443df02124000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003b8ca698751618092a720020d6bdbf786b175474e89094c44da98b954eedeac495271d0f00a085db1a5900005af3107a400000a0cd211e1e056fd409e1d7a124bd7017459dfea2f387b6d5cd0000000000000000000000000000000000000000000000000000000001b163c7000000000000000000000000000001ee33ff9008d19f58aabd9ed0d60971565aa8510560ab4180a06c4eca27056fd409e1d7a124bd7017459dfea2f387b6d5cd1111111254eeb25477b68fb85ed929f73a960582000000000000000000000000000000000000000000000000d26cd1970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    }
  ]
}'

responds with

{"jsonrpc":"2.0","id":1,"error":{"code":-32000,"message":"Must be authenticated!"}}%   

but of course the requests from their documentation works:

curl https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}   -X POST   -H "Content-Type: application/json"   -d '{"jsonrpc":"2.0","method":"alchemy_getTokenBalances","params": ["0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be", ["0x607f4c5bb672230e8672085532f7e901544a7375", "0x618e75ac90b12c6049ba3b27f5d5f8651b0037f6", "0x63b992e6246d88f07fc35a056d2c365e6d441a3d", "0x6467882316dc6e206feef05fba6deaa69277f155", "0x647f274b3a7248d6cf51b35f08e7e7fd6edfb271"]],"id":"42"}'
bh2smith commented 1 year ago

Phalcon seems to work well on this batch

https://explorer.phalcon.xyz/tx/eth/0xa5ed3e795403b4dd2eb6b53e3e2009e264e8e053e6f601c93fa42ccd37723728?event=simulation&type=2&timestamp=1681812853192

bh2smith commented 1 year ago

https://cowservices.slack.com/archives/C035RP0RH3P/p1683907822012099

Try this out (only requires a full node)!

https://github.com/EnsoFinance/transaction-simulator

fleupold commented 1 year ago

Every time I try Alchemy it NEVER works properly

In the request you pasted ${ALCHEMY_KEY} needs to be replaced by an actual API Key (see 1Password), which is also implied by the error message you shared.

Try this out (only requires a full node)!

One thing that I'm not sure if for this project it's enough to do "top of block" simulations or if you need to be able to specify a transaction index. If the latter, the EnsoFinance project needs to be somewhat adjusted to allow for mid block simulations (should be fairly easy to add)

bh2smith commented 1 year ago

In the request you pasted ${ALCHEMY_KEY} needs to be replaced by an actual API Key (see 1Password), which is also implied by the error message you shared.

I am 100% sure that I used an actual key, but I will try again sometime.

or if you need to be able to specify a transaction index.

No need for us to specify transaction index (at least not at this point).

bh2smith commented 1 year ago

Phalcon API (reverse engineered)

curl -X POST https://explorer.phalcon.xyz/api/v1/tx/simulate/2 \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"chainID":1,"sender":"0x7f01D9b227593E033bf8d6FC86e634d27aa85568","receiver":"0x7f01D9b227593E033bf8d6FC86e634d27aa85568","inputData":"0x1234","value":"0","block":0,"position":0,"gasLimit":1000000,"gasPrice":"100"}'
bh2smith commented 1 year ago

Unfortunately, we will not be able to use Phalcon here as any form of "professional" simulator because of their overly processed response data:

See here: http://jsonblob.com/1109228672375865344

Or here if link is dead:

partially truncated json ``` { "latestBlock": 17296089, "transaction": { "accountLabels": [ { "address": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", "label": "Ether" }, { "address": "0x61eb53ee427ab4e007d78a9134aacb3101a2dc23", "label": "SushiSwap: FXS" }, { "address": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "label": "CoW Protocol: GPv2Settlement" }, { "address": "0x0000000000000000000000000000000000000001", "label": "Null: 0x000...001" }, { "address": "0x9e7ae8bdba9aa346739792d219a808884996db67", "label": "CoW Protocol: GPv2AllowListAuthentication" }, { "address": "0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f", "label": "SushiSwap: Router" }, { "address": "0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0", "label": "Frax Finance: FXS Token" }, { "address": "0x6b175474e89094c44da98b954eedeac495271d0f", "label": "Maker: Dai Stablecoin" }, { "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "label": "Wrapped Ether" }, { "address": "0x2c4c28ddbdac9c5e7055b4c863b72ea0149d8afe", "label": "CoW Protocol: GPv2AllowListAuthentication_Proxy" }, { "address": "0xc92e8bdf79f0507f65a392b0ab4667716bfe0110", "label": "CoW Protocol: GPv2VaultRelayer" } ], "balanceChanges": [ { "account": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "assets": [ { "address": "0x6b175474e89094c44da98b954eedeac495271d0f", "amount": "2000.000000000000000000", "iconUrl": "https://assets.blocksec.com/icon/39aead569b9c011cb6f69734d9abbc9ab6a80049fe93bbd12bb473a3e0e859a3.png", "sign": true, "value": "1999.8" }, { "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "amount": "1.614063949739215622", "iconUrl": "https://assets.blocksec.com/icon/f1cb2d02c471d545bbc7722daf3277fd852d98e63d118771af7047bd8256c516.png", "sign": false, "value": "1935.327238" }, { "address": "0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0", "amount": "13.465661362123409367", "iconUrl": "https://assets.blocksec.com/icon/f6d1496c0db643a5472d31b1c538aedd635a56f27b51fc3564ed46409f000250.png", "sign": false, "value": "56.82509095" } ] }, { "account": "0xe2b424053b9ebfcedf89ecb8bf2972974e98700c", "assets": [ { "address": "0x6b175474e89094c44da98b954eedeac495271d0f", "amount": "2000.000000000000000000", "iconUrl": "https://assets.blocksec.com/icon/39aead569b9c011cb6f69734d9abbc9ab6a80049fe93bbd12bb473a3e0e859a3.png", "sign": false, "value": "1999.8" }, { "address": "0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0", "amount": "469.613864284355328238", "iconUrl": "https://assets.blocksec.com/icon/f6d1496c0db643a5472d31b1c538aedd635a56f27b51fc3564ed46409f000250.png", "sign": true, "value": "1981.770507" } ] }, { "account": "0x61eb53ee427ab4e007d78a9134aacb3101a2dc23", "assets": [ { "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", "amount": "1.614063949739215622", "iconUrl": "https://assets.blocksec.com/icon/f1cb2d02c471d545bbc7722daf3277fd852d98e63d118771af7047bd8256c516.png", "sign": true, "value": "1935.327238" }, { "address": "0x3432b6a60d23ca0dfca7761b7ab56459d9c964d0", "amount": "456.148202922231918871", "iconUrl": "https://assets.blocksec.com/icon/f6d1496c0db643a5472d31b1c538aedd635a56f27b51fc3564ed46409f000250.png", "sign": false, "value": "1924.945416" } ] } ], "basicInfo": { "baseFee": "16.993708868", "block": 16300366, "callParameter": "0x13d79a0b000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000000020000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d00000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000009e1a51c6b00000000000000000000000000000000000000000000000000000002540be4000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e2b424053b9ebfcedf89ecb8bf2972974e98700c00000000000000000000000000000000000000000000006c0b439bc588511000000000000000000000000000000000000000000000000019629e5fa65ea1706b0000000000000000000000000000000000000000000000000000000063af639ec86d3a0def4d16bd04317645da9ae1d6871726d8adf83a0695447f8ee5c63d12000000000000000000000000000000000000000000000000604fbfc634eef000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006c0b439bc58851100000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000041d6f2b85ab927ca9078c1081587fe4ea7ec72a9e1ef3ed826649e8fa063bafb45643196adc29f3c13403865f063131bb2a5a293483423c810ea56dc764e25e2971c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001048803dbee000000000000000000000000000000000000000000000018ba53f5c7f06ef117000000000000000000000000000000000000000000000000166c0a97dd56bfd500000000000000000000000000000000000000000000000000000000000000a00000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab41ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003432b6a60d23ca0dfca7761b7ab56459d9c964d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "errorInfo": "", "eventCount": 13, "gasLimit": 10000000, "gasPrice": "100.000000000", "gasUsed": 331884, "hash": "0x997c5ec1880c6753a3cc2d46e630ca51a12ae3e6bf118adc328c221df0ad13f2", "intTxnCount": 13, "isFlashbots": false, "isFlashloan": false, "maxFee": "", "nonce": 15885, "overwrited": false, "overwritedBlock": 0, "priorityFee": "", "receiver": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "revertDetail": "", "sender": "0xa21740833858985e4d801533a808786d3647fb83", "status": true, "timestamp": "2022-12-30T21:48:35Z", "transactionFee": "0.033188400000000000", "txnIndex": 0, "type": 0, "value": "0" }, "chainID": 1, "debugFlowMap": { "-1": [ { "children": [ { "children": [], "evmDepth": 0, "id": 0, "jumpGuide": { "nextId": -2, "previousId": -2, "stepInId": -2, "stepOutId": -2 }, "order": 0 } ], "evmDepth": -1, "id": -1, "jumpGuide": { "nextId": -2, "previousId": -2, "stepInId": -2, "stepOutId": -2 }, "order": -1 } ] }, "enableDebug": false, "fundflow": [ { "amount": "2,000", "from": "0xe2b424053b9ebfcedf89ecb8bf2972974e98700c", "id": 1, "to": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "token": "DAI" }, { "amount": "1.614063949739215622", "from": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "id": 2, "to": "0x61eb53ee427ab4e007d78a9134aacb3101a2dc23", "token": "WETH" }, { "amount": "456.148202922231918871", "from": "0x61eb53ee427ab4e007d78a9134aacb3101a2dc23", "id": 3, "to": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "token": "FXS" }, { "amount": "469.613864284355328238", "from": "0x9008d19f58aabd9ed0d60971565aa8510560ab41", "id": 4, "to": "0xe2b424053b9ebfcedf89ecb8bf2972974e98700c", "token": "FXS" } ], "gasFlame": [ { "children": [ { "children": [ { "children": [], "depth": 0, "name": "Initial Gas", "value": 31400 }, { "children": [ { "children": [ { "children": [], "depth": 2, "name": "isSolver", "value": 2431 } ], "depth": 1, "name": "isSolver", "value": 7365 }, { "children": [], "depth": 1, "name": "0xbf293f65", "value": 3000 }, { "children": [ { "children": [], "depth": 2, "name": "transferFrom", "value": 15418 } ], "depth": 1, "name": "transferFromAccounts", "value": 19868 }, { "children": [ { "children": [], "depth": 2, "name": "getReserves", "value": 2517 }, { "children": [], "depth": 2, "name": "transferFrom", "value": 15025 }, { "children": [ { "children": [], "depth": 3, "name": "transfer", "value": 80365 }, { "children": [], "depth": 3, "name": "balanceOf", "value": 665 }, { "children": [], "depth": 3, "name": "balanceOf", "value": 534 } ], "depth": 2, "name": "swap", "value": 115760 } ], "depth": 1, "name": "swapTokensForExactTokens", "value": 146613 }, { "children": [], "depth": 1, "name": "transfer", "value": 76080 } ], "depth": 0, "name": "settle", "value": 306084 } ], "depth": -1, "name": "Actual Gas Used", "value": 331884 }, { "children": [], "depth": -1, "name": "Refunded Gas", "value": 5600 } ], "depth": -2, "name": "Total Gas", "value": 337484 } ], "highlightIdMap": {}, "invocationFlow": [ { "children": [ { "children": [ { "children": [ { "children": [], "evmDepth": 2, "id": 2, "order": 2 } ], "evmDepth": 1, "id": 1, "order": 1 }, { "children": [], "evmDepth": 1, "id": 3, "order": 3 }, { "children": [], "evmDepth": 1, "id": 4, "order": 4 }, { "children": [ { "children": [ { "children": [], "evmDepth": 3, "id": 7, "order": 7 } ], "evmDepth": 2, "id": 6, "order": 6 } ], "evmDepth": 1, "id": 5, "order": 5 }, { "children": [ { "children": [], "evmDepth": 2, "id": 9, "order": 9 }, { "children": [ { "children": [], "evmDepth": 3, "id": 11, "order": 11 } ], "evmDepth": 2, "id": 10, "order": 10 }, { "children": [ { "children": [ { "children": [], "evmDepth": 4, "id": 14, "order": 14 }, { "children": [], "evmDepth": 4, "id": 15, "order": 15 }, { "children": [], "evmDepth": 4, "id": 16, "order": 16 } ], "evmDepth": 3, "id": 13, "order": 13 }, { "children": [], "evmDepth": 3, "id": 17, "order": 17 }, { "children": [], "evmDepth": 3, "id": 18, "order": 18 }, { "children": [], "evmDepth": 3, "id": 19, "order": 19 }, { "children": [], "evmDepth": 3, "id": 20, "order": 20 } ], "evmDepth": 2, "id": 12, "order": 12 } ], "evmDepth": 1, "id": 8, "order": 8 }, { "children": [], "evmDepth": 1, "id": 21, "order": 21 }, { "children": [ { "children": [], "evmDepth": 2, "id": 23, "order": 23 }, { "children": [], "evmDepth": 2, "id": 24, "order": 24 }, { "children": [], "evmDepth": 2, "id": 25, "order": 25 } ], "evmDepth": 1, "id": 22, "order": 22 }, { "children": [], "evmDepth": 1, "id": 26, "order": 26 } ], "evmDepth": 0, "id": 0, "order": 0 } ], "evmDepth": -1, "id": -1, "order": -1 } ], "nodeCount": { "invocationsCount": 27, "tidyInvocationsCount": 21 }, "parentIdMap": { "0": -1, "1": 0, "2": 1, "3": 0, "4": 0, "5": 0, "6": 5, "7": 6, "8": 0, "9": 8, "10": 8, "11": 10, "12": 8, "13": 12, "14": 13, "15": 13, "16": 13, "17": 12, "18": 12, "19": 12, "20": 12, "21": 0, "22": 0, "23": 22, "24": 22, "25": 22, "26": 0 }, "rootIdMap": { "0": -1 }, "tidyInvocationFlow": [ { "children": [ { "children": [ { "children": [], "evmDepth": 1, "id": 4, "order": 1 }, { "children": [ { "children": [ { "children": [], "evmDepth": 3, "id": 7, "order": 4 } ], "evmDepth": 2, "id": 6, "order": 3 } ], "evmDepth": 1, "id": 5, "order": 2 }, { "children": [ { "children": [ { "children": [], "evmDepth": 3, "id": 11, "order": 7 } ], "evmDepth": 2, "id": 10, "order": 6 }, { "children": [ { "children": [ { "children": [], "evmDepth": 4, "id": 14, "order": 10 }, { "children": [], "evmDepth": 4, "id": 15, "order": 11 }, { "children": [], "evmDepth": 4, "id": 16, "order": 12 } ], "evmDepth": 3, "id": 13, "order": 9 }, { "children": [], "evmDepth": 3, "id": 19, "order": 13 }, { "children": [], "evmDepth": 3, "id": 20, "order": 14 } ], "evmDepth": 2, "id": 12, "order": 8 } ], "evmDepth": 1, "id": 8, "order": 5 }, { "children": [], "evmDepth": 1, "id": 21, "order": 15 }, { "children": [ { "children": [], "evmDepth": 2, "id": 23, "order": 17 }, { "children": [], "evmDepth": 2, "id": 24, "order": 18 }, { "children": [], "evmDepth": 2, "id": 25, "order": 19 } ], "evmDepth": 1, "id": 22, "order": 16 }, { "children": [], "evmDepth": 1, "id": 26, "order": 20 } ], "evmDepth": 0, "id": 0, "order": 0 } ], "evmDepth": -1, "id": -1, "order": -1 } ] } } ```

The problem is that their "balanceChanges" are not in WEI and they do not provide proper event logs.

Implementation started in #285 -- and stopped immediately after response data came back.