Skip to content

Commit

Permalink
Payloads: add NotValidBefore transaction attribute (neo-project#2812)
Browse files Browse the repository at this point in the history
Fixes neo-project#1992.

Co-authored-by: Erik Zhang <[email protected]>
Co-authored-by: Vitor Nazário Coelho <[email protected]>
  • Loading branch information
3 people authored Mar 11, 2023
1 parent e786ab4 commit ec7ac2b
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
46 changes: 46 additions & 0 deletions src/Neo/Network/P2P/Payloads/NotValidBefore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Neo.IO;
using Neo.Json;
using Neo.Persistence;
using Neo.SmartContract.Native;
using System.IO;

namespace Neo.Network.P2P.Payloads
{
public class NotValidBefore : TransactionAttribute
{
/// <summary>
/// Indicates that the transaction is not valid before this height.
/// </summary>
public uint Height;

public override TransactionAttributeType Type => TransactionAttributeType.NotValidBefore;

public override bool AllowMultiple => false;

public override int Size => base.Size +
sizeof(uint); // Height.

protected override void DeserializeWithoutType(ref MemoryReader reader)
{
Height = reader.ReadUInt32();
}

protected override void SerializeWithoutType(BinaryWriter writer)
{
writer.Write(Height);
}

public override JObject ToJson()
{
JObject json = base.ToJson();
json["height"] = Height;
return json;
}

public override bool Verify(DataCache snapshot, Transaction tx)
{
var block_height = NativeContract.Ledger.CurrentIndex(snapshot);
return block_height >= Height;
}
}
}
8 changes: 7 additions & 1 deletion src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public enum TransactionAttributeType : byte
/// Indicates that the transaction is an oracle response.
/// </summary>
[ReflectionCache(typeof(OracleResponse))]
OracleResponse = 0x11
OracleResponse = 0x11,

/// <summary>
/// Indicates that the transaction is not valid before <see cref="NotValidBefore.Height"/>.
/// </summary>
[ReflectionCache(typeof(NotValidBefore))]
NotValidBefore = 0x20
}
}
75 changes: 75 additions & 0 deletions tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotValidBefore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract.Native;
using System;

namespace Neo.UnitTests.Network.P2P.Payloads
{
[TestClass]
public class UT_NotValidBefore
{
[TestMethod]
public void Size_Get()
{
var test = new NotValidBefore();
test.Size.Should().Be(5);
}

[TestMethod]
public void ToJson()
{
var test = new NotValidBefore();
test.Height = 42;
var json = test.ToJson().ToString();
Assert.AreEqual(@"{""type"":""NotValidBefore"",""height"":42}", json);
}

[TestMethod]
public void DeserializeAndSerialize()
{
var test = new NotValidBefore();

var clone = test.ToArray().AsSerializable<NotValidBefore>();
Assert.AreEqual(clone.Type, test.Type);

// As transactionAttribute

byte[] buffer = test.ToArray();
var reader = new MemoryReader(buffer);
clone = TransactionAttribute.DeserializeFrom(ref reader) as NotValidBefore;
Assert.AreEqual(clone.Type, test.Type);

// Wrong type

buffer[0] = 0xff;
reader = new MemoryReader(buffer);
try
{
TransactionAttribute.DeserializeFrom(ref reader);
Assert.Fail();
}
catch (FormatException) { }
reader = new MemoryReader(buffer);
try
{
new NotValidBefore().Deserialize(ref reader);
Assert.Fail();
}
catch (FormatException) { }
}

[TestMethod]
public void Verify()
{
var test = new NotValidBefore();
var snapshot = TestBlockchain.GetTestSnapshot();
test.Height = NativeContract.Ledger.CurrentIndex(snapshot) + 1;

Assert.IsFalse(test.Verify(snapshot, new Transaction()));
test.Height--;
Assert.IsTrue(test.Verify(snapshot, new Transaction()));
}
}
}

0 comments on commit ec7ac2b

Please sign in to comment.