Merge pull request #1145 from nspcc-dev/fix/feeperbyte

Cache `transaction.FeePerByte()`
This commit is contained in:
Roman Khimov 2020-07-03 18:45:44 +03:00 committed by GitHub
commit 02bc0bdc1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 2 deletions

View file

@ -64,6 +64,9 @@ type Transaction struct {
// for correct signing/verification. // for correct signing/verification.
Network netmode.Magic Network netmode.Magic
// feePerByte is the ratio of NetworkFee and tx size, used for calculating tx priority.
feePerByte int64
// Hash of the transaction (double SHA256). // Hash of the transaction (double SHA256).
hash util.Uint256 hash util.Uint256
@ -272,13 +275,22 @@ func NewTransactionFromBytes(network netmode.Magic, b []byte) (*Transaction, err
if r.Err != nil { if r.Err != nil {
return nil, r.Err return nil, r.Err
} }
_ = r.ReadB()
if r.Err == nil {
return nil, errors.New("additional data after the transaction")
}
tx.feePerByte = tx.NetworkFee / int64(len(b))
return tx, nil return tx, nil
} }
// FeePerByte returns NetworkFee of the transaction divided by // FeePerByte returns NetworkFee of the transaction divided by
// its size // its size
func (t *Transaction) FeePerByte() int64 { func (t *Transaction) FeePerByte() int64 {
return t.NetworkFee / int64(io.GetVarSize(t)) if t.feePerByte != 0 {
return t.feePerByte
}
t.feePerByte = t.NetworkFee / int64(io.GetVarSize(t))
return t.feePerByte
} }
// transactionJSON is a wrapper for Transaction and // transactionJSON is a wrapper for Transaction and

View file

@ -71,6 +71,26 @@ func TestNew(t *testing.T) {
testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet}) testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet})
} }
func TestNewTransactionFromBytes(t *testing.T) {
script := []byte{0x51}
tx := New(netmode.UnitTestNet, script, 1)
tx.NetworkFee = 123
data, err := testserdes.EncodeBinary(tx)
require.NoError(t, err)
// set cached fields
tx.Hash()
tx.FeePerByte()
tx1, err := NewTransactionFromBytes(netmode.UnitTestNet, data)
require.NoError(t, err)
require.Equal(t, tx, tx1)
data = append(data, 42)
_, err = NewTransactionFromBytes(netmode.UnitTestNet, data)
require.Error(t, err)
}
func TestEncodingTXWithNoScript(t *testing.T) { func TestEncodingTXWithNoScript(t *testing.T) {
_, err := testserdes.EncodeBinary(new(Transaction)) _, err := testserdes.EncodeBinary(new(Transaction))
require.Error(t, err) require.Error(t, err)

View file

@ -498,7 +498,12 @@ var rpcClientTestCases = map[string][]rpcClientTestCase{
if err != nil { if err != nil {
panic(err) panic(err)
} }
return c.GetRawTransactionVerbose(hash) out, err := c.GetRawTransactionVerbose(hash)
if err != nil {
return nil, err
}
out.Transaction.FeePerByte() // set fee per byte
return out, nil
}, },
serverResponse: txMoveNeoVerbose, serverResponse: txMoveNeoVerbose,
result: func(c *Client) interface{} { result: func(c *Client) interface{} {