-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
near and storage tracing - wip #7
base: main
Are you sure you want to change the base?
Conversation
ref-exchange/src/account_deposit.rs
Outdated
pub amount: Balance, | ||
/// NEAR sent to the exchange. | ||
/// Used for storage and trading. | ||
pub ynear: Balance, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
renaming amount
-> ynear
to enhance code readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will use near_amount
ref-exchange/src/lib.rs
Outdated
@@ -193,6 +188,8 @@ impl Contract { | |||
deposits.add(token_out.as_ref().clone(), amount_out); | |||
self.deposited_amounts.insert(&sender_id, &deposits); | |||
self.pools.replace(pool_id, &pool); | |||
deposits.update_storage(start_storage); | |||
self.deposited_amounts.insert(&sender_id, &deposits); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To verify: I think we need to insert 2 times:
- once in line 194 (prev)
- second time here.
This is because we won't trace properly new storage until we insert the record into the storage tree.
Alternative would be to refactor the AccountDeposit and moveynear
to another, top-level map.
ref-exchange/src/account_deposit.rs
Outdated
pub(crate) fn update_storage(&self, from: &AccountDeposit, tx_start_storage: StorageUsage) { | ||
let mut d = self.get_account_depoists(from); | ||
d.update_storage(tx_start_storage); | ||
self.deposited_amounts.insert(from, &d); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about renaming self.deposited_amounts
to self.deposits
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename to accounts
ref-exchange/src/lib.rs
Outdated
@@ -109,7 +109,7 @@ impl Contract { | |||
let mut pool = self.pools.get(pool_id).expect("ERR_NO_POOL"); | |||
// Add amounts given to liquidity first. It will return the balanced amounts. | |||
pool.add_liquidity(&sender_id, &mut amounts); | |||
let mut deposits = self.deposited_amounts.get(&sender_id).unwrap_or_default(); | |||
let mut deposits = self.get_account_depoists(&sender_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add liquidity should early fail if account is not registered.
68c7bc8
to
379ebde
Compare
ref-exchange/src/lib.rs
Outdated
storage_cost <= env::attached_deposit(), | ||
"ERR_STORAGE_DEPOSIT" | ||
); | ||
// TODO: update deposit handling | ||
let refund = env::attached_deposit() - storage_cost; | ||
if refund > 0 { | ||
Promise::new(env::predecessor_account_id()).transfer(refund); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refund won't work, because I added assert_one_yocto()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moreover - it's easier to standarize here to use internal storage tracking + assert_one_yocto
, rather than asking user for unknown required NEAR attachment.
ref-exchange/src/account_deposit.rs
Outdated
const MIN_ACCOUNT_DEPOSIT_LENGTH: u128 = MAX_ACCOUNT_LENGTH + 16 + 4; | ||
/// Minimum Account Storage used for account registration. | ||
/// 64 (AccountID bytes) + 2*8 (int32) + byte | ||
pub const INIT_ACCOUNT_STORAGE: StorageUsage = 64 + 16 + 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's bring constants like this - https://github.com/ref-finance/ref-contracts/pull/6/files#diff-445ab9fc382f558a0e9d7831b135b640b79e74be187c7cbdd435b7ecf6e108bbR13 to explain what is happening
379ebde
to
a6ba015
Compare
9eeb1b3
to
ec470c8
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'm not 100% sure you actually handled the upgrading - i see direct self.account.get calls.
I think the easiest way is to keep account_deposit as old field and create new lookup map with VersionedAccount. And just when loading - check back if it exists and upgrade.
And let's have a test_upgrade to actually test this upgrade with an old contract that has some state.
/// Account deposits information and storage cost. | ||
#[derive(BorshSerialize, BorshDeserialize, Default)] | ||
#[cfg_attr(feature = "test", derive(Clone))] | ||
pub struct AccountDepositV2 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's rename to Account?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The v1 structure is already named AccountDeposit. So - do you suggest to rename both?
return a; | ||
} | ||
// migrate from V1 | ||
a.storage_used = U64_STORAGE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, this is (MIN_ACCOUNT_DEPOSIT_LENGTH + self.tokens.len() as u128 * (MAX_ACCOUNT_LENGTH + 16)) * env::storage_byte_cost()
(old storage_usage
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW - we don't multiply by env::storage_byte_cost()
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I remember why I don't include the AccountDeposit storage here, please see the comment below (#7 (comment))
* env::storage_byte_cost() | ||
let s = self.storage_used | ||
+ INIT_ACCOUNT_STORAGE // empty account storage | ||
+ (ACC_ID_STORAGE + U64_STORAGE) * self.tokens.len() as u64; // self.tokens storage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just count this inside storage_used? so storage_usage * cost
is just self.storage_used?
also it seems like you are missing cost of storage in general here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because, in self.storage_used
we only account storage used outside of this structure. This is to avoid "double" storing the account. See here: #7 (comment)
#[payable] | ||
pub fn deposit_near(&mut self) { | ||
let sender_id = env::predecessor_account_id(); | ||
let mut acc = self.get_account(&sender_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we register here if not registered? it seems like this will be easier to use than storage_deposit in general case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about it. We have a standard for user / account registration. This function is to make it more clear to deposit more NEAR and not confuse with registration. However if you think that by allowing a registration here, we will improve UX then we can do that.
// pub const NEAR: AccountId = "".to_string(); | ||
|
||
#[derive(BorshDeserialize, BorshSerialize)] | ||
pub enum AccountDeposit { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like more VersionedAccount and Account for the current version.
This way everywhere in the code except in the places where it's used - it's just Account. And VersionedAccount is where need to store/load/upgrade
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, you want to have a LegacyAccount
and Account
? What if we will do another migration? I think having a consecutive versions in struct name is more clear. We will mark all old version Legacy in the comments.
6362de5
to
7e8b9ae
Compare
I've asked @evgenykuzyakov about possible strategies few weeks ago. I think if we won't use indexer then then doing byte computation for figuring out the structure version is too error prone. So, depending which strategy we will take. If we want to do it lazy (so user will do migration when he will use the account next time) then we will need to duplicate the accounts - if we will use indexer then we will do a migration function. We had a chat about it in telegram. Here I wanted to verify the AccountDeposit structure and update. |
#27 adds storage handling without needing to upgrade Account data structure. This fixes the issue short term and removes need to keep track storage_used from it for now. |
Accumulative patches in April
No description provided.