[#42] container: Make GAS costs more predictable in Delete()

Persisting a transaction is done in 2 stages:
1. TestInvoke
2. Sign and send to the network.
3. At some point the tx is persisted.
Some time passes between 1 and 3, this could lead to different GAS
costs. It is a known issue for container delete: different epoch can
have different size in bytes and thus different cost to store.
Here we introduce fixed-length encoding for integers, so that the
problem can be avoided.

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2023-10-05 15:01:30 +03:00 committed by Alex Vanin
parent 2be81b1def
commit bab6b619d0
2 changed files with 13 additions and 5 deletions

View file

@ -343,6 +343,11 @@ type DelInfo struct {
Epoch int
}
type delInfo struct {
Owner []byte
Epoch []byte
}
// DeletionInfo method returns container deletion info.
// If the container had never existed, NotFoundError is throwed.
// It can be used to check whether non-existing container was indeed deleted
@ -354,7 +359,12 @@ func DeletionInfo(containerID []byte) DelInfo {
if data == nil {
panic(NotFoundError)
}
return std.Deserialize(data).(DelInfo)
d := std.Deserialize(data).(delInfo)
return DelInfo{
Owner: d.Owner,
Epoch: common.FromFixedWidth64(d.Epoch),
}
}
// Get method returns a structure that contains a stable marshaled Container structure,
@ -631,9 +641,9 @@ func removeContainer(ctx storage.Context, id []byte, owner []byte) {
graveKey := append([]byte{graveKeyPrefix}, id...)
netmapContractAddr := storage.Get(ctx, netmapContractKey).(interop.Hash160)
epoch := contract.Call(netmapContractAddr, "epoch", contract.ReadOnly).(int)
common.SetSerialized(ctx, graveKey, DelInfo{
common.SetSerialized(ctx, graveKey, delInfo{
Owner: owner,
Epoch: epoch,
Epoch: common.ToFixedWidth64(epoch),
})
}

View file

@ -283,8 +283,6 @@ func TestContainerDelete(t *testing.T) {
})
t.Run("gas costs are the same for different epochs", func(t *testing.T) {
t.Skip()
_, cnt2 := addContainer(t, c, cBal)
args := []interface{}{cnt2.id[:], cnt2.sig, cnt2.pub, cnt2.token}