transaction: cache tx size, don't serialize it over and over again
This commit is contained in:
parent
a6a1df4e0d
commit
19c69618c5
5 changed files with 21 additions and 11 deletions
|
@ -1181,7 +1181,7 @@ func (bc *Blockchain) ApplyPolicyToTxSet(txes []*transaction.Transaction) []*tra
|
|||
)
|
||||
blockSize = uint32(io.GetVarSize(new(block.Block)) + io.GetVarSize(len(txes)+1))
|
||||
for i, tx := range txes {
|
||||
blockSize += uint32(io.GetVarSize(tx))
|
||||
blockSize += uint32(tx.Size())
|
||||
sysFee += tx.SystemFee
|
||||
if blockSize > maxBlockSize || sysFee > maxBlockSysFee {
|
||||
txes = txes[:i]
|
||||
|
@ -1234,7 +1234,7 @@ func (bc *Blockchain) verifyAndPoolTx(t *transaction.Transaction, pool *mempool.
|
|||
// Only one %w can be used.
|
||||
return fmt.Errorf("%w: %v", ErrPolicy, err)
|
||||
}
|
||||
size := io.GetVarSize(t)
|
||||
size := t.Size()
|
||||
if size > transaction.MaxTransactionSize {
|
||||
return fmt.Errorf("%w: (%d > MaxTransactionSize %d)", ErrTxTooBig, size, transaction.MaxTransactionSize)
|
||||
}
|
||||
|
|
|
@ -524,8 +524,8 @@ func TestGetTransaction(t *testing.T) {
|
|||
tx, height, err := bc.GetTransaction(block.Transactions[0].Hash())
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, block.Index, height)
|
||||
assert.Equal(t, txSize, tx.Size())
|
||||
assert.Equal(t, block.Transactions[0], tx)
|
||||
assert.Equal(t, txSize, io.GetVarSize(tx))
|
||||
assert.Equal(t, 1, io.GetVarSize(tx.Attributes))
|
||||
assert.Equal(t, 1, io.GetVarSize(tx.Scripts))
|
||||
assert.NoError(t, bc.persist())
|
||||
|
|
|
@ -62,8 +62,8 @@ type Transaction struct {
|
|||
// for correct signing/verification.
|
||||
Network netmode.Magic
|
||||
|
||||
// feePerByte is the ratio of NetworkFee and tx size, used for calculating tx priority.
|
||||
feePerByte int64
|
||||
// size is transaction's serialized size.
|
||||
size int
|
||||
|
||||
// Hash of the transaction (double SHA256).
|
||||
hash util.Uint256
|
||||
|
@ -158,6 +158,7 @@ func (t *Transaction) DecodeBinary(br *io.BinReader) {
|
|||
// to do it anymore.
|
||||
if br.Err == nil {
|
||||
br.Err = t.createHash()
|
||||
_ = t.Size()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,18 +253,22 @@ func NewTransactionFromBytes(network netmode.Magic, b []byte) (*Transaction, err
|
|||
if r.Err == nil {
|
||||
return nil, errors.New("additional data after the transaction")
|
||||
}
|
||||
tx.feePerByte = tx.NetworkFee / int64(len(b))
|
||||
tx.size = len(b)
|
||||
return tx, nil
|
||||
}
|
||||
|
||||
// FeePerByte returns NetworkFee of the transaction divided by
|
||||
// its size
|
||||
func (t *Transaction) FeePerByte() int64 {
|
||||
if t.feePerByte != 0 {
|
||||
return t.feePerByte
|
||||
return t.NetworkFee / int64(t.Size())
|
||||
}
|
||||
|
||||
// Size returns size of the serialized transaction.
|
||||
func (t *Transaction) Size() int {
|
||||
if t.size == 0 {
|
||||
t.size = io.GetVarSize(t)
|
||||
}
|
||||
t.feePerByte = t.NetworkFee / int64(io.GetVarSize(t))
|
||||
return t.feePerByte
|
||||
return t.size
|
||||
}
|
||||
|
||||
// Sender returns the sender of the transaction which is always on the first place
|
||||
|
@ -296,7 +301,7 @@ type transactionJSON struct {
|
|||
func (t *Transaction) MarshalJSON() ([]byte, error) {
|
||||
tx := transactionJSON{
|
||||
TxID: t.Hash(),
|
||||
Size: io.GetVarSize(t),
|
||||
Size: t.Size(),
|
||||
Version: t.Version,
|
||||
Nonce: t.Nonce,
|
||||
Sender: address.Uint160ToString(t.Sender()),
|
||||
|
@ -329,6 +334,9 @@ func (t *Transaction) UnmarshalJSON(data []byte) error {
|
|||
if t.Hash() != tx.TxID {
|
||||
return errors.New("txid doesn't match transaction hash")
|
||||
}
|
||||
if t.Size() != tx.Size {
|
||||
return errors.New("'size' doesn't match transaction size")
|
||||
}
|
||||
|
||||
return t.isValid()
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ func TestNew(t *testing.T) {
|
|||
assert.Equal(t, script, tx.Script)
|
||||
// Update hash fields to match tx2 that is gonna autoupdate them on decode.
|
||||
_ = tx.Hash()
|
||||
_ = tx.Size()
|
||||
testserdes.EncodeDecodeBinary(t, tx, &Transaction{Network: netmode.UnitTestNet})
|
||||
}
|
||||
|
||||
|
|
|
@ -811,6 +811,7 @@ func testRPCProtocol(t *testing.T, doRPCCall func(string, string, *testing.T) []
|
|||
t.Run("getrawtransaction 2 arguments, verbose", func(t *testing.T) {
|
||||
block, _ := chain.GetBlock(chain.GetHeaderHash(0))
|
||||
TXHash := block.Transactions[0].Hash()
|
||||
_ = block.Transactions[0].Size()
|
||||
rpc := fmt.Sprintf(`{"jsonrpc": "2.0", "id": 1, "method": "getrawtransaction", "params": ["%s", 1]}"`, TXHash.StringLE())
|
||||
body := doRPCCall(rpc, httpSrv.URL, t)
|
||||
txOut := checkErrGetResult(t, body, false)
|
||||
|
|
Loading…
Reference in a new issue