core: no longer treat sysfee as claimable

As it's not on Neo 3, it just gets burned and that's it. Only network fee is
being redistributed to CNs.
This commit is contained in:
Roman Khimov 2020-06-04 22:59:34 +03:00
parent 50ed4c5967
commit 39dfebccc4
9 changed files with 31 additions and 77 deletions

View file

@ -536,7 +536,6 @@ func (bc *Blockchain) processHeader(h *block.Header, batch storage.Batch, header
} }
buf.Reset() buf.Reset()
buf.BinWriter.WriteU32LE(0) // sys fee is yet to be calculated
h.EncodeBinary(buf.BinWriter) h.EncodeBinary(buf.BinWriter)
if buf.Err != nil { if buf.Err != nil {
return buf.Err return buf.Err
@ -549,13 +548,6 @@ func (bc *Blockchain) processHeader(h *block.Header, batch storage.Batch, header
return nil return nil
} }
// getSystemFeeAmount returns sum of all system fees for blocks up to h.
// and 0 if no such block exists.
func (bc *Blockchain) getSystemFeeAmount(h util.Uint256) uint32 {
_, sf, _ := bc.dao.GetBlock(h)
return sf
}
// TODO: storeBlock needs some more love, its implemented as in the original // TODO: storeBlock needs some more love, its implemented as in the original
// project. This for the sake of development speed and understanding of what // project. This for the sake of development speed and understanding of what
// is happening here, quite allot as you can see :). If things are wired together // is happening here, quite allot as you can see :). If things are wired together
@ -563,11 +555,7 @@ func (bc *Blockchain) getSystemFeeAmount(h util.Uint256) uint32 {
func (bc *Blockchain) storeBlock(block *block.Block) error { func (bc *Blockchain) storeBlock(block *block.Block) error {
cache := dao.NewCached(bc.dao) cache := dao.NewCached(bc.dao)
appExecResults := make([]*state.AppExecResult, 0, len(block.Transactions)) appExecResults := make([]*state.AppExecResult, 0, len(block.Transactions))
fee := bc.getSystemFeeAmount(block.PrevHash) if err := cache.StoreAsBlock(block); err != nil {
for _, tx := range block.Transactions {
fee += uint32(tx.SystemFee.IntegralValue())
}
if err := cache.StoreAsBlock(block, fee); err != nil {
return err return err
} }
@ -1048,7 +1036,7 @@ func (bc *Blockchain) GetBlock(hash util.Uint256) (*block.Block, error) {
} }
} }
block, _, err := bc.dao.GetBlock(hash) block, err := bc.dao.GetBlock(hash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1070,7 +1058,7 @@ func (bc *Blockchain) GetHeader(hash util.Uint256) (*block.Header, error) {
return tb.Header(), nil return tb.Header(), nil
} }
} }
block, _, err := bc.dao.GetBlock(hash) block, err := bc.dao.GetBlock(hash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1235,10 +1223,9 @@ func (bc *Blockchain) UnsubscribeFromExecutions(ch chan<- *state.AppExecResult)
bc.unsubCh <- ch bc.unsubCh <- ch
} }
// CalculateClaimable calculates the amount of GAS which can be claimed for a transaction with value. // CalculateClaimable calculates the amount of GAS generated by owning specified
// First return value is GAS generated between startHeight and endHeight. // amount of NEO between specified blocks.
// Second return value is GAS returned from accumulated SystemFees between startHeight and endHeight. func (bc *Blockchain) CalculateClaimable(value util.Fixed8, startHeight, endHeight uint32) util.Fixed8 {
func (bc *Blockchain) CalculateClaimable(value util.Fixed8, startHeight, endHeight uint32) (util.Fixed8, util.Fixed8) {
var amount util.Fixed8 var amount util.Fixed8
di := uint32(bc.decrementInterval) di := uint32(bc.decrementInterval)
@ -1264,17 +1251,8 @@ func (bc *Blockchain) CalculateClaimable(value util.Fixed8, startHeight, endHeig
amount += util.Fixed8(iend-istart) * util.Fixed8(bc.generationAmount[ustart]) amount += util.Fixed8(iend-istart) * util.Fixed8(bc.generationAmount[ustart])
} }
if startHeight == 0 {
startHeight++
}
h := bc.GetHeaderHash(int(startHeight - 1))
feeStart := bc.getSystemFeeAmount(h)
h = bc.GetHeaderHash(int(endHeight - 1))
feeEnd := bc.getSystemFeeAmount(h)
sysFeeTotal := util.Fixed8(feeEnd - feeStart)
ratio := value / 100000000 ratio := value / 100000000
return amount * ratio, sysFeeTotal * ratio return amount * ratio
} }
// References maps transaction's inputs into a slice of InOuts, effectively // References maps transaction's inputs into a slice of InOuts, effectively
@ -1479,8 +1457,7 @@ func (bc *Blockchain) calculateBonus(claims []transaction.Input) (util.Fixed8, e
func (bc *Blockchain) calculateBonusInternal(scs []*spentCoin) (util.Fixed8, error) { func (bc *Blockchain) calculateBonusInternal(scs []*spentCoin) (util.Fixed8, error) {
var claimed util.Fixed8 var claimed util.Fixed8
for _, sc := range scs { for _, sc := range scs {
gen, sys := bc.CalculateClaimable(sc.Output.Amount, sc.StartHeight, sc.EndHeight) claimed += bc.CalculateClaimable(sc.Output.Amount, sc.StartHeight, sc.EndHeight)
claimed += gen + sys
} }
return claimed, nil return claimed, nil

View file

@ -194,27 +194,23 @@ func TestGetClaimable(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Run("first generation period", func(t *testing.T) { t.Run("first generation period", func(t *testing.T) {
amount, sysfee := bc.CalculateClaimable(util.Fixed8FromInt64(1), 0, 2) amount := bc.CalculateClaimable(util.Fixed8FromInt64(1), 0, 2)
require.EqualValues(t, 8, amount) require.EqualValues(t, 8, amount)
require.EqualValues(t, 0, sysfee)
}) })
t.Run("a number of full periods", func(t *testing.T) { t.Run("a number of full periods", func(t *testing.T) {
amount, sysfee := bc.CalculateClaimable(util.Fixed8FromInt64(1), 0, 6) amount := bc.CalculateClaimable(util.Fixed8FromInt64(1), 0, 6)
require.EqualValues(t, 4+4+3+3+2+2, amount) require.EqualValues(t, 4+4+3+3+2+2, amount)
require.EqualValues(t, 0, sysfee)
}) })
t.Run("start from the 2-nd block", func(t *testing.T) { t.Run("start from the 2-nd block", func(t *testing.T) {
amount, sysfee := bc.CalculateClaimable(util.Fixed8FromInt64(1), 1, 7) amount := bc.CalculateClaimable(util.Fixed8FromInt64(1), 1, 7)
require.EqualValues(t, 4+3+3+2+2+1, amount) require.EqualValues(t, 4+3+3+2+2+1, amount)
require.EqualValues(t, 0, sysfee)
}) })
t.Run("end height after generation has ended", func(t *testing.T) { t.Run("end height after generation has ended", func(t *testing.T) {
amount, sysfee := bc.CalculateClaimable(util.Fixed8FromInt64(1), 1, 10) amount := bc.CalculateClaimable(util.Fixed8FromInt64(1), 1, 10)
require.EqualValues(t, 4+3+3+2+2+1+1, amount) require.EqualValues(t, 4+3+3+2+2+1+1, amount)
require.EqualValues(t, 0, sysfee)
}) })
} }

View file

@ -19,7 +19,7 @@ type Blockchainer interface {
AddHeaders(...*block.Header) error AddHeaders(...*block.Header) error
AddBlock(*block.Block) error AddBlock(*block.Block) error
BlockHeight() uint32 BlockHeight() uint32
CalculateClaimable(value util.Fixed8, startHeight, endHeight uint32) (util.Fixed8, util.Fixed8) CalculateClaimable(value util.Fixed8, startHeight, endHeight uint32) util.Fixed8
Close() Close()
HeaderHeight() uint32 HeaderHeight() uint32
GetBlock(hash util.Uint256) (*block.Block, error) GetBlock(hash util.Uint256) (*block.Block, error)

View file

@ -25,7 +25,7 @@ type DAO interface {
GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error) GetAppExecResult(hash util.Uint256) (*state.AppExecResult, error)
GetAssetState(assetID util.Uint256) (*state.Asset, error) GetAssetState(assetID util.Uint256) (*state.Asset, error)
GetBatch() *storage.MemBatch GetBatch() *storage.MemBatch
GetBlock(hash util.Uint256) (*block.Block, uint32, error) GetBlock(hash util.Uint256) (*block.Block, error)
GetContractState(hash util.Uint160) (*state.Contract, error) GetContractState(hash util.Uint160) (*state.Contract, error)
GetCurrentBlockHeight() (uint32, error) GetCurrentBlockHeight() (uint32, error)
GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error) GetCurrentHeaderHeight() (i uint32, h util.Uint256, err error)
@ -53,7 +53,7 @@ type DAO interface {
PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error PutStorageItem(scripthash util.Uint160, key []byte, si *state.StorageItem) error
PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error PutUnspentCoinState(hash util.Uint256, ucs *state.UnspentCoin) error
PutVersion(v string) error PutVersion(v string) error
StoreAsBlock(block *block.Block, sysFee uint32) error StoreAsBlock(block *block.Block) error
StoreAsCurrentBlock(block *block.Block) error StoreAsCurrentBlock(block *block.Block) error
StoreAsTransaction(tx *transaction.Transaction, index uint32) error StoreAsTransaction(tx *transaction.Transaction, index uint32) error
putAccountState(as *state.Account, buf *io.BufBinWriter) error putAccountState(as *state.Account, buf *io.BufBinWriter) error
@ -402,18 +402,18 @@ func makeStorageItemKey(scripthash util.Uint160, key []byte) []byte {
// -- other. // -- other.
// GetBlock returns Block by the given hash if it exists in the store. // GetBlock returns Block by the given hash if it exists in the store.
func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, uint32, error) { func (dao *Simple) GetBlock(hash util.Uint256) (*block.Block, error) {
key := storage.AppendPrefix(storage.DataBlock, hash.BytesLE()) key := storage.AppendPrefix(storage.DataBlock, hash.BytesLE())
b, err := dao.Store.Get(key) b, err := dao.Store.Get(key)
if err != nil { if err != nil {
return nil, 0, err return nil, err
} }
block, err := block.NewBlockFromTrimmedBytes(b[4:]) block, err := block.NewBlockFromTrimmedBytes(b)
if err != nil { if err != nil {
return nil, 0, err return nil, err
} }
return block, binary.LittleEndian.Uint32(b[:4]), nil return block, nil
} }
// GetVersion attempts to get the current version stored in the // GetVersion attempts to get the current version stored in the
@ -531,12 +531,11 @@ func (dao *Simple) HasTransaction(hash util.Uint256) bool {
} }
// StoreAsBlock stores the given block as DataBlock. // StoreAsBlock stores the given block as DataBlock.
func (dao *Simple) StoreAsBlock(block *block.Block, sysFee uint32) error { func (dao *Simple) StoreAsBlock(block *block.Block) error {
var ( var (
key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE()) key = storage.AppendPrefix(storage.DataBlock, block.Hash().BytesLE())
buf = io.NewBufBinWriter() buf = io.NewBufBinWriter()
) )
buf.WriteU32LE(sysFee)
b, err := block.Trim() b, err := block.Trim()
if err != nil { if err != nil {
return err return err

View file

@ -155,7 +155,7 @@ func TestDeleteStorageItem(t *testing.T) {
func TestGetBlock_NotExists(t *testing.T) { func TestGetBlock_NotExists(t *testing.T) {
dao := NewSimple(storage.NewMemoryStore()) dao := NewSimple(storage.NewMemoryStore())
hash := random.Uint256() hash := random.Uint256()
block, _, err := dao.GetBlock(hash) block, err := dao.GetBlock(hash)
require.Error(t, err) require.Error(t, err)
require.Nil(t, block) require.Nil(t, block)
} }
@ -171,12 +171,11 @@ func TestPutGetBlock(t *testing.T) {
}, },
} }
hash := b.Hash() hash := b.Hash()
err := dao.StoreAsBlock(b, 42) err := dao.StoreAsBlock(b)
require.NoError(t, err) require.NoError(t, err)
gotBlock, sysfee, err := dao.GetBlock(hash) gotBlock, err := dao.GetBlock(hash)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, gotBlock) require.NotNil(t, gotBlock)
require.EqualValues(t, 42, sysfee)
} }
func TestGetVersion_NoVersion(t *testing.T) { func TestGetVersion_NoVersion(t *testing.T) {

View file

@ -10,9 +10,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/crypto/hash" "github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm"
) )
// GAS represents GAS native contract. // GAS represents GAS native contract.
@ -40,11 +38,6 @@ func NewGAS() *GAS {
g.nep5TokenNative = *nep5 g.nep5TokenNative = *nep5
desc := newDescriptor("getSysFeeAmount", smartcontract.IntegerType,
manifest.NewParameter("index", smartcontract.IntegerType))
md := newMethodAndPrice(g.getSysFeeAmount, 1, smartcontract.NoneFlag)
g.AddMethod(md, desc, true)
return g return g
} }
@ -98,16 +91,6 @@ func (g *GAS) OnPersist(ic *interop.Context) error {
return nil return nil
} }
func (g *GAS) getSysFeeAmount(ic *interop.Context, args []vm.StackItem) vm.StackItem {
index := toBigInt(args[0])
h := ic.Chain.GetHeaderHash(int(index.Int64()))
_, sf, err := ic.DAO.GetBlock(h)
if err != nil {
panic(err)
}
return vm.NewBigIntegerItem(big.NewInt(int64(sf)))
}
func getStandbyValidatorsHash(ic *interop.Context) (util.Uint160, []*keys.PublicKey, error) { func getStandbyValidatorsHash(ic *interop.Context) (util.Uint160, []*keys.PublicKey, error) {
vs, err := ic.Chain.GetStandByValidators() vs, err := ic.Chain.GetStandByValidators()
if err != nil { if err != nil {

View file

@ -188,9 +188,9 @@ func (n *NEO) distributeGas(ic *interop.Context, h util.Uint160, acc *state.NEOB
if ic.Block == nil || ic.Block.Index == 0 { if ic.Block == nil || ic.Block.Index == 0 {
return nil return nil
} }
sys, net := ic.Chain.CalculateClaimable(util.Fixed8(acc.Balance.Int64()), acc.BalanceHeight, ic.Block.Index) gen := ic.Chain.CalculateClaimable(util.Fixed8(acc.Balance.Int64()), acc.BalanceHeight, ic.Block.Index)
acc.BalanceHeight = ic.Block.Index acc.BalanceHeight = ic.Block.Index
n.GAS.mint(ic, h, big.NewInt(int64(sys+net))) n.GAS.mint(ic, h, big.NewInt(int64(gen)))
return nil return nil
} }
@ -203,8 +203,8 @@ func (n *NEO) unclaimedGas(ic *interop.Context, args []vm.StackItem) vm.StackIte
} }
tr := bs.Trackers[n.Hash] tr := bs.Trackers[n.Hash]
sys, net := ic.Chain.CalculateClaimable(util.Fixed8(tr.Balance), tr.LastUpdatedBlock, end) gen := ic.Chain.CalculateClaimable(util.Fixed8(tr.Balance), tr.LastUpdatedBlock, end)
return vm.NewBigIntegerItem(big.NewInt(int64(sys.Add(net)))) return vm.NewBigIntegerItem(big.NewInt(int64(gen)))
} }
func (n *NEO) registerValidator(ic *interop.Context, args []vm.StackItem) vm.StackItem { func (n *NEO) registerValidator(ic *interop.Context, args []vm.StackItem) vm.StackItem {

View file

@ -31,7 +31,7 @@ func (chain testChain) ApplyPolicyToTxSet([]mempool.TxWithFee) []mempool.TxWithF
func (chain testChain) GetConfig() config.ProtocolConfiguration { func (chain testChain) GetConfig() config.ProtocolConfiguration {
panic("TODO") panic("TODO")
} }
func (chain testChain) CalculateClaimable(util.Fixed8, uint32, uint32) (util.Fixed8, util.Fixed8) { func (chain testChain) CalculateClaimable(util.Fixed8, uint32, uint32) util.Fixed8 {
panic("TODO") panic("TODO")
} }

View file

@ -821,8 +821,8 @@ func (s *Server) getUnclaimedGas(ps request.Params) (interface{}, *response.Erro
if neo == 0 { if neo == 0 {
return "0", nil return "0", nil
} }
gasG, gasF := s.chain.CalculateClaimable(neo, neoHeight, s.chain.BlockHeight()+1) // +1 as in C#, for the next block. gas := s.chain.CalculateClaimable(neo, neoHeight, s.chain.BlockHeight()+1) // +1 as in C#, for the next block.
return strconv.FormatInt(int64(gasG+gasF), 10), nil // It's not represented as Fixed8 in C#. return strconv.FormatInt(int64(gas), 10), nil // It's not represented as Fixed8 in C#.
} }
// getValidators returns the current NEO consensus nodes information and voting status. // getValidators returns the current NEO consensus nodes information and voting status.