Closed rahimklaber closed 4 years ago
That's weird, given that I have this exact test as unit test (test_e2e_trade
), and there I cannot reproduce this. There's not much information here but I'm suspecting it might be something related to matchmaking. Could you reveal the whole stack trace by editing this line in IPv8, change the self._logger.error
to self._logger.exception
, and try again?
I changed the line in IPv8 and got these stack traces.
INFO:MarketTestnetCommunity:We received a match message from a654707e2cbae2313ada9caa2cc947bcca022342 for order 6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14.6 (matched a
gainst a654707e2cbae2313ada9caa2cc947bcca022342.1)
INFO:MatchCache:Scheduling batch match of order 6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14.6
INFO:MatchCache:Processing incoming matches for order 6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14.6
INFO:SingleTradeClearingPolicy:Starting crawl of chain of trader a654707e2cbae2313ada9caa2cc947bcca022342
INFO:TrustChainCommunity:Requesting crawl of node b'da5cf256' (blocks -1 to -1) with id 9188
INFO:TrustChainCommunity:Block validation result <function ValidationResult.partial_next at 0x000002A86710CE58>, [], (Block b'd14ad923' from ...b'da5cf256':7 links .
..b'30303030':0 for {'tick': {'trader_id': 'a654707e2cbae2313ada9caa2cc947bcca022342', 'order_number': 5, 'assets': {'first': {'amount': 10, 'type': 'DUM1'}, 'second
': {'amount': 10, 'type': 'DUM2'}}, 'timeout': 3600, 'timestamp': 1589882687662, 'traded': 0}, 'version': 4} type b'ask')
INFO:TrustChainCommunity:Received crawl request from node b'da5cf256' for range -1--1
INFO:TrustChainCommunity:Sent 1 blocks
ERROR:MarketTestnetCommunity:Task resulted in error: 'b"b\'DUM1\'"'
Traceback (most recent call last):
File "C:\Users\Rahim\Miniconda3\envs\anydex-core\lib\site-packages\pyipv8-2.0.0-py3.7.egg\ipv8\taskmanager.py", line 123, in done_cb
future.result()
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 1618, in received_accept_trade
incoming_address, outgoing_address = self.get_order_addresses(order)
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 594, in get_order_addresses
return (WalletAddress(self.wallets[order.assets.first.asset_id].get_address()),
KeyError: 'b"b\'DUM1\'"'
INFO:MarketTestnetCommunity:Sending match message for order id a654707e2cbae2313ada9caa2cc947bcca022342.2 and tick order id 6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14.
1 to trader a654707e2cbae2313ada9caa2cc947bcca022342
INFO:TrustChainCommunity:Received crawl request from node b'da5cf256' for range -1--1
INFO:TrustChainCommunity:Sent 1 blocks
ERROR:MarketTestnetCommunity:Task resulted in error: '<=' not supported between instances of 'Price' and 'Price'
Traceback (most recent call last):
File "C:\Users\Rahim\Miniconda3\envs\anydex-core\lib\site-packages\pyipv8-2.0.0-py3.7.egg\ipv8\taskmanager.py", line 123, in done_cb
future.result()
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 1436, in received_proposed_trade
result = await self.should_accept_propose_trade(peer, proposed_trade, order)
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 1467, in should_accept_propose_trade
elif not my_order.has_acceptable_price(proposed_trade.assets):
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\order.py", line 293, in has_acceptable_price
my_price <= other_price or abs(float(my_price.frac - other_price.frac)) < 0.0001)) or (
TypeError: '<=' not supported between instances of 'Price' and 'Price'
I changed the __le__
method of Price
to:
def __le__(self, other):
if isinstance(other, Price) and self.num_type == other.num_type and self.denom_type == other.denom_type:
return self.amount <= other.amount
else:
print(self) #line i added
print(other) #line i added
return NotImplemented
and got this back :
1 b'b"b\'DUM2\'"'/b'b"b\'DUM1\'"'
1 b'DUM2'/b'DUM1'
I also tried placing an order and then retrieving it via the api and got this:
{
"orders":[
{
"trader_id":"6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14",
"order_number":1,
"assets":{
"first":{
"amount":10,
"type":"b'DUM1'"
},
"second":{
"amount":10,
"type":"b'DUM2'"
}
},
"reserved_quantity":0,
"traded":0,
"timeout":3600,
"timestamp":1589884778564,
"completed_timestamp":null,
"is_ask":true,
"cancelled":false,
"status":"open"
},
{
"trader_id":"6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14",
"order_number":2,
"assets":{
"first":{
"amount":10,
"type":"b'DUM1'"
},
"second":{
"amount":10,
"type":"b'DUM2'"
}
},
"reserved_quantity":0,
"traded":0,
"timeout":3600,
"timestamp":1589884812204,
"completed_timestamp":null,
"is_ask":true,
"cancelled":false,
"status":"open"
}
]
}
The type here also contains b
so I have a feeling that somewhere bytes
are not being decoded correctly.
I also tried running the test_e2e_trade
and it passed, so that's weird.
It seems indeed to be an encoding issue of the asset type. Are you placing your order using the REST API? If so, how are you doing that?
Yes i am using the REST API. I was using Advanced rest client (api testing tool) to make the requests. I also tried making the requests using these two curl commands :
curl -X PUT http://localhost:8090/asks --data "first_asset_amount=10&second_asset_amount=10&first_asset_type=DUM1&second_asset_type=DUM2"
curl -X PUT http://localhost:8090/bids --data "first_asset_amount=10&second_asset_amount=10&first_asset_type=DUM1&second_asset_type=DUM2"
but the problem persists.
Ok, I think the issue is then related to the REST API, which would explain why the issue does not trigger in the tests (since the tests are not using the REST API). IIRC, the POST request parameters are parsed by asyncio
as bytes
, see here. So, if first_asset_type
turns out to be bytes
, could try to decode the assets type at the code that I linked (both the first one and the second one), and try again?
It seems to be fine there.
I tried to decode first_asset_type
and second_asset_type
, but it turns out that they are strings. I also tried printing them and they seemed fine. The AssetAmount class also checks if asset_id
is a string, so the problems seems to originate form somewhere else.
Apperently the asset_type
is returned as bytes
from the database.
The from_database
function of the order class seems to be the problem.str(asset1_type))
and str(asset2_type))
convert the bytes to string without decoding them, which results in the b
prefix.
I decoded asset1_type
and asset2_type
and I get the asset_type
in the correct format (without b
) when making a request to the orders
endpoint.
This didn't fix the entire issue though, I now get this error when trying to trade:
INFO:MarketTestnetCommunity:Received wallet info from trader 6b218e7fd93c78d3bf7bb43c4f7925e8fa2f2e14
INFO:MarketTestnetCommunity:Wallet info exchanged for transaction 42dd3762146ff1441f065fa8296c99062da3ae39382601e648dab4a6f31bf7aa - starting payments
ERROR:asyncio:Exception in callback TaskManager.register_task.<locals>.done_cb(<Task finishe...or("b'DUM2'")>) at /usr/local/lib/python3.7/dist-packages/pyipv8-2.1.0-py3.7.egg/ipv8/taskmanager.py:120
handle: <Handle TaskManager.register_task.<locals>.done_cb(<Task finishe...or("b'DUM2'")>) at /usr/local/lib/python3.7/dist-packages/pyipv8-2.1.0-py3.7.egg/ipv8/taskmanager.py:120>
Traceback (most recent call last):
File "/usr/lib/python3.7/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.7/dist-packages/pyipv8-2.1.0-py3.7.egg/ipv8/taskmanager.py", line 123, in done_cb
future.result()
File "/home/ubuntu/anydex-core/anydex/core/community.py", line 1714, in send_payment
wallet = self.wallets[asset_id]
KeyError: "b'DUM2'"
I find this weird as the send_payment
function uses the database to find a order and the database uses the from_database
function of the order class (which I fixed) to return an order object, see here and here
Good find! The asset_type
is stored as TEXT
in the sqlite database, so it will return a string indeed in Python 3. This might be something we missed when migrating from Python 2 to Python 3 recently.
One thing you could try is to hook up a real database in test_e2e_trade
and see if you can reproduce it + fix it. See here how to do so. Unfortunately, I don't have much time to help you further with this currently, but a PR for what you found would be greatly appreciated! 👍
Allright I will try to figure it out.
Managed to reproduce this issue with a unit test! Debugging...
Should be fixed by #42 , please let me know if it isn't.
I haven't gotten trades to work between dummy wallets. I assume this is a problem on my end and that it should work since I got trades to work between stellar and ethereum. While the trade goes through and the funds are transferred, I did get this error:
ERROR:asyncio:Exception in callback MarketCommunity.process_tx_payment_block.<locals>.on_tx_done_signed(<Task finishe...public_key'")>) at C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py:703
handle: <Handle MarketCommunity.process_tx_payment_block.<locals>.on_tx_done_signed(<Task finishe...public_key'")>) at C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py:703>
Traceback (most recent call last):
File "C:\Users\Rahim\Miniconda3\envs\anydex-core\lib\asyncio\events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 707, in on_tx_done_signed
block = future.result()
File "C:\Users\Rahim\Desktop\anydex-core\anydex\core\community.py", line 1106, in create_new_tx_done_block
blocks = await self.trustchain.sign_block(peer, peer.public_key.key_to_bin(),
AttributeError: 'NoneType' object has no attribute 'public_key'
I will try to get trades between dummy wallets to work and see if I also get the error then.
I am trying to trade dummy coins between two computers. Every time I try, I get one of these two errors. I tried trading between a windows and an ubuntu machine and between a windows and arch machine.