From be885163f7790419976086506906cc5800f4026a Mon Sep 17 00:00:00 2001 From: Charis Zhao Date: Fri, 29 Nov 2019 18:04:34 +0800 Subject: [PATCH] Cache `Transaction.Size` (#1282) --- src/neo/Network/P2P/Payloads/Transaction.cs | 133 +++++++++++++++----- tests/neo.UnitTests/Ledger/UT_PoolItem.cs | 12 +- 2 files changed, 110 insertions(+), 35 deletions(-) diff --git a/src/neo/Network/P2P/Payloads/Transaction.cs b/src/neo/Network/P2P/Payloads/Transaction.cs index 6bda3f8c6b..c2adb34017 100644 --- a/src/neo/Network/P2P/Payloads/Transaction.cs +++ b/src/neo/Network/P2P/Payloads/Transaction.cs @@ -4,7 +4,6 @@ using Neo.Persistence; using Neo.SmartContract; using Neo.SmartContract.Native; -using Neo.VM; using Neo.VM.Types; using Neo.Wallets; using System; @@ -28,22 +27,36 @@ public class Transaction : IEquatable, IInventory, IInteroperable /// private const int MaxCosigners = 16; - public byte Version; - public uint Nonce; - public UInt160 Sender; - /// - /// Distributed to NEO holders. - /// - public long SystemFee; - /// - /// Distributed to consensus nodes. - /// - public long NetworkFee; - public uint ValidUntilBlock; - public TransactionAttribute[] Attributes; - public Cosigner[] Cosigners { get; set; } - public byte[] Script; - public Witness[] Witnesses { get; set; } + private byte version; + private uint nonce; + private UInt160 sender; + private long sysfee; + private long netfee; + private uint validUntilBlock; + private TransactionAttribute[] attributes; + private Cosigner[] cosigners; + private byte[] script; + private Witness[] witnesses; + + public const int HeaderSize = + sizeof(byte) + //Version + sizeof(uint) + //Nonce + 20 + //Sender + sizeof(long) + //SystemFee + sizeof(long) + //NetworkFee + sizeof(uint); //ValidUntilBlock + + public TransactionAttribute[] Attributes + { + get => attributes; + set { attributes = value; _hash = null; _size = 0; } + } + + public Cosigner[] Cosigners + { + get => cosigners; + set { cosigners = value; _hash = null; _size = 0; } + } /// /// The NetworkFee for the transaction divided by its Size. @@ -66,24 +79,86 @@ public UInt256 Hash InventoryType IInventory.InventoryType => InventoryType.TX; - public const int HeaderSize = - sizeof(byte) + //Version - sizeof(uint) + //Nonce - 20 + //Sender - sizeof(long) + //SystemFee - sizeof(long) + //NetworkFee - sizeof(uint); //ValidUntilBlock + /// + /// Distributed to consensus nodes. + /// + public long NetworkFee + { + get => netfee; + set { netfee = value; _hash = null; } + } - public int Size => HeaderSize + - Attributes.GetVarSize() + //Attributes - Cosigners.GetVarSize() + //Cosigners - Script.GetVarSize() + //Script - Witnesses.GetVarSize(); //Witnesses + public uint Nonce + { + get => nonce; + set { nonce = value; _hash = null; } + } + + public byte[] Script + { + get => script; + set { script = value; _hash = null; _size = 0; } + } + + public UInt160 Sender + { + get => sender; + set { sender = value; _hash = null; } + } + + private int _size; + public int Size + { + get + { + if (_size == 0) + { + _size = HeaderSize + + Attributes.GetVarSize() + //Attributes + Cosigners.GetVarSize() + //Cosigners + Script.GetVarSize() + //Script + Witnesses.GetVarSize(); //Witnesses + } + return _size; + } + } + + /// + /// Distributed to NEO holders. + /// + public long SystemFee + { + get => sysfee; + set { sysfee = value; _hash = null; } + } + + public uint ValidUntilBlock + { + get => validUntilBlock; + set { validUntilBlock = value; _hash = null; } + } + + public byte Version + { + get => version; + set { version = value; _hash = null; } + } + + public Witness[] Witnesses + { + get => witnesses; + set { witnesses = value; _size = 0; } + } void ISerializable.Deserialize(BinaryReader reader) { + int startPosition = -1; + if (reader.BaseStream.CanSeek) + startPosition = (int)reader.BaseStream.Position; DeserializeUnsigned(reader); Witnesses = reader.ReadSerializableArray(); + if (startPosition >= 0) + _size = (int)reader.BaseStream.Position - startPosition; } public void DeserializeUnsigned(BinaryReader reader) diff --git a/tests/neo.UnitTests/Ledger/UT_PoolItem.cs b/tests/neo.UnitTests/Ledger/UT_PoolItem.cs index d94cec8e4c..0d37e6edfd 100644 --- a/tests/neo.UnitTests/Ledger/UT_PoolItem.cs +++ b/tests/neo.UnitTests/Ledger/UT_PoolItem.cs @@ -67,11 +67,11 @@ public void PoolItem_CompareTo_Hash() PoolItem pitem1 = new PoolItem(tx1); PoolItem pitem2 = new PoolItem(tx2); - // pitem2 < pitem1 (fee) => -1 - pitem2.CompareTo(pitem1).Should().Be(-1); + // pitem2.tx.Hash < pitem1.tx.Hash => 1 descending order + pitem2.CompareTo(pitem1).Should().Be(1); - // pitem1 > pitem2 (fee) => 1 - pitem1.CompareTo(pitem2).Should().Be(1); + // pitem2.tx.Hash > pitem1.tx.Hash => -1 descending order + pitem1.CompareTo(pitem2).Should().Be(-1); } } @@ -96,7 +96,7 @@ public Transaction GenerateTxWithFirstByteOfHashGreaterThanOrEqualTo(byte firstH do { tx = GenerateTx(networkFee, size); - } while (tx.Hash >= new UInt256(TestUtils.GetByteArray(32, firstHashByte))); + } while (tx.Hash < new UInt256(TestUtils.GetByteArray(32, firstHashByte))); return tx; } @@ -107,7 +107,7 @@ public Transaction GenerateTxWithFirstByteOfHashLessThanOrEqualTo(byte firstHash do { tx = GenerateTx(networkFee, size); - } while (tx.Hash <= new UInt256(TestUtils.GetByteArray(32, firstHashByte))); + } while (tx.Hash > new UInt256(TestUtils.GetByteArray(32, firstHashByte))); return tx; }