private bool CheckEchoMessage(ECHOMessage msg, int from) { var value = msg.Data.Keccak(); // We can get exception here if the size of msg.MerkleProof is less then the depth of MerkleTree int i, j; for (i = from + _merkleTreeSize, j = 0; i > 1 && j < msg.MerkleProof.Count; i /= 2, ++j) { value = (i & 1) == 0 ? value.ToBytes().Concat(msg.MerkleProof[j].ToBytes()).Keccak() // we are left sibling : msg.MerkleProof[j].ToBytes().Concat(value.ToBytes()).Keccak(); // we are right sibling } return(msg.MerkleTreeRoot.Equals(value) && i == 1); // it reached the root and matches the root }
public void TestErasureCoding() { const int nShards = 4, nErasures = 2; var rbc = new ReliableBroadcast( new ReliableBroadcastId(0, 0), new PublicConsensusKeySet(4, 1, null !, null !, Enumerable.Empty <ECDSAPublicKey>()), null ! ); var data = Enumerable.Range(0, 100) .Select(x => (byte)x) .ToArray(); var shards = ReliableBroadcast.ErasureCodingShards(data, nShards, nErasures); var echo1 = new ECHOMessage { Data = ByteString.CopyFrom(shards[1]) }; var echo2 = new ECHOMessage { Data = ByteString.CopyFrom(shards[2]) }; var decoded = rbc.DecodeFromEchos(new (ECHOMessage echo, int @from)[] { (echo1, 1), (echo2, 2) });
private void HandleEchoMessage(ECHOMessage echo, int validator) { // Every validator can send echo to any instance of ReliableBroadcast of any validator. So if not handled // properly, wrong message can stop all instances of ReliableBroadcast which will stop consensus var validatorPubKey = Wallet.EcdsaPublicKeySet[validator].ToHex(); if (_echoMessages[validator] != null) { Logger.LogWarning($"{Id} already received correct echo from {validator} ({validatorPubKey})"); return; } if (!CheckEchoMessage(echo, validator)) { Logger.LogWarning($"{Id}: validator {validator} ({validatorPubKey}) sent incorrect ECHO"); return; } Logger.LogTrace($"Protocol {Id} got ECHO message from {validator} ({validatorPubKey})"); _echoMessages[validator] = echo; TrySendReadyMessageFromEchos(); CheckResult(); }