[#45] balance: Fix inconsistent fee of transfer operations
Signed-off-by: Alex Vanin <a.vanin@yadro.com>
This commit is contained in:
parent
5124555f05
commit
e834a66117
2 changed files with 31 additions and 25 deletions
|
@ -31,6 +31,13 @@ type (
|
||||||
// account wasn't burnt.
|
// account wasn't burnt.
|
||||||
Parent []byte
|
Parent []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// account is a stored view of Account with fixed int size
|
||||||
|
account struct {
|
||||||
|
Balance []byte
|
||||||
|
Until []byte
|
||||||
|
Parent []byte
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -69,7 +76,7 @@ func _deploy(data interface{}, isUpdate bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
args := data.(struct {
|
args := data.(struct {
|
||||||
//TODO(@acid-ant): #9 remove notaryDisabled in future version
|
// TODO(@acid-ant): #9 remove notaryDisabled in future version
|
||||||
notaryDisabled bool
|
notaryDisabled bool
|
||||||
addrNetmap interop.Hash160
|
addrNetmap interop.Hash160
|
||||||
addrContainer interop.Hash160
|
addrContainer interop.Hash160
|
||||||
|
@ -173,7 +180,7 @@ func Lock(txDetails []byte, from, to interop.Hash160, amount, until int) {
|
||||||
Parent: from,
|
Parent: from,
|
||||||
}
|
}
|
||||||
|
|
||||||
common.SetSerialized(ctx, to, lockAccount)
|
setAccount(ctx, to, lockAccount)
|
||||||
|
|
||||||
result := token.transfer(ctx, from, to, amount, true, details)
|
result := token.transfer(ctx, from, to, amount, true, details)
|
||||||
if !result {
|
if !result {
|
||||||
|
@ -310,14 +317,14 @@ func (t Token) transfer(ctx storage.Context, from, to interop.Hash160, amount in
|
||||||
storage.Delete(ctx, from)
|
storage.Delete(ctx, from)
|
||||||
} else {
|
} else {
|
||||||
amountFrom.Balance = amountFrom.Balance - amount // neo-go#953
|
amountFrom.Balance = amountFrom.Balance - amount // neo-go#953
|
||||||
common.SetSerialized(ctx, from, amountFrom)
|
setAccount(ctx, from, amountFrom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(to) == 20 {
|
if len(to) == 20 {
|
||||||
amountTo := getAccount(ctx, to)
|
amountTo := getAccount(ctx, to)
|
||||||
amountTo.Balance = amountTo.Balance + amount // neo-go#953
|
amountTo.Balance = amountTo.Balance + amount // neo-go#953
|
||||||
common.SetSerialized(ctx, to, amountTo)
|
setAccount(ctx, to, amountTo)
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime.Notify("Transfer", from, to, amount)
|
runtime.Notify("Transfer", from, to, amount)
|
||||||
|
@ -371,8 +378,21 @@ func isUsableAddress(addr interop.Hash160) bool {
|
||||||
func getAccount(ctx storage.Context, key interface{}) Account {
|
func getAccount(ctx storage.Context, key interface{}) Account {
|
||||||
data := storage.Get(ctx, key)
|
data := storage.Get(ctx, key)
|
||||||
if data != nil {
|
if data != nil {
|
||||||
return std.Deserialize(data.([]byte)).(Account)
|
acc := std.Deserialize(data.([]byte)).(account)
|
||||||
|
return Account{
|
||||||
|
Balance: common.FromFixedWidth64(acc.Balance),
|
||||||
|
Until: common.FromFixedWidth64(acc.Until),
|
||||||
|
Parent: acc.Parent,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Account{}
|
return Account{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setAccount(ctx storage.Context, key interface{}, acc Account) {
|
||||||
|
common.SetSerialized(ctx, key, account{
|
||||||
|
Balance: common.ToFixedWidth64(acc.Balance),
|
||||||
|
Until: common.ToFixedWidth64(acc.Until),
|
||||||
|
Parent: acc.Parent,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -59,24 +59,6 @@ func newContainerInvoker(t *testing.T) (*neotest.ContractInvoker, *neotest.Contr
|
||||||
return e.CommitteeInvoker(ctrContainer.Hash), e.CommitteeInvoker(ctrBalance.Hash), e.CommitteeInvoker(ctrNetmap.Hash)
|
return e.CommitteeInvoker(ctrContainer.Hash), e.CommitteeInvoker(ctrBalance.Hash), e.CommitteeInvoker(ctrNetmap.Hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(alexvanin): remove this after fix of inconsistent tx cost in balance contract
|
|
||||||
func newFreeContainerInvoker(t *testing.T) (*neotest.ContractInvoker, *neotest.ContractInvoker, *neotest.ContractInvoker) {
|
|
||||||
e := newExecutor(t)
|
|
||||||
|
|
||||||
ctrNNS := neotest.CompileFile(t, e.CommitteeHash, nnsPath, path.Join(nnsPath, "config.yml"))
|
|
||||||
ctrNetmap := neotest.CompileFile(t, e.CommitteeHash, netmapPath, path.Join(netmapPath, "config.yml"))
|
|
||||||
ctrBalance := neotest.CompileFile(t, e.CommitteeHash, balancePath, path.Join(balancePath, "config.yml"))
|
|
||||||
ctrContainer := neotest.CompileFile(t, e.CommitteeHash, containerPath, path.Join(containerPath, "config.yml"))
|
|
||||||
|
|
||||||
e.DeployContract(t, ctrNNS, nil)
|
|
||||||
deployNetmapContract(t, e, ctrBalance.Hash, ctrContainer.Hash,
|
|
||||||
container.RegistrationFeeKey, int64(0),
|
|
||||||
container.AliasFeeKey, int64(0))
|
|
||||||
deployBalanceContract(t, e, ctrNetmap.Hash, ctrContainer.Hash)
|
|
||||||
deployContainerContract(t, e, ctrNetmap.Hash, ctrBalance.Hash, ctrNNS.Hash)
|
|
||||||
return e.CommitteeInvoker(ctrContainer.Hash), e.CommitteeInvoker(ctrBalance.Hash), e.CommitteeInvoker(ctrNetmap.Hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
func setContainerOwner(c []byte, acc neotest.Signer) {
|
func setContainerOwner(c []byte, acc neotest.Signer) {
|
||||||
copy(c[6:], signerToOwner(acc))
|
copy(c[6:], signerToOwner(acc))
|
||||||
}
|
}
|
||||||
|
@ -253,10 +235,14 @@ func TestContainerPut(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("gas costs are the same for all containers in block", func(t *testing.T) {
|
t.Run("gas costs are the same for all containers in block", func(t *testing.T) {
|
||||||
c, _, _ := newFreeContainerInvoker(t)
|
const (
|
||||||
const containerPerBlock = 512
|
containerPerBlock = 512
|
||||||
|
totalContainers = containerPerBlock + 1
|
||||||
|
totalPrice = containerFee + containerAliasFee
|
||||||
|
)
|
||||||
|
|
||||||
acc := c.NewAccount(t)
|
acc := c.NewAccount(t)
|
||||||
|
balanceMint(t, cBal, acc, totalPrice*totalContainers, []byte{})
|
||||||
cnt := dummyContainer(acc)
|
cnt := dummyContainer(acc)
|
||||||
putArgs := []interface{}{cnt.value, cnt.sig, cnt.pub, cnt.token, "precreated", ""}
|
putArgs := []interface{}{cnt.value, cnt.sig, cnt.pub, cnt.token, "precreated", ""}
|
||||||
c.Invoke(t, stackitem.Null{}, "putNamed", putArgs...)
|
c.Invoke(t, stackitem.Null{}, "putNamed", putArgs...)
|
||||||
|
|
Loading…
Reference in a new issue