Closed sergpsu closed 2 years ago
Is the storage modifier in the metadata for your storage call Optional
? (like for example System.ExtrinsicCount
) Then it should return None
if no result is found. If the storage modifier is Default
(like System.Account
) it should return the default value if no result is found and this is expected behaviour.
You can check the metadata properties of a storage function with: substrate.get_metadata_storage_function("System", "ExtrinsicCount")
Thanks! Is there a simple way to know that the default value is returned ( beside copying query() inner logic )?
Yes there is, its a property of the result of the get_metadata_storage_function()
function as I mentioned above..
I mean how can I know that query() returned default object. Currently I've implemented this by creating default object by myself and comparing it to the query() result, but it does not look too elegant
Ok maybe it was a bit confusing (or I misinterpreted the question :) ) but here is an example for storage function System.Account
:
storage_function = substrate.get_metadata_storage_function("System", "Account")
if storage_function.value['modifier'] == 'Default':
# query() will return default value when no result
result = substrate.query("System", "Account")
if storage_function.value['modifier'] == 'Optional':
# query() will return None when no result
result = substrate.query("System", "Account")
Is this what you mean?
No :)
Let me explain in detail. The query(.. param=[somekey])
call returns me such object:
{"account_id":"5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM"}
The problem is that by "looking" at the object I can't say that this is the default storage item, so I can't tell that storage does not contain somekey
. As I wrote above I solved it by constructing object from metadata default value and comparing result with that object, but maybe there is more elegant way to tell that "storage key not found, default object is returned"
Ok I finally get it now 😁
That is indeed valuable information that gets lost now after the query result is returned.
I am considering two solutions, one is to add to the result obj if a result was found, second is a kwarg for query() to exclitly tell the function to not return the default value but None on no result.
I think the kwarg is more elegant and in this case no unnecessary extra decoding is done.
Yes, I like kwarg option too.
Actually 1st option might make sense too in a situation when having default object is fine but also need to know that it's default indeed.
I have the folowing call:
Since key does not exist in storage I expect None to be returned. But the returning value is an impementation of Default trait for my storage value which actually would be fine unless the following. The actual storage value is a struct with the only field of AccountId type and Default implementation fills that field with all zeroes 0x0000000... So if query() call uses default value I expect to receive "000000000...000" hex string but instead "5C4hrfjw9DjXZTzV3MwzrrAr9P1MJhSrvWGWqi1eSuyUpnhM" is returned. So finally there is no way to recognize that storage key was not found at all.