Wallet balance always zero during container creation #115
Labels
No labels
P0
P1
P2
P3
good first issue
Infrastructure
blocked
bug
config
discussion
documentation
duplicate
enhancement
go
help wanted
internal
invalid
kludge
observability
perfomance
question
refactoring
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: TrueCloudLab/frostfs-contract#115
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Expected Behavior
We should be able to create containers when
ContainerFee
is configured to a non-zero value (given that subject's wallet has enough GAS).Current Behavior
We can not create containers if a fee is required. This happens because
balance
seen by container_contract is always zero - regardless of actual wallet's balance.Possible Solution
No fix can be suggested by reporter. Further solutions shall be up to developers.
Steps to Reproduce (for bugs)
Create a container with default frostfs-dev-env config (
ContainerFee = 0
): everything is OKSet non-zero container fee:
Can't create containers anymore:
Even though we have enough GAS:
Context
Many thanks to @aarifullin for help with debugging! (private chat)
We have confirmed that container_contract always sees zero value instead of wallet balance by modifying the contract and checking neo-go logs:
ownerID
confirms that the contract operates on the wallet we expect it to, but loggedbalance
is always 0.Ayrat suggested that this bug may be caused by permissions mismatch:
balanceOf
must be safePutNamed
method (where this error occurs) is not marked as safe - anddata
in the following snippet is always nil even though the correspondingkey
exists:func getAccount(ctx storage.Context, key any) Account {
data := storage.Get(ctx, key)
if data != nil {
acc := std.Deserialize(data.([]byte)).(account)
return Account{
Balance: common.FromFixedWidth64(acc.Balance),
Until: common.FromFixedWidth64(acc.Until),
Parent: acc.Parent,
}
}
return Account{}
}
Regression
Can't be assessed by reporter.
Your Environment
uname -a
):Linux hostname 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 GNU/Linux
ContainerFee > 0
? #2This fee should be deposited to the
balance
contract.During container creation the GAS is transferred to the alphabet nodes from the balance contract via
transferX
methodhttps://git.frostfs.info/TrueCloudLab/frostfs-contract/src/branch/master/container/container_contract.go#L219
I'm not sure if I understand your comment. Was it addressed to me or is it some kind of note to self during debug?
Balance check (which panics) happens before
transferX
call you linked, and it checks the balance of the wallet that calledcontainer create
. Were you trying to point to some misconfiguration on my end?What I am trying to say is that wallet balance is different from its deposit in the
balance
contract, they are unrelated to each other.Are we on the same note here?
What I am trying to say is that wallet balance is different from its deposit in the
balance
contract, they are unrelated to each other.Are we on the same note here?
What I am trying to say is that wallet balance is different from its deposit in the
balance
contract, they are unrelated to each other.Are we on the same note here?
This was unexpected. I guess I need to do some reading on the
balance
contract.In the end, whose responsibility is it to make that deposit? Should it be done automatically by
frostfs-cli container create
or should the user do it beforehand in some other way?They are similar, actually.
Wallet balance is its GAS balance, that is some number in the native GAS contract.
Balance contract is similar, but it is our contract. Balance contract has its own hash, and thus has its own balance in the GAS contract!
When we transfer our GAS to the balance contract it starts to own them, but, being a contract, it remembers whom it has received this funds from.
The important part here is that
balance
contract governs how this GAS is being distributed: node can make a deposit, alphabet nodes can take the reward. This would not be possible with the native contract in the presence of malicious actors.A client is reponsible.
frostfs-adm morph dump-hashes
command can give you the hash of thebalance
contract.neo-go wallet nep17 transfer
command can allow you to transfer funds from your wallet to thebalance
contract.Notes from IRL chat:
frostfs-cli container create
is not possible because by designfrostfs-cli
should interact only with FrostFS storage API and is not aware of sidechain RPC endpointsfrostfs-adm
may be useful (if this functionality is not already covered by existing ones)