native: optimize totalSupply operations during token burn/mint

We burn GAS in OnPersist for every transaction so some buffer reuse here is
quite natural.

This also doesn't change a lot in the overall TPS picture, maybe adding some
1%.
This commit is contained in:
Roman Khimov 2021-08-03 00:19:23 +03:00
parent dede4fa7b1
commit 64c780ad7a
3 changed files with 16 additions and 11 deletions

View file

@ -108,7 +108,8 @@ func (g *GAS) Initialize(ic *interop.Context) error {
if err := g.nep17TokenNative.Initialize(ic); err != nil { if err := g.nep17TokenNative.Initialize(ic); err != nil {
return err return err
} }
if g.nep17TokenNative.getTotalSupply(ic.DAO).Sign() != 0 { _, totalSupply := g.nep17TokenNative.getTotalSupply(ic.DAO)
if totalSupply.Sign() != 0 {
return errors.New("already initialized") return errors.New("already initialized")
} }
h, err := getStandbyValidatorsHash(ic) h, err := getStandbyValidatorsHash(ic)

View file

@ -189,7 +189,8 @@ func (n *NEO) Initialize(ic *interop.Context) error {
return err return err
} }
if n.nep17TokenNative.getTotalSupply(ic.DAO).Sign() != 0 { _, totalSupply := n.nep17TokenNative.getTotalSupply(ic.DAO)
if totalSupply.Sign() != 0 {
return errors.New("already initialized") return errors.New("already initialized")
} }
@ -977,7 +978,8 @@ func (n *NEO) computeCommitteeMembers(bc blockchainer.Blockchainer, d dao.DAO) (
votersCount := bigint.FromBytes(si) votersCount := bigint.FromBytes(si)
// votersCount / totalSupply must be >= 0.2 // votersCount / totalSupply must be >= 0.2
votersCount.Mul(votersCount, big.NewInt(effectiveVoterTurnout)) votersCount.Mul(votersCount, big.NewInt(effectiveVoterTurnout))
voterTurnout := votersCount.Div(votersCount, n.getTotalSupply(d)) _, totalSupply := n.getTotalSupply(d)
voterTurnout := votersCount.Div(votersCount, totalSupply)
sbVals := bc.GetStandByCommittee() sbVals := bc.GetStandByCommittee()
count := len(sbVals) count := len(sbVals)

View file

@ -95,19 +95,21 @@ func (c *nep17TokenNative) Decimals(_ *interop.Context, _ []stackitem.Item) stac
} }
func (c *nep17TokenNative) TotalSupply(ic *interop.Context, _ []stackitem.Item) stackitem.Item { func (c *nep17TokenNative) TotalSupply(ic *interop.Context, _ []stackitem.Item) stackitem.Item {
return stackitem.NewBigInteger(c.getTotalSupply(ic.DAO)) _, supply := c.getTotalSupply(ic.DAO)
return stackitem.NewBigInteger(supply)
} }
func (c *nep17TokenNative) getTotalSupply(d dao.DAO) *big.Int { func (c *nep17TokenNative) getTotalSupply(d dao.DAO) (state.StorageItem, *big.Int) {
si := d.GetStorageItem(c.ID, totalSupplyKey) si := d.GetStorageItem(c.ID, totalSupplyKey)
if si == nil { if si == nil {
return big.NewInt(0) si = []byte{}
} }
return bigint.FromBytes(si) return si, bigint.FromBytes(si)
} }
func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, supply *big.Int) error { func (c *nep17TokenNative) saveTotalSupply(d dao.DAO, si state.StorageItem, supply *big.Int) error {
return d.PutStorageItem(c.ID, totalSupplyKey, bigint.ToBytes(supply)) si = state.StorageItem(bigint.ToPreallocatedBytes(supply, si))
return d.PutStorageItem(c.ID, totalSupplyKey, si)
} }
func (c *nep17TokenNative) Transfer(ic *interop.Context, args []stackitem.Item) stackitem.Item { func (c *nep17TokenNative) Transfer(ic *interop.Context, args []stackitem.Item) stackitem.Item {
@ -283,9 +285,9 @@ func (c *nep17TokenNative) addTokens(ic *interop.Context, h util.Uint160, amount
panic(err) panic(err)
} }
supply := c.getTotalSupply(ic.DAO) buf, supply := c.getTotalSupply(ic.DAO)
supply.Add(supply, amount) supply.Add(supply, amount)
err = c.saveTotalSupply(ic.DAO, supply) err = c.saveTotalSupply(ic.DAO, buf, supply)
if err != nil { if err != nil {
panic(err) panic(err)
} }