Skip to content

Commit

Permalink
Implement NotaryAssisted transaction attribute
Browse files Browse the repository at this point in the history
Close #2896. Use a stub for native Notary contract hash since this
contract is not implemented yet. Thus, technically, NotaryAssisted
attribute verification will always fail on real network until native
Notary is implemented.

Signed-off-by: Anna Shaleva <[email protected]>
  • Loading branch information
AnnaShaleva committed Mar 6, 2024
1 parent 74562d5 commit 6da4ae2
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/Neo.CLI/CLI/MainService.Blockchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ public void OnShowTransactionCommand(UInt256 hash)
ConsoleHelper.Info("", " Type: ", $"{n.Type}");
ConsoleHelper.Info("", " Height: ", $"{n.Height}");
break;
case NotaryAssisted n:
ConsoleHelper.Info("", " Type: ", $"{n.Type}");
ConsoleHelper.Info("", " NKeys: ", $"{n.NKeys}");
break;
default:
ConsoleHelper.Info("", " Type: ", $"{attribute.Type}");
ConsoleHelper.Info("", " Size: ", $"{attribute.Size} Byte(s)");
Expand Down
63 changes: 63 additions & 0 deletions src/Neo/Network/P2P/Payloads/NotaryAssisted.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// NotaryAssisted.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using Neo.IO;
using Neo.Json;
using Neo.Persistence;
using Neo.SmartContract.Native;
using System.IO;
using System.Linq;

namespace Neo.Network.P2P.Payloads
{
public class NotaryAssisted : TransactionAttribute
{
/// <summary>
/// Indicates the number of keys participating in the transaction (main or fallback) signing process.
/// </summary>
public byte NKeys;

public override TransactionAttributeType Type => TransactionAttributeType.NotaryAssisted;

public override bool AllowMultiple => false;

public override int Size => base.Size + sizeof(byte);

protected override void DeserializeWithoutType(ref MemoryReader reader)
{
NKeys = reader.ReadByte();
}

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

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

public override bool Verify(DataCache snapshot, Transaction tx)
{
// Stub native Notary contract related check until the contract is implemented.
UInt160 notaryH = new UInt160();
return tx.Signers.Any(p => p.Account.Equals(notaryH));
}

public override long CalculateNetworkFee(DataCache snapshot, Transaction tx)
{
return (NKeys + 1) * base.CalculateNetworkFee(snapshot, tx);
}
}
}
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 @@ -40,6 +40,12 @@ public enum TransactionAttributeType : byte
/// Indicates that the transaction conflicts with <see cref="Conflicts.Hash"/>.
/// </summary>
[ReflectionCache(typeof(Conflicts))]
Conflicts = 0x21
Conflicts = 0x21,

/// <summary>
/// Indicates that the transaction is aimed to service notary request with <see cref="NotaryAssisted.NKeys" number of keys/>.

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (windows-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'

Check warning on line 46 in src/Neo/Network/P2P/Payloads/TransactionAttributeType.cs

View workflow job for this annotation

GitHub Actions / Test (macos-latest)

XML comment has badly formed XML -- 'Missing equals sign between attribute and attribute value.'
/// </summary>
[ReflectionCache(typeof(NotaryAssisted))]
NotaryAssisted = 0x22
}
}
6 changes: 6 additions & 0 deletions src/Neo/SmartContract/Native/PolicyContract.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public sealed class PolicyContract : NativeContract
/// </summary>
public const uint DefaultAttributeFee = 0;

/// <summary>
/// The default fee for NotaryAssisted attribute.
/// </summary>
public const uint DefaultNotaryAssistedAttributeFee = 1000_0000;

/// <summary>
/// The maximum execution fee factor that the committee can set.
/// </summary>
Expand Down Expand Up @@ -73,6 +78,7 @@ internal override ContractTask Initialize(ApplicationEngine engine, Hardfork? ha
engine.Snapshot.Add(CreateStorageKey(Prefix_FeePerByte), new StorageItem(DefaultFeePerByte));
engine.Snapshot.Add(CreateStorageKey(Prefix_ExecFeeFactor), new StorageItem(DefaultExecFeeFactor));
engine.Snapshot.Add(CreateStorageKey(Prefix_StoragePrice), new StorageItem(DefaultStoragePrice));
engine.Snapshot.Add(CreateStorageKey(Prefix_AttributeFee).Add((byte)TransactionAttributeType.NotaryAssisted), new StorageItem(DefaultNotaryAssistedAttributeFee));
}
return ContractTask.CompletedTask;
}
Expand Down
88 changes: 88 additions & 0 deletions tests/Neo.UnitTests/Network/P2P/Payloads/UT_NotaryAssisted.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (C) 2015-2024 The Neo Project.
//
// UT_NotaryAssisted.cs file belongs to the neo project and is free
// software distributed under the MIT software license, see the
// accompanying file LICENSE in the main directory of the
// repository or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
using Neo.SmartContract.Native;
using Neo.VM;
using System;

namespace Neo.UnitTests.Network.P2P.Payloads
{
[TestClass]
public class UT_NotaryAssisted
{
[TestMethod]
public void Size_Get()
{
var attr = new NotaryAssisted() { NKeys = 4 };
attr.Size.Should().Be(1 + 1);
}

[TestMethod]
public void ToJson()
{
var attr = new NotaryAssisted() { NKeys = 4 };
var json = attr.ToJson().ToString();
Assert.AreEqual(@"{""type"":""NotaryAssisted"",""nkeys"":4}", json);
}

[TestMethod]
public void DeserializeAndSerialize()
{
var attr = new NotaryAssisted() { NKeys = 4 };

var clone = attr.ToArray().AsSerializable<NotaryAssisted>();
Assert.AreEqual(clone.Type, attr.Type);

// As transactionAttribute
byte[] buffer = attr.ToArray();
var reader = new MemoryReader(buffer);
clone = TransactionAttribute.DeserializeFrom(ref reader) as NotaryAssisted;
Assert.AreEqual(clone.Type, attr.Type);

// Wrong type
buffer[0] = 0xff;
Assert.ThrowsException<FormatException>(() =>
{
var reader = new MemoryReader(buffer);
TransactionAttribute.DeserializeFrom(ref reader);
});
}

[TestMethod]
public void Verify()
{
var attr = new NotaryAssisted() { NKeys = 4 };

// Temporary use Notary contract hash stub for valid transaction.
var txGood = new Transaction { Signers = new Signer[] { new Signer() { Account = UInt160.Zero } } };
var txBad = new Transaction { Signers = new Signer[] { new Signer() { Account = UInt160.Parse("0xa400ff00ff00ff00ff00ff00ff00ff00ff00ff01") } } };
var snapshot = TestBlockchain.GetTestSnapshot();

Assert.IsTrue(attr.Verify(snapshot, txGood));
Assert.IsFalse(attr.Verify(snapshot, txBad));
}

[TestMethod]
public void CalculateNetworkFee()
{
var snapshot = TestBlockchain.GetTestSnapshot();
var attr = new NotaryAssisted() { NKeys = 4 };
var tx = new Transaction { Signers = new Signer[] { new Signer() { Account = UInt160.Zero } } };

Assert.AreEqual((4 + 1) * 1000_0000, attr.CalculateNetworkFee(snapshot, tx));
}
}
}

0 comments on commit 6da4ae2

Please sign in to comment.