Closed czepluch closed 5 years ago
Tried to use both the bb eth node vpn and my dappcon node, but same problem occurs.
I can't reproduce the error. Your error code points to a reverted onchain Tx No clue what goes wrong here, but it works fine for me atm.
I reproduced the error. I first successfully ran a scenario, then, when I simply want to re-run it, I get the same error.
{
"result": "scenario error",
"event": "Run finished",
"logger": "scenario_player.main",
"level": "error",
"timestamp": "2019-08-16 09:46:51.021767",
"exception": "
Traceback (most recent call last):
File \"/home/pirate/PycharmProjects/ScenarioPlayer/scenario-player/scenario_player/main.py\", line 179, in run
runner.run_scenario()
File \"/home/pirate/PycharmProjects/ScenarioPlayer/scenario-player/scenario_player/runner.py\", line 224, in run_scenario
wait_for_txs(self.client, fund_tx | ud_token_tx | mint_tx)
File \"/home/pirate/PycharmProjects/ScenarioPlayer/scenario-player/scenario_player/utils/legacy.py\", line 193, in wait_for_txs
raise ScenarioTxError(f\"Transaction {encode_hex(txhash)} failed.\")
scenario_player.exceptions.legacy.ScenarioTxError: Transaction 0xe8195f306388726e7810eb84d5e1e1bac96fc884eb67ad13fc3c09998bbd77e3 failed."
}
Now it constantly fails with this error
@Dominik1999 That's wired since your "first" deposit Tx went through (https://goerli.etherscan.io/tx/0xb74dcdfa5820bbf9d2bf38b395c5eb83e6808f0d7ed505ca22a2b548d1d58156) but the second one failed. Which scenario did you run?
Edit: Ok I'll try to reproduce it as well and have a look
I ran https://github.com/raiden-network/raiden/pull/4619/files
but it also happens with any other scenario now. Probably the deposit is not increasing, because the SP uses the same nodes (Eth addresses) and tries to deposit as defined in the scenario
one of these require()
isn't fulfilled probably.
function deposit(address beneficiary, uint256 new_total_deposit)
external
{
require(new_total_deposit > total_deposit[beneficiary], "deposit not increasing");
// Calculate the actual amount of tokens that will be transferred
uint256 added_deposit = new_total_deposit - total_deposit[beneficiary];
balances[beneficiary] += added_deposit;
total_deposit[beneficiary] += added_deposit;
// Update whole_balance, but take care against overflows.
require(whole_balance + added_deposit >= whole_balance, "overflowing deposit");
whole_balance += added_deposit;
// Decline deposit if the whole balance is bigger than the limit.
require(whole_balance <= whole_balance_limit, "too much deposit");
// Actual transfer.
require(token.transferFrom(msg.sender, address(this), added_deposit), "tokens didn't transfer");
Mhh I still can't reproduce the error.
Not even if I reuse already used addresses on purpose...
@Dominik1999 could you provide me with the exact command you ran as well as the content of your ~./raiden/scenario-player/scenarios/pfs7_multiple_payments
folder?
I even ran the scenario without any trouble even though I used previously used Addresses on purpose...
Edit:
(Since we're always deploying a new token for every run there should be no conflict with already existing balances in any SC.)
@Dominik1999 what you explain is exactly what happened to me too.
Running scenarios on 0.3.1
, I cannot reproduce this locally.
Since I won't be able to fix it until Wednesday, I'll unassign me for now.
So apparently we still have trouble with deposit function calls. Some of them fail with no obvious pattern.
You can check my tx history here. All Tx in block 1209528 & 1209530 belong to one scenario player run. (Only one deposit fails) Another player-run are the Tx in block 1209685 and 1209686. (Three deposits fail)
@hackaugusto could you please also have a look at it?
The initial comment has the following stacktrace:
Traceback (most recent call last):
File "/home/jacob/dev/venvs/sp_venv/lib/python3.7/site-packages/scenario_player/main.py", line 179, in run
runner.ru
n_scenario()
File "/home/jacob/dev/venvs/sp_venv/lib/python3.7/site-packages/scenario_player/runner.py", line 224, in run_scenario
wait_for_txs(self.client, fund_tx |
ud_token_tx | mint_tx)
File "/home/jacob/dev/venvs/sp_venv/lib/python3.7/site-packages/scenario_player/utils/legacy.py", line 193, in wait_for_txs
raise ScenarioTxErro
r(f"Transaction {encode_hex(txhash)} failed.")
scenario_player.exceptions.legacy.ScenarioTxError: Transaction 0xb508c34739260b6031e96deed105783edc0306c9b7addbe470789656c2f91c
e4 failed.
desc | value |
---|---|
tx.hash | 0xb508c34739260b6031e96deed105783edc0306c9b7addbe470789656c2f91c |
mined at block | 1124179 |
msg.sender | 0x0bae0289AAA26845224F528F9B9DefE69e01606E |
UserDeposit address | 0xdE6c9977D903Ff978E24f06DC4d78FA49486094E |
Token address | 0x2D64D0d6C3892f58B7698C8520ba12ee02998F00 |
function | deposit |
beneficiary | 0x263726Baa4606153cEc023fd294E55e15ec391B5 |
new_total_deposit | 5000 |
These are the requires for the deposit
function:
require(new_total_deposit > total_deposit[beneficiary], "deposit not increasing");
require(whole_balance + added_deposit >= whole_balance, "overflowing deposit");
require(whole_balance <= whole_balance_limit, "too much deposit");
require(token.transferFrom(msg.sender, address(this), added_deposit), "tokens didn't transfer");
And these are the requires for the transferFrom
:
require(balances[_from] >= _value);
require(allowed[_from][msg.sender] >= _value);
require(_value > 0);
I used the following setup:
from web3 import HTTPProvider, Web3
from raiden_contracts.contract_manager import ContractManager, contracts_precompiled_path
from raiden_contracts.constants import CONTRACT_CUSTOM_TOKEN, CONTRACT_USER_DEPOSIT
from eth_utils import to_checksum_address
url ='<redacted>'
web3 = Web3(HTTPProvider(url))
contract_manager = ContractManager(contracts_precompiled_path())
ud = web3.eth.contract(abi=contract_manager.get_contract_abi(CONTRACT_USER_DEPOSIT), address='0xdE6c9977D903Ff978E24f06DC4d78FA49486094E')
token = web3.eth.contract(abi=contract_manager.get_contract_abi(CONTRACT_CUSTOM_TOKEN), address=ud.functions.token().call())
And executed the following queries:
>>> ud.functions.total_deposit('0x263726Baa4606153cEc023fd294E55e15ec391B5').call(block_identifier=1124179)
0
>>> ud.functions.whole_balance().call(block_identifier=1124179)
47000000000000004041000
>>> ud.functions.whole_balance_limit().call(block_identifier=1124179)
115792089237316195423570985008687907853269984665640564039457584007913129639935
>>> token.functions.balanceOf('0x0bae0289AAA26845224F528F9B9DefE69e01606E').call(block_identifier=1124179)
0
>>> token.functions.allowance('0x0bae0289AAA26845224F528F9B9DefE69e01606E', '0xdE6c9977D903Ff978E24f06DC4d78FA49486094E').call(block_identifier=1124179)
15000
So, the problem is that the address 0x0bae0289AAA26845224F528F9B9DefE69e01606E
doesn't have any tokens to transfer.
@hackaugusto I think there is a misunderstanding. In Jacobs code the Token
is "0xb06bA27e1cc31aa7d16f0B9303Da6Bf23885Fd7F"
. And the beneficiary does have 10.000 of those tokens.
The Token Address thing that you pulled out of the logs is something else (pls don't ask me what it is :D )
So, I followed the logs, and the scenario player is calling the mint
function, turns out the address had a balance of 10000
until the block 1124178
. At the block 1124179
the following happened:
from web3.utils.abi import filter_by_type
from eth_utils import event_abi_to_log_topic
from web3.utils.events import get_event_data
topic_to_event_abi = {event_abi_to_log_topic(event_abi): event_abi for event_abi in filter_by_type('event', token.events.abi)}
[get_event_data(topic_to_event_abi[log['topics'][0]], log) for log in web3.eth.getLogs({'address': '0x2D64D0d6C3892f58B7698C8520ba12ee02998F00', 'fromBlock': 1124178, 'toBlock': 1124190})]
The above prints:
[AttributeDict({'args': AttributeDict({'_from': '0x0bae0289AAA26845224F528F9B9DefE69e01606E', '_to': '0xdE6c9977D903Ff978E24f06DC4d78FA49486094E', '_value': 5000}), 'event': 'Transfer', 'logIndex': 44, 'transactionIndex': 44, 'transactionHash': HexBytes('0x926a169a3dd41b99d1db7709bda3410bd24695d19268de28de2dbdafe4dbb5c0'), 'address': '0x2D64D0d6C3892f58B7698C8520ba12ee02998F00', 'blockHash': HexBytes('0xc871d5fff14637cbbcf4a07e2ca4eb1f274f9a49de8bddd8c992cc37fc3d1e76'), 'blockNumber': 1124179}),
AttributeDict({'args': AttributeDict({'_from': '0x0bae0289AAA26845224F528F9B9DefE69e01606E', '_to': '0xdE6c9977D903Ff978E24f06DC4d78FA49486094E', '_value': 5000}), 'event': 'Transfer', 'logIndex': 46, 'transactionIndex': 46, 'transactionHash': HexBytes('0xf6e550196aa35cab2cccb22d2346e834963082138487acef4ae87baa3a0822ac'), 'address': '0x2D64D0d6C3892f58B7698C8520ba12ee02998F00', 'blockHash': HexBytes('0xc871d5fff14637cbbcf4a07e2ca4eb1f274f9a49de8bddd8c992cc37fc3d1e76'), 'blockNumber': 1124179})]
Transactions:
status | txidx | txhash |
---|---|---|
success | 44 | 0xf6e550196aa35cab2cccb22d2346e834963082138487acef4ae87baa3a0822ac |
success | 46 | 0x926a169a3dd41b99d1db7709bda3410bd24695d19268de28de2dbdafe4dbb5c0 |
revert | 50 | 0xb508c34739260b6031e96deed105783edc0306c9b7addbe470789656c2f91ce4 |
So it makes sense for the third one to fail.
@eorituz I pulled the address directly from the user deposit smart contract, calling ud.functions.token().call()
@hackaugusto thanks, that makes sense... So to me, it looks like something more fundamental is broken. The handling around when which, for whom and how much tokens should be minted. (During the PFS7 scenario run e.g. plenty of tokens get minted but never used?)
~@ulope found the problem~
~The problem is that Contract.mint
uses self.config.token.max_funding - balance
, while UserDepositContract.deposit
uses self.config.settings.services.udc.token.balance_per_node
~
~The first defaults to DEFAULT_TOKEN_BALANCE_FUND = 10_000
, while the second is set in the scenario to balance_per_node: 20000
~
Edit: It was close, but not the exact problem in the issue. The balance_per_node
was not set, it used the default of 5_000
. Nevertheless there are 5 nodes that need a deposit of 5_000
but only 10_000
are minted, the code has to be changed to mint the amount of tokens required proportionally to the number of nodes.
Edit, some updates based on the dev branch:
~self.config.token.max_funding
defaults to 50_000 tokens.~ (These values are not important)
General workflow of the scenario player:
run_scenario
initialize_nodes
: Run nodes and fund with etherinitialize_udc
: Sets allowance and mint for the scenario runner node.initialize_scenario_token
: Load the token config, then for each address it will mint and deposit on the udc.The call to UserDepositContract.mint
delegates to Contract.mint
, which does the following:
Relevant logs for the allowance/mint/deposit (note that the first two entries are for the allowance, the use of the deposit
word is a typo)
From a timing perspective this could have been introduced by https://github.com/raiden-network/scenario-player/pull/221 released with https://github.com/raiden-network/scenario-player/releases/tag/v0.3.0
@hackaugusto Here's a proper problem description.
I ran this scenario pfs7_multiple_payments.zip it's basically the same as jacob suggested but with settings.services.udc.token.balance_per_node = token.balance_min = 20000
scenario_player --chain goerli:http://geth.goerli.ethnodes.brainbot.com:8545 run --keystore-file keystore/UTC--1 --password 123 --no-ui /home/oliver/Arbeit/github/scenario-player/test_scenarios/pfs7_multiple_payments.yaml
Should be latest Dev
(scenario_player) oliver@bbpc:~/Arbeit/github/scenario-player$ git log
commit 60b359899a3385d82e2d71da8f57dacce8789111 (HEAD -> dev, upstream/dev, origin/dev)
Author: DevOpsBot <contact@brainbot.li>
Date: Fri Aug 23 08:04:57 2019 +0000
'Sync Branch Versions.'
(scenario_player) oliver@bbpc:~/Arbeit/github/scenario-player$ raiden version
{
"raiden": "0.100.5.dev3+g3a6642643",
"raiden_db_version": 23,
"python_implementation": "CPython",
"python_version": "3.7.1",
"system": "Linux 64bit_ELF 4.15.0-58-generic",
"architecture": "x86_64",
"distribution": "source"
}
If I set the ~/.raiden/scenario-player/scenarios/pfs7/run_number.txt
value to 1 I face another problem. (The run_number is used to generate the deterministic priv keys of the nodes. So I "reused" nodes on purpose)
scenario_player.exceptions.legacy.ScenarioError: Failed to start Raiden node 0
Logs: logs_failed_to_start_raien.zip
I'm not sure if it is related or an issue on it's own...
Seems @hackaugusto found the issue.
Contract.balance
(which is inherited by Token
and UserDepositContract
) is querying the account's eth balance not the token balance:
https://github.com/raiden-network/scenario-player/blob/3f87cc464cf8974a3ac69acc6266336d5edd70ac/scenario_player/utils/token.py#L39-L40
The scenario player logs don't have enough information for me to pin down exactly what happened. So I fetched all logs from the smart contract:
from collections import defaultdict
from eth_utils import to_hex
token_address = '0x2D64D0d6C3892f58B7698C8520ba12ee02998F00'
scenario_node_address = '0x0bae0289AAA26845224F528F9B9DefE69e01606E'
deployed_at = 1008864
testing_up_to = 1124190
sender_transaction = defaultdict(list)
hash_to_log = defaultdict(list)
all_logs = web3.eth.getLogs({'address': token_address, 'fromBlock': deployed_at, 'toBlock': testing_up_to})
decoded_logs = [get_event_data(topic_to_event_abi[log['topics'][0]], log) for log in all_logs]
transactions = [web3.eth.getTransaction(l['transactionHash']) for l in decoded_logs]
for t in transactions:
sender_transaction[t['from']].append(t)
for l in decoded_logs:
hash_to_log[l['transactionHash']].append(l)
events_from_scenario = [hash_to_log[t['hash']] for t in sender_transaction[scenario_node_address]]
result = 0
for t, h, v in [(e['event'], e['transactionHash'], e['args'].get('_value') or e['args'].get('_num')) for e in events_from_scenario]:
if t == 'Transfer': result -= v
if t == 'Minted': result += v
print(result, to_hex(result))
result
is 0, here are the events.
Here are the balances of interest for the corresponding run (The same address was used multiple times, it first minted 500000 tokens and gradually this balance decreased, until tests runs to fail):
function | balance | tx_hash |
---|---|---|
approve | 0 | 0x847223ba1edde49c9d8cfe6bbb944f832527a3b25d230ec1efd175bd538ca3d6 |
mintFor | 10000 | 0x53864d0566f21165a717f79ce9e3ddd224e2e6ea8af24fe4b4df9370cefb5940 |
deposit | 5000 | 0x926a169a3dd41b99d1db7709bda3410bd24695d19268de28de2dbdafe4dbb5c0 |
deposit | 0 | 0xf6e550196aa35cab2cccb22d2346e834963082138487acef4ae87baa3a0822ac |
The important thing is that the hashes match above match the ones from above. And now its known all the transactions for the given scenario run.
Okay, I found the problem. The explanation bellow assumes the code from v0.3.0-dev
(this is important because of the values in the constants.py
):
UDC
, it is for the token used for the channels in the scenario.mint
that is useful for the run is done during _initialize_udc
. This will end up executing this code.self.config.token.max_funding - self.balance
. self.balance
is probably mistakenly the ether balance of the UDC smart contract, which is always zero. This means the amount of tokens is always max_funding
.The solution here should be simple, just like update allowance, a update mint of sort has to be introduced, and replace the call to mint that is not enough.
Description
Today when trying to start a new scenario I run into the error shown in the attached logfile. scenario-player-run_pfs7_multiple_payments_2019-08-15T16:54:56.log
It seems that a tx fails when trying to call
deposit
in the UDC contract. The problem also happens on old scenarios that I've run earlier today.I tried installing the SP in a fresh venv too, but the problems persists.
This is on latest dev branch of the SP and of Raiden.
Expected Behavior
I expected the SP to start the scenario as usual and to fund the nodes correctly.