-
Notifications
You must be signed in to change notification settings - Fork 0
/
BlockWriter.cs
154 lines (137 loc) · 5.13 KB
/
BlockWriter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using Newtonsoft.Json;
using System.Diagnostics;
namespace OrdererTest
{
class BlockWriter
{
public BlockHeader PreviousBlockHeader;
private SHA256 hasher = SHA256.Create();
private bool useGPU;
//Create block out of batch
unsafe public Block CreateNextBlock(Batch newbatch)
{
byte[] previousblockhash = BlockHeaderHash(PreviousBlockHeader);
BlockData blockdata = new BlockData();
byte[][] data = new byte[newbatch.MsgCount][];
//Convert each message to byte format to add to data
Parallel.For(0, newbatch.MsgCount, i =>
{
SafeEnvelope safe = new SafeEnvelope();
List<byte> pllist = new List<byte>();
List<byte> siglist = new List<byte>();
int j = 0;
while(true)
{
if(newbatch.Messages[i].Payload[j] == 0)
{
break;
}
else
{
pllist.Add(newbatch.Messages[i].Payload[j]);
}
j++;
}
j = 0;
while (true)
{
if (newbatch.Messages[i].Signature[j] == 0)
{
break;
}
else
{
siglist.Add(newbatch.Messages[i].Signature[j]);
}
j++;
}
safe.Payload = pllist.ToArray();
safe.Signature = siglist.ToArray();
data[i] = Marshal(safe);
});
blockdata.Data = data;
Block newblock = NewBlock(PreviousBlockHeader.Number + 1, previousblockhash);
newblock.Header.DataHash = BlockDataHash(blockdata);
newblock.Data = blockdata;
PreviousBlockHeader = newblock.Header;
return newblock;
}
public Block CreateNextBlockCPU(SafeBatch newbatch)
{
byte[] previousblockhash = BlockHeaderHash(PreviousBlockHeader);
BlockData blockdata = new BlockData();
byte[][] data = new byte[newbatch.Messages.Count()][];
//Convert each message to byte format to add to data
Parallel.For(0, newbatch.Messages.Count(), i =>
{
data[i] = Marshal(newbatch.Messages[i]);
});
blockdata.Data = data;
Block newblock = NewBlock(PreviousBlockHeader.Number + 1, previousblockhash);
newblock.Header.DataHash = BlockDataHash(blockdata);
newblock.Data = blockdata;
PreviousBlockHeader = newblock.Header;
return newblock;
}
//Saves block as .json, watched for by hyperledger go program
public void WriteBlock(Block newblock)
{
string jsontext = JsonConvert.SerializeObject(newblock);
File.WriteAllText("block" + newblock.Header.Number + ".json", jsontext);
}
public void WriteConfigBlock(Block newblock)
{
string jsontext = JsonConvert.SerializeObject(newblock);
File.WriteAllText("block" + newblock.Header.Number + "-config.json", jsontext);
}
// Convert an object to a byte array
public byte[] Marshal(Object obj)
{
string objjson = JsonConvert.SerializeObject(obj);
byte[] bytes = new byte[objjson.Length];
GetBytes(objjson.ToCharArray(), objjson.Length, bytes);
return bytes;
}
//Convert each char of string into a byte and add to array
private void GetBytes(char[] obj, int len, byte[] byteconvert)
{
Parallel.For(0, len, i =>
{
byteconvert[i] = (byte)obj[i];
});
}
public byte[] BlockHeaderHash(BlockHeader hdr)
{
return hasher.ComputeHash(Marshal(hdr)); //Create hash of byte representation of header
}
public byte[] BlockDataHash(BlockData data)
{
return hasher.ComputeHash(Marshal(data)); //Create hash of byte representation of data
}
//Initialize block with supplied values
public Block NewBlock(ulong SeqNum, byte[] prevhash)
{
Block newblock = new Block();
newblock.Header = new BlockHeader();
newblock.Header.Number = SeqNum;
newblock.Header.PreviousHash = prevhash;
newblock.Metadata = new BlockMetadata();
newblock.Metadata.Metadata = new byte[1][];
return newblock;
}
public BlockWriter() { } //Constructor for GPU
//Constructor with initial block header
public BlockWriter(BlockHeader prev)
{
PreviousBlockHeader = prev;
}
}
}