Skip to content

Commit

Permalink
Merge pull request #23 from EanCuznaivy/master
Browse files Browse the repository at this point in the history
Re-implement the verification of proof list
  • Loading branch information
xtaci committed Jan 11, 2018
2 parents b60b482 + 793b008 commit b956cb1
Show file tree
Hide file tree
Showing 21 changed files with 397 additions and 313 deletions.
2 changes: 1 addition & 1 deletion AElf.Kernel.Tests/HashTests.cs
Expand Up @@ -20,7 +20,7 @@ public void Test1()
[Fact]
public async Task MerkleTree()
{
var mt=new Mock<IMerkleTree<ITransaction>>();
var mt = new Mock<IMerkleTree<ITransaction>>();

mt.Setup(p => p.AddNode(It.IsAny<IHash<ITransaction>>()));

Expand Down
200 changes: 66 additions & 134 deletions AElf.Kernel.Tests/MerkleTest.cs
@@ -1,166 +1,98 @@
using Xunit;
using AElf.Kernel.Merkle;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;

namespace AElf.Kernel.Tests
{
public class MerkleTest
{
[Fact]
public void EqualHashes()
{
MerkleHash h1 = new MerkleHash("aelf");
MerkleHash h2 = new MerkleHash("aelf");
Assert.Equal(h1.Value, h2.Value);
}

[Fact]
public void NotEqualHashes()
{
MerkleHash h1 = new MerkleHash("aelf");
MerkleHash h2 = new MerkleHash("yifu");
Assert.NotEqual(h1.Value, h2.Value);
}

[Fact]
public void CreateEmptyNode()
{
MerkleNode node = new MerkleNode();
Assert.Null(node.ParentNode);
Assert.Null(node.LeftNode);
Assert.Null(node.RightNode);
}

[Fact]
public void VerifyLeftHash()
{
MerkleNode left = new MerkleNode
{
Hash = new MerkleHash("aelf")
};

MerkleNode parent = new MerkleNode();
parent.SetLeftNode(left);
//[Fact]
//public void ProofListTest()
//{
// MerkleTree tree = new MerkleTree();
// tree.AddLeaves(CreateLeaves(new string[] { "a", "e", "l", "f", "2", "0", "1", "8" }))
// .Generate();

Assert.True(parent.VerifyHash());
}
// Hash target = new Hash("e");
// var prooflist = tree.GetProofList(target);

[Fact]
public void VerifyHash()
{
MerkleNode parent = CreateNode("ae", "lf");
Assert.True(parent.VerifyHash());
}

[Fact]
public void EqualNodes()
{
MerkleNode node1 = CreateNode("ae", "lf");
MerkleNode node2 = CreateNode("ae", "lf");
Assert.Equal(node1.Hash.Value, node2.Hash.Value);
}

[Fact]
public void NotEqualNodes()
{
MerkleNode node1 = CreateNode("ae", "lf");
MerkleNode node2 = CreateNode("yi", "fu");
Assert.NotEqual(node1.Hash.Value, node2.Hash.Value);
}

[Fact]
public void GenerateTreeWithEvenLeaves()
{
MerkleTree tree = new MerkleTree();
tree.AddLeaves(CreateLeaves(new string[] { "a", "e", "l", "f" }));
tree.GenerateMerkleTree();
Assert.NotNull(tree.MerkleRoot);
}

[Fact]
public void GenerateTreeWithOddLeaves()
{
MerkleTree tree = new MerkleTree();
tree.AddLeaves(CreateLeaves(new string[] { "e", "l", "f" }));
tree.GenerateMerkleTree();
Assert.NotNull(tree.MerkleRoot);
}

[Fact]
public void ProofListTest()
{
MerkleTree tree = new MerkleTree();
tree.AddLeaves(CreateLeaves(new string[] { "a", "e", "l", "f", "2", "0", "1", "8" }));
tree.GenerateMerkleTree();

MerkleHash target = new MerkleHash("e");
var prooflist = tree.GetProofList(target);

Assert.True(prooflist[0].Hash.ToString() == new MerkleHash("a").ToString());
Assert.True(prooflist[prooflist.Count - 1].Hash.ToString() == tree.MerkleRoot.Hash.ToString());
}
// Assert.True(prooflist[0].Hash.ToString() == new Hash("a").ToString());
// Assert.True(prooflist[prooflist.Count - 1].Hash.ToString() == tree.MerkleRoot.Hash.ToString());
//}

[Fact]
public void VerifyProofListTest()
{
MerkleTree tree = new MerkleTree();
tree.AddLeaves(CreateLeaves(new string[] { "a", "e", "l", "f" }));
tree.GenerateMerkleTree();

#region Proof List
//Proof List: hash(a), hash(e), hash(hash(l), hash(f))
var hash_a = new MerkleHash("a");

var hash_e = new MerkleHash("e");

var hash_l = new MerkleHash("l");
var hash_f = new MerkleHash("f");
var hash_l_f = new MerkleHash(hash_l, hash_f);
MerkleTree<ITransaction> tree = new MerkleTree<ITransaction>();
tree.AddNodes(CreateLeaves(new string[] { "a", "e", "l", "f" }))
.ComputeRootHash();

#region Create elements of Proof List
/* Merkle Tree:
* root
* hash(hash(a),hash(e)) hash(hash(l),hash(f))
* hash(a) hash(e) hash(l) hash(f)
* a e l f
*/
//Proof List: { hash(a), hash(e), hash(hash(l), hash(f)) }
var hash_a = new Hash<ITransaction>(GetSHA256Hash("a"));

var hash_e = new Hash<ITransaction>(GetSHA256Hash("e"));

var hash_l = new Hash<ITransaction>(GetSHA256Hash("l"));
var hash_f = new Hash<ITransaction>(GetSHA256Hash("f"));
var hash_l_f = new Hash<ITransaction>(GetSHA256Hash(hash_l.ToString() + hash_f.ToString()));
#endregion

List<MerkleHash> prooflist = new List<MerkleHash>();
prooflist.Add(hash_a);
prooflist.Add(hash_e);
prooflist.Add(hash_l_f);
List<Hash<ITransaction>> prooflist = new List<Hash<ITransaction>>
{
hash_a,
hash_e,
hash_l_f
};

Assert.True(tree.VerifyProofList(prooflist));
}

#region Some methods

private static MerkleNode CreateNode(string buffer1, string buffer2)
{
MerkleNode left = new MerkleNode
{
Hash = new MerkleHash(buffer1)
};
MerkleNode right = new MerkleNode
{
Hash = new MerkleHash(buffer2)
};

MerkleNode parent = new MerkleNode();
parent.SetLeftNode(left);
parent.SetRightNode(right);

return parent;
}

private static List<MerkleNode> CreateLeaves(string[] buffers)
//private static MerkleNode CreateNode(string buffer1, string buffer2)
//{
// MerkleNode left = new MerkleNode
// {
// Hash = new Hash<T>(buffer1)
// };
// MerkleNode right = new MerkleNode
// {
// Hash = new Hash<T>(buffer2)
// };

// MerkleNode parent = new MerkleNode();
// parent.SetLeftNode(left);
// parent.SetRightNode(right);

// return parent;
//}

private static List<IHash<ITransaction>> CreateLeaves(string[] buffers)
{
List<MerkleNode> leaves = new List<MerkleNode>();
List<IHash<ITransaction>> leaves = new List<IHash<ITransaction>>();
foreach (var buffer in buffers)
{
MerkleHash hash = new MerkleHash(buffer);
MerkleNode node = new MerkleNode
{
Hash = hash
};
leaves.Add(node);
IHash<ITransaction> hash = new Hash<ITransaction>(GetSHA256Hash(buffer));
leaves.Add(hash);
}
return leaves;
}

private static byte[] GetSHA256Hash(string str)
{
return SHA256.Create().ComputeHash(
Encoding.UTF8.GetBytes(str));
}

#endregion
}
}
9 changes: 9 additions & 0 deletions AElf.Kernel/AELFException.cs
@@ -0,0 +1,9 @@
using System;

namespace AElf.Kernel
{
public class AELFException : ApplicationException
{
public AELFException(string msg) : base(msg) { }
}
}
43 changes: 43 additions & 0 deletions AElf.Kernel/Block.cs
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace AElf.Kernel
{
public class Block : IBlock
{
public int MagicNumber => 0xAE1F;

/// <summary>
/// Magic Number: 4B
/// BlockSize: 4B
/// BlockHeader: 84B
/// </summary>
public int BlockSize => 92;

public BlockHeader BlockHeader { get; set; }

public BlockBody BlockBody { get; set; }


public bool AddTransaction(ITransaction tx)
{
throw new NotImplementedException();
}

public IBlockBody GetBody()
{
return BlockBody;
}

public IHash GetHash()
{
throw new NotImplementedException();
}

public IBlockHeader GetHeader()
{
return BlockHeader;
}
}
}
12 changes: 12 additions & 0 deletions AElf.Kernel/BlockBody.cs
@@ -0,0 +1,12 @@
using System.Linq;

namespace AElf.Kernel
{
public class BlockBody : IBlockBody
{
public IQueryable<ITransaction> GetTransactions()
{
throw new System.NotImplementedException();
}
}
}
40 changes: 40 additions & 0 deletions AElf.Kernel/BlockHeader.cs
@@ -0,0 +1,40 @@
using System;

namespace AElf.Kernel
{
public class BlockHeader : IBlockHeader
{
public int Version => 0;
public IHash<IBlock> PreBlockHash { get; protected set; }
public IHash<IMerkleTree<ITransaction>> MerkleRootHash { get; protected set; }
public long TimeStamp { get; protected set; }
/// <summary>
/// The difficulty of mining.
/// </summary>
public int Bits => GetBits();
/// <summary>
/// Random value.
/// </summary>
public int Nonce => GetNonce();

public void AddTransaction(IHash<ITransaction> hash)
{
throw new NotImplementedException();
}

public IHash<IMerkleTree<ITransaction>> GetTransactionMerkleTreeRoot()
{
throw new NotImplementedException();
}

private int GetBits()
{
return 1;
}

private int GetNonce()
{
return new Random().Next(1, 100);
}
}
}
7 changes: 0 additions & 7 deletions AElf.Kernel/Consensus/IDelegate.cs

This file was deleted.

0 comments on commit b956cb1

Please sign in to comment.