Example #1
0
        public void TestSerializeAndDeserializeRecoveryMessageWithoutChangeViewsWithoutCommits()
        {
            Transaction[] txs = new Transaction[5];
            for (int i = 0; i < txs.Length; i++)
            {
                txs[i] = TestUtils.CreateRandomHashTransaction();
            }
            var msg = new RecoveryMessage
            {
                ChangeViewMessages    = new Dictionary <int, RecoveryMessage.ChangeViewPayloadCompact>(),
                PrepareRequestMessage = new PrepareRequest
                {
                    TransactionHashes = txs.Select(p => p.Hash).ToArray()
                },
                PreparationMessages = new Dictionary <int, RecoveryMessage.PreparationPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 0,
                            InvocationScript = new[] { (byte)'t', (byte)'e' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 1,
                            InvocationScript = new[] { (byte)'s', (byte)'t' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 3,
                            InvocationScript = new[] { (byte)'1', (byte)'2' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 6,
                            InvocationScript = new[] { (byte)'3', (byte)'!' }
                        }
                    }
                },
                CommitMessages = new Dictionary <int, RecoveryMessage.CommitPayloadCompact>()
            };

            var copiedMsg = TestUtils.CopyMsgBySerialization(msg, new RecoveryMessage());;

            copiedMsg.ChangeViewMessages.Count.Should().Be(0);
            copiedMsg.PrepareRequestMessage.ShouldBeEquivalentTo(msg.PrepareRequestMessage);
            copiedMsg.PreparationHash.Should().Be(null);
            copiedMsg.PreparationMessages.ShouldAllBeEquivalentTo(msg.PreparationMessages);
            copiedMsg.CommitMessages.Count.Should().Be(0);
        }
Example #2
0
        public void OnRecoveryMessageReceived(ConsensusPayload payload, RecoveryMessage recovery)
        {
            if (!_consensus.TryGetValue(ConsensusMessageType.RecoveryMessage, out var state))
            {
                state = new ConsensusPhaseStat();
            }

            state.Add(payload);
        }
Example #3
0
        private string GetMessage(List <Satellite> satellites)
        {
            List <string[]> listTransmissionsMessages = new List <string[]>();

            satellites.ForEach(x =>
            {
                listTransmissionsMessages.Add(x.ReceivedMessage.Message);
            });

            return(RecoveryMessage.Recovery(listTransmissionsMessages));
        }
Example #4
0
        public void TestRecoveryMessage()
        {
            List <string[]> listTransmissionsMessages = new List <string[]>();

            listTransmissionsMessages.Add(new string[] { "", "es", "", "mensaje", "" });
            listTransmissionsMessages.Add(new string[] { "", "", "un", "", "secreto" });
            listTransmissionsMessages.Add(new string[] { "este", "", "un", "", "secreto" });


            string expected = "este es un mensaje secreto";
            string actual   = RecoveryMessage.Recovery(listTransmissionsMessages);

            Assert.AreEqual(expected, actual);
        }
Example #5
0
        public void TestSerializeAndDeserializeRecoveryMessageWithChangeViewsAndPrepareRequest()
        {
            Transaction[] txs = new Transaction[5];
            for (int i = 0; i < txs.Length; i++)
            {
                txs[i] = TestUtils.CreateRandomHashTransaction();
            }
            var msg = new RecoveryMessage
            {
                ChangeViewMessages = new Dictionary <int, RecoveryMessage.ChangeViewPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 0,
                            OriginalViewNumber = 9,
                            Timestamp          = 6,
                            InvocationScript   = new[] { (byte)'A' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 1,
                            OriginalViewNumber = 7,
                            Timestamp          = 5,
                            InvocationScript   = new[] { (byte)'B' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 3,
                            OriginalViewNumber = 5,
                            Timestamp          = 3,
                            InvocationScript   = new[] { (byte)'C' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 6,
                            OriginalViewNumber = 2,
                            Timestamp          = 1,
                            InvocationScript   = new[] { (byte)'D' }
                        }
                    }
                },
                PrepareRequestMessage = new PrepareRequest
                {
                    TransactionHashes = txs.Select(p => p.Hash).ToArray()
                },
                PreparationHash     = new UInt256(Crypto.Default.Hash256(new[] { (byte)'a' })),
                PreparationMessages = new Dictionary <int, RecoveryMessage.PreparationPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 0,
                            InvocationScript = new[] { (byte)'t', (byte)'e' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 1,
                            InvocationScript = new[] { (byte)'s', (byte)'t' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 3,
                            InvocationScript = new[] { (byte)'1', (byte)'2' }
                        }
                    }
                },
                CommitMessages = new Dictionary <int, RecoveryMessage.CommitPayloadCompact>()
            };

            var copiedMsg = TestUtils.CopyMsgBySerialization(msg, new RecoveryMessage());;

            copiedMsg.ChangeViewMessages.ShouldAllBeEquivalentTo(msg.ChangeViewMessages);
            copiedMsg.PrepareRequestMessage.ShouldBeEquivalentTo(msg.PrepareRequestMessage);
            copiedMsg.PreparationHash.Should().Be(null);
            copiedMsg.PreparationMessages.ShouldAllBeEquivalentTo(msg.PreparationMessages);
            copiedMsg.CommitMessages.Count.Should().Be(0);
        }
Example #6
0
        public void TestSerializeAndDeserializeRecoveryMessageWithChangeViewsAndNoPrepareRequest()
        {
            var msg = new RecoveryMessage
            {
                ChangeViewMessages = new Dictionary <int, RecoveryMessage.ChangeViewPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 0,
                            OriginalViewNumber = 9,
                            Timestamp          = 6,
                            InvocationScript   = new[] { (byte)'A' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 1,
                            OriginalViewNumber = 7,
                            Timestamp          = 5,
                            InvocationScript   = new[] { (byte)'B' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 3,
                            OriginalViewNumber = 5,
                            Timestamp          = 3,
                            InvocationScript   = new[] { (byte)'C' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 6,
                            OriginalViewNumber = 2,
                            Timestamp          = 1,
                            InvocationScript   = new[] { (byte)'D' }
                        }
                    }
                },
                PreparationHash     = new UInt256(Crypto.Default.Hash256(new[] { (byte)'a' })),
                PreparationMessages = new Dictionary <int, RecoveryMessage.PreparationPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 0,
                            InvocationScript = new[] { (byte)'t', (byte)'e' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 3,
                            InvocationScript = new[] { (byte)'1', (byte)'2' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 6,
                            InvocationScript = new[] { (byte)'3', (byte)'!' }
                        }
                    }
                },
                CommitMessages = new Dictionary <int, RecoveryMessage.CommitPayloadCompact>()
            };

            // msg.TransactionHashes = null;
            // msg.Nonce = 0;
            // msg.NextConsensus = null;
            // msg.MinerTransaction = (MinerTransaction) null;
            msg.PrepareRequestMessage.Should().Be(null);

            var copiedMsg = TestUtils.CopyMsgBySerialization(msg, new RecoveryMessage());;

            copiedMsg.ChangeViewMessages.ShouldAllBeEquivalentTo(msg.ChangeViewMessages);
            copiedMsg.PreparationHash.Should().Be(msg.PreparationHash);
            copiedMsg.PreparationMessages.ShouldAllBeEquivalentTo(msg.PreparationMessages);
            copiedMsg.CommitMessages.Count.Should().Be(0);
        }
Example #7
0
        public void TestSerializeAndDeserializeRecoveryMessageWithoutChangeViewsWithCommits()
        {
            Transaction[] txs = new Transaction[5];
            txs[0] = TestUtils.CreateRandomMockMinerTransaction().Object;
            for (int i = 1; i < txs.Length; i++)
            {
                txs[i] = TestUtils.CreateRandomHashInvocationMockTransaction().Object;
            }
            var msg = new RecoveryMessage
            {
                ChangeViewMessages    = new Dictionary <int, RecoveryMessage.ChangeViewPayloadCompact>(),
                PrepareRequestMessage = new PrepareRequest
                {
                    TransactionHashes = txs.Select(p => p.Hash).ToArray(),
                    Nonce             = ulong.MaxValue,
                    NextConsensus     = UInt160.Parse("5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA"),
                    MinerTransaction  = (MinerTransaction)txs[0]
                },
                PreparationMessages = new Dictionary <int, RecoveryMessage.PreparationPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 0,
                            InvocationScript = new[] { (byte)'t', (byte)'e' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 1,
                            InvocationScript = new[] { (byte)'s', (byte)'t' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 3,
                            InvocationScript = new[] { (byte)'1', (byte)'2' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex   = 6,
                            InvocationScript = new[] { (byte)'3', (byte)'!' }
                        }
                    }
                },
                CommitMessages = new Dictionary <int, RecoveryMessage.CommitPayloadCompact>
                {
                    {
                        1,
                        new RecoveryMessage.CommitPayloadCompact
                        {
                            ValidatorIndex = 1,
                            Signature      = new byte[64] {
                                (byte)'1', (byte)'2', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                            },
                            InvocationScript = new[] { (byte)'1', (byte)'2' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.CommitPayloadCompact
                        {
                            ValidatorIndex = 6,
                            Signature      = new byte[64] {
                                (byte)'3', (byte)'D', (byte)'R', (byte)'I', (byte)'N', (byte)'K', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                            },
                            InvocationScript = new[] { (byte)'6', (byte)'7' }
                        }
                    }
                }
            };

            var copiedMsg = TestUtils.CopyMsgBySerialization(msg, new RecoveryMessage());;

            copiedMsg.ChangeViewMessages.Count.Should().Be(0);
            copiedMsg.PrepareRequestMessage.ShouldBeEquivalentTo(msg.PrepareRequestMessage);
            copiedMsg.PreparationHash.Should().Be(null);
            copiedMsg.PreparationMessages.ShouldAllBeEquivalentTo(msg.PreparationMessages);
            copiedMsg.CommitMessages.ShouldAllBeEquivalentTo(msg.CommitMessages);
        }
Example #8
0
        public void ConsensusService_SingleNodeActors_OnStart_PrepReq_PrepResponses_Commits()
        {
            var mockWallet = new Mock <Wallet>();

            mockWallet.Setup(p => p.GetAccount(It.IsAny <UInt160>())).Returns <UInt160>(p => new TestWalletAccount(p));
            Console.WriteLine($"\n(UT-Consensus) Wallet is: {mockWallet.Object.GetAccount(UInt160.Zero).GetKey().PublicKey}");

            var mockContext = new Mock <ConsensusContext>(mockWallet.Object, Blockchain.Singleton.Store);

            mockContext.Object.LastSeenMessage = new int[] { 0, 0, 0, 0, 0, 0, 0 };

            var timeValues = new[] {
                new DateTime(1980, 06, 01, 0, 0, 1, 001, DateTimeKind.Utc),  // For tests, used below
                new DateTime(1980, 06, 01, 0, 0, 3, 001, DateTimeKind.Utc),  // For receiving block
                new DateTime(1980, 05, 01, 0, 0, 5, 001, DateTimeKind.Utc),  // For Initialize
                new DateTime(1980, 06, 01, 0, 0, 15, 001, DateTimeKind.Utc), // unused
            };

            for (int i = 0; i < timeValues.Length; i++)
            {
                Console.WriteLine($"time {i}: {timeValues[i].ToString()} ");
            }
            ulong defaultTimestamp = 328665601001;   // GMT: Sunday, June 1, 1980 12:00:01.001 AM
                                                     // check basic ConsensusContext
                                                     // mockConsensusContext.Object.block_received_time.ToTimestamp().Should().Be(4244941697); //1968-06-01 00:00:01
                                                     // ============================================================================
                                                     //                      creating ConsensusService actor
                                                     // ============================================================================

            int timeIndex = 0;
            var timeMock  = new Mock <TimeProvider>();

            timeMock.SetupGet(tp => tp.UtcNow).Returns(() => timeValues[timeIndex]);
            //.Callback(() => timeIndex = timeIndex + 1); //Comment while index is not fixed

            TimeProvider.Current = timeMock.Object;
            TimeProvider.Current.UtcNow.ToTimestampMS().Should().Be(defaultTimestamp); //1980-06-01 00:00:15:001

            //public void Log(string message, LogLevel level)
            //create ILogPlugin for Tests

            /*
             * mockConsensusContext.Setup(mr => mr.Log(It.IsAny<string>(), It.IsAny<LogLevel>()))
             *           .Callback((string message, LogLevel level) => {
             *                           Console.WriteLine($"CONSENSUS LOG: {message}");
             *                                                     }
             *                    );
             */

            // Creating a test block
            Header header = new Header();

            TestUtils.SetupHeaderWithValues(header, UInt256.Zero, out UInt256 merkRootVal, out UInt160 val160, out ulong timestampVal, out uint indexVal, out Witness scriptVal);
            header.Size.Should().Be(105);
            Console.WriteLine($"header {header} hash {header.Hash} {header.PrevHash} timestamp {timestampVal}");
            timestampVal.Should().Be(defaultTimestamp);
            TestProbe subscriber = CreateTestProbe();
            TestActorRef <ConsensusService> actorConsensus = ActorOfAsTestActorRef <ConsensusService>(
                Akka.Actor.Props.Create(() => (ConsensusService)Activator.CreateInstance(typeof(ConsensusService), BindingFlags.Instance | BindingFlags.NonPublic, null, new object[] { subscriber, subscriber, mockContext.Object }, null))
                );

            var testPersistCompleted = new Blockchain.PersistCompleted
            {
                Block = new Block
                {
                    Version       = header.Version,
                    PrevHash      = header.PrevHash,
                    MerkleRoot    = header.MerkleRoot,
                    Timestamp     = header.Timestamp,
                    Index         = header.Index,
                    NextConsensus = header.NextConsensus,
                    Transactions  = new Transaction[0]
                }
            };

            Console.WriteLine("\n==========================");
            Console.WriteLine("Telling a new block to actor consensus...");
            Console.WriteLine("will trigger OnPersistCompleted without OnStart flag!");
            // OnPersist will not launch timer, we need OnStart
            actorConsensus.Tell(testPersistCompleted);
            Console.WriteLine("\n==========================");

            Console.WriteLine("\n==========================");
            Console.WriteLine("will start consensus!");
            actorConsensus.Tell(new ConsensusService.Start
            {
                IgnoreRecoveryLogs = true
            });

            Console.WriteLine("Waiting for subscriber recovery message...");
            // The next line force a waits, then, subscriber keeps running its thread
            // In the next case it waits for a Msg of type LocalNode.SendDirectly
            // As we may expect, as soon as consensus start it sends a RecoveryRequest of this aforementioned type
            var askingForInitialRecovery = subscriber.ExpectMsg <LocalNode.SendDirectly>();

            Console.WriteLine($"Recovery Message I: {askingForInitialRecovery}");
            // Ensuring cast of type ConsensusPayload from the received message from subscriber
            ConsensusPayload initialRecoveryPayload = (ConsensusPayload)askingForInitialRecovery.Inventory;
            // Ensuring casting of type RecoveryRequest
            RecoveryRequest rrm = (RecoveryRequest)initialRecoveryPayload.ConsensusMessage;

            rrm.Timestamp.Should().Be(defaultTimestamp);

            Console.WriteLine("Waiting for backupChange View... ");
            var        backupOnAskingChangeView = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var        changeViewPayload        = (ConsensusPayload)backupOnAskingChangeView.Inventory;
            ChangeView cvm = (ChangeView)changeViewPayload.ConsensusMessage;

            cvm.Timestamp.Should().Be(defaultTimestamp);
            cvm.ViewNumber.Should().Be(0);
            cvm.Reason.Should().Be(ChangeViewReason.Timeout);

            Console.WriteLine("\n==========================");
            Console.WriteLine("will trigger OnPersistCompleted again with OnStart flag!");
            actorConsensus.Tell(testPersistCompleted);
            Console.WriteLine("\n==========================");

            // Disabling flag ViewChanging by reverting cache of changeview that was sent
            mockContext.Object.ChangeViewPayloads[mockContext.Object.MyIndex] = null;
            Console.WriteLine("Forcing Failed nodes for recovery request... ");
            mockContext.Object.CountFailed.Should().Be(0);
            mockContext.Object.LastSeenMessage = new int[] { -1, -1, -1, -1, -1, -1, -1 };
            mockContext.Object.CountFailed.Should().Be(7);
            Console.WriteLine("\nWaiting for recovery due to failed nodes... ");
            var backupOnRecoveryDueToFailedNodes = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var recoveryPayload = (ConsensusPayload)backupOnRecoveryDueToFailedNodes.Inventory;

            rrm = (RecoveryRequest)recoveryPayload.ConsensusMessage;
            rrm.Timestamp.Should().Be(defaultTimestamp);

            Console.WriteLine("will tell PrepRequest!");
            mockContext.Object.PrevHeader.Timestamp = defaultTimestamp;
            mockContext.Object.PrevHeader.NextConsensus.Should().Be(UInt160.Parse("0xbdbe3ca30e9d74df12ce57ebc95a302dfaa0828c"));
            var prepReq  = mockContext.Object.MakePrepareRequest();
            var ppToSend = (PrepareRequest)prepReq.ConsensusMessage;

            // Forcing hashes to 0 because mempool is currently shared
            ppToSend.TransactionHashes = new UInt256[0];
            ppToSend.TransactionHashes.Length.Should().Be(0);

            actorConsensus.Tell(prepReq);
            Console.WriteLine("Waiting for something related to the PrepRequest...\nNothing happens...Recovery will come due to failed nodes");
            var backupOnRecoveryDueToFailedNodesII = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var recoveryPayloadII = (ConsensusPayload)backupOnRecoveryDueToFailedNodesII.Inventory;

            rrm = (RecoveryRequest)recoveryPayloadII.ConsensusMessage;

            Console.WriteLine("\nFailed because it is not primary and it created the prereq...Time to adjust");
            prepReq.ValidatorIndex = 1; //simulating primary as prepreq creator (signature is skip, no problem)
            // cleaning old try with Self ValidatorIndex
            mockContext.Object.PreparationPayloads[mockContext.Object.MyIndex] = null;
            actorConsensus.Tell(prepReq);
            var             OnPrepResponse      = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var             prepResponsePayload = (ConsensusPayload)OnPrepResponse.Inventory;
            PrepareResponse prm = (PrepareResponse)prepResponsePayload.ConsensusMessage;

            prm.PreparationHash.Should().Be(prepReq.Hash);

            // Simulating CN 3
            actorConsensus.Tell(GetPayloadAndModifyValidator(prepResponsePayload, 2));

            // Simulating CN 5
            actorConsensus.Tell(GetPayloadAndModifyValidator(prepResponsePayload, 4));

            // Simulating CN 4
            actorConsensus.Tell(GetPayloadAndModifyValidator(prepResponsePayload, 3));

            var    onCommitPayload = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var    commitPayload   = (ConsensusPayload)onCommitPayload.Inventory;
            Commit cm = (Commit)commitPayload.ConsensusMessage;

            // Original Contract
            Contract originalContract = Contract.CreateMultiSigContract(mockContext.Object.M, mockContext.Object.Validators);

            Console.WriteLine($"\nORIGINAL Contract is: {originalContract.ScriptHash}");
            originalContract.ScriptHash.Should().Be(UInt160.Parse("0xbdbe3ca30e9d74df12ce57ebc95a302dfaa0828c"));
            mockContext.Object.Block.NextConsensus.Should().Be(UInt160.Parse("0xbdbe3ca30e9d74df12ce57ebc95a302dfaa0828c"));

            Console.WriteLine($"ORIGINAL BlockHash: {mockContext.Object.Block.Hash}");
            Console.WriteLine($"ORIGINAL Block NextConsensus: {mockContext.Object.Block.NextConsensus}");
            //Console.WriteLine($"VALIDATOR[0] {mockContext.Object.Validators[0]}");
            //Console.WriteLine($"VALIDATOR[0]ScriptHash: {mockWallet.Object.GetAccount(mockContext.Object.Validators[0]).ScriptHash}");

            KeyPair[] kp_array = new KeyPair[7]
            {
                UT_Crypto.generateKey(32),     // not used, kept for index consistency, didactically
                UT_Crypto.generateKey(32),
                UT_Crypto.generateKey(32),
                UT_Crypto.generateKey(32),
                UT_Crypto.generateKey(32),
                UT_Crypto.generateKey(32),
                UT_Crypto.generateKey(32)
            };
            for (int i = 0; i < mockContext.Object.Validators.Length; i++)
            {
                Console.WriteLine($"{mockContext.Object.Validators[i]}");
            }
            mockContext.Object.Validators = new ECPoint[7]
            {
                mockContext.Object.Validators[0],
                kp_array[1].PublicKey,
                kp_array[2].PublicKey,
                kp_array[3].PublicKey,
                kp_array[4].PublicKey,
                kp_array[5].PublicKey,
                kp_array[6].PublicKey
            };
            Console.WriteLine($"Generated keypairs PKey:");
            for (int i = 0; i < mockContext.Object.Validators.Length; i++)
            {
                Console.WriteLine($"{mockContext.Object.Validators[i]}");
            }

            // update Contract with some random validators
            var updatedContract = Contract.CreateMultiSigContract(mockContext.Object.M, mockContext.Object.Validators);

            Console.WriteLine($"\nContract updated: {updatedContract.ScriptHash}");

            // Forcing next consensus
            var originalBlockHashData = mockContext.Object.Block.GetHashData();

            mockContext.Object.Block.NextConsensus        = updatedContract.ScriptHash;
            mockContext.Object.Block.Header.NextConsensus = updatedContract.ScriptHash;
            mockContext.Object.PrevHeader.NextConsensus   = updatedContract.ScriptHash;
            var originalBlockMerkleRoot = mockContext.Object.Block.MerkleRoot;

            Console.WriteLine($"\noriginalBlockMerkleRoot: {originalBlockMerkleRoot}");
            var updatedBlockHashData = mockContext.Object.Block.GetHashData();

            Console.WriteLine($"originalBlockHashData: {originalBlockHashData.ToScriptHash()}");
            Console.WriteLine($"updatedBlockHashData: {updatedBlockHashData.ToScriptHash()}");

            Console.WriteLine("\n\n==========================");
            Console.WriteLine("\nBasic commits Signatures verification");
            // Basic tests for understanding signatures and ensuring signatures of commits are correct on tests
            var cmPayloadTemp = GetCommitPayloadModifiedAndSignedCopy(commitPayload, 1, kp_array[1], updatedBlockHashData);

            Crypto.VerifySignature(originalBlockHashData, cm.Signature, mockContext.Object.Validators[0].EncodePoint(false)).Should().BeFalse();
            Crypto.VerifySignature(updatedBlockHashData, cm.Signature, mockContext.Object.Validators[0].EncodePoint(false)).Should().BeFalse();
            Crypto.VerifySignature(originalBlockHashData, ((Commit)cmPayloadTemp.ConsensusMessage).Signature, mockContext.Object.Validators[1].EncodePoint(false)).Should().BeFalse();
            Crypto.VerifySignature(updatedBlockHashData, ((Commit)cmPayloadTemp.ConsensusMessage).Signature, mockContext.Object.Validators[1].EncodePoint(false)).Should().BeTrue();
            Console.WriteLine("\n==========================");

            Console.WriteLine("\n==========================");
            Console.WriteLine("\nCN2 simulation time");
            actorConsensus.Tell(cmPayloadTemp);

            Console.WriteLine("\nCN3 simulation time");
            actorConsensus.Tell(GetCommitPayloadModifiedAndSignedCopy(commitPayload, 2, kp_array[2], updatedBlockHashData));

            Console.WriteLine("\nCN4 simulation time");
            actorConsensus.Tell(GetCommitPayloadModifiedAndSignedCopy(commitPayload, 3, kp_array[3], updatedBlockHashData));

            // =============================================
            // Testing commit with wrong signature not valid
            // It will be invalid signature because we did not change ECPoint
            Console.WriteLine("\nCN7 simulation time. Wrong signature, KeyPair is not known");
            actorConsensus.Tell(GetPayloadAndModifyValidator(commitPayload, 6));

            Console.WriteLine("\nWaiting for recovery due to failed nodes... ");
            var             backupOnRecoveryMessageAfterCommit = subscriber.ExpectMsg <LocalNode.SendDirectly>();
            var             rmPayload = (ConsensusPayload)backupOnRecoveryMessageAfterCommit.Inventory;
            RecoveryMessage rmm       = (RecoveryMessage)rmPayload.ConsensusMessage;

            // =============================================

            mockContext.Object.CommitPayloads[0] = null;
            Console.WriteLine("\nCN5 simulation time");
            actorConsensus.Tell(GetCommitPayloadModifiedAndSignedCopy(commitPayload, 4, kp_array[4], updatedBlockHashData));


            Console.WriteLine($"\nFocing block PrevHash to UInt256.Zero {mockContext.Object.Block.GetHashData().ToScriptHash()}");
            mockContext.Object.Block.PrevHash = UInt256.Zero;
            // Payload should also be forced, otherwise OnConsensus will not pass
            commitPayload.PrevHash = UInt256.Zero;
            Console.WriteLine($"\nNew Hash is {mockContext.Object.Block.GetHashData().ToScriptHash()}");

            Console.WriteLine($"\nForcing block VerificationScript to {updatedContract.Script.ToScriptHash()}");
            mockContext.Object.Block.Witness = new Witness {
            };
            mockContext.Object.Block.Witness.VerificationScript = updatedContract.Script;
            Console.WriteLine($"\nUpdating BlockBase Witness scripthash  is {mockContext.Object.Block.Witness.ScriptHash}");
            Console.WriteLine($"\nNew Hash is {mockContext.Object.Block.GetHashData().ToScriptHash()}");

            Console.WriteLine("\nCN6 simulation time");
            // Here we used modified mockContext.Object.Block.GetHashData().ToScriptHash() for blockhash
            actorConsensus.Tell(GetCommitPayloadModifiedAndSignedCopy(commitPayload, 5, kp_array[5], mockContext.Object.Block.GetHashData()));

            Console.WriteLine("\nWait for subscriber Local.Node Relay");
            var onBlockRelay = subscriber.ExpectMsg <LocalNode.Relay>();

            Console.WriteLine("\nAsserting time was Block...");
            var utBlock = (Block)onBlockRelay.Inventory;

            Console.WriteLine($"\nAsserting block NextConsensus..{utBlock.NextConsensus}");
            utBlock.NextConsensus.Should().Be(updatedContract.ScriptHash);

            Console.WriteLine("\n==========================");
            // ============================================================================
            //                      finalize ConsensusService actor
            // ============================================================================
            Console.WriteLine("Finalizing consensus service actor and returning states.");
            TimeProvider.ResetToDefault();

            //Sys.Stop(actorConsensus);
        }
Example #9
0
        public static async Task Run(
            [TimerTrigger("%RedisDataPumpSchedule%", RunOnStartup = true)] TimerInfo myTimer,
            ILogger log)
        {
            // Get startTicks
            long startTicks = DateTime.UtcNow.Ticks;

            using (log.BeginScope(logProperties))
                // This DataLake client is used for writing exceptions that occur inside RedisDataPump. Do NOT remove it.
                using (DataLakeClient dataLake = new DataLakeClient(log))
                {
                    try
                    {
                        List <Task> tasks = new List <Task>();

                        // Pump and dump Redis lists (default: res-datalake)
                        tasks.Add(new DataLakeClient(log).FlushRedis(startTicks, 55000));

                        // Named
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.AccountsPayableInvoiceInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.AccountsPayableInvoiceOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.AccountsPayablePayInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.AdvanceShippingNoticeInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.Adyen)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.Coupon)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.CouponDeliveryOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.CustomerInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.CustomerOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.DropshipOrderInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.EdiPurchaseOrder)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.EmployeeInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.FraudOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.GeneralLedgerOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.GenericApi)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.GenericInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.GenericOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.Invalid)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.InventoryInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.InventoryOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.Loyalty)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.LoyaltyInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.LoyaltyOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.MapleLake)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.PricingOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.ProductInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.ProductOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.PurchaseAgreementOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.PurchaseOrderConfirmInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.PurchaseOrderInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderConfirmOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderDropshipOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderReturnInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderReturnOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SalesOrderSurveyOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SapReturnOrderInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SapSalesOrderUpdateInbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SupportImport)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.SvsGiftCardOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.TaxwareOutbound)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.TradeAgreementInbound_Map)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.TradeAgreementInbound_Purch)).FlushRedis(startTicks, 55000));
                        tasks.Add(new DataLakeClient(log, Extension.ToString(Res.ServiceName.TradeAgreementOutbound)).FlushRedis(startTicks, 55000));

                        // Wait for all Tasks
                        Task.WaitAll(tasks.ToArray());
                    }
                    catch (Exception ex)
                    {
                        await RecoveryMessage.SendAsync(new RecoveryMessage()
                        {
                            ServiceName   = ServiceName.DataLake,
                            FamilyName    = Extension.ToString(FamilyName.DataLake),
                            FunctionName  = nameof(RedisDataPump),
                            MethodName    = nameof(Run),
                            ResourceGroup = Extension.ToString(Res.ServiceName.DataLake),
                            Exception     = ex,
                        }, dataLake, log);
                    }
                }
        }
Example #10
0
        public void TestSerializeAndDeserializeRecoveryMessageWithChangeViewsAndPrepareRequest()
        {
            Transaction[] txs = new Transaction[5];
            txs[0] = TestUtils.CreateRandomMockBlockReward().Object;
            for (int i = 1; i < txs.Length; i++)
            {
                txs[i] = TestUtils.CreateRandomHashInvocationMockTransaction().Object;
            }
            var msg = new RecoveryMessage
            {
                ChangeViewMessages = new Dictionary <int, RecoveryMessage.ChangeViewPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 0,
                            OriginalViewNumber = 9,
                            Timestamp          = 6,
                            InvocationScript   = new[] { (byte)'A' }
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 1,
                            OriginalViewNumber = 7,
                            Timestamp          = 5,
                            InvocationScript   = new[] { (byte)'B' }
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 3,
                            OriginalViewNumber = 5,
                            Timestamp          = 3,
                            InvocationScript   = new[] { (byte)'C' }
                        }
                    },
                    {
                        6,
                        new RecoveryMessage.ChangeViewPayloadCompact
                        {
                            ValidatorIndex     = 6,
                            OriginalViewNumber = 2,
                            Timestamp          = 1,
                            InvocationScript   = new[] { (byte)'D' }
                        }
                    }
                },
                PrepareRequestMessage = new PrepareRequest
                {
                    TransactionHashes  = txs.Select(p => p.Hash).ToArray(),
                    Nonce              = ulong.MaxValue,
                    NextConsensus      = UInt160.Parse("5555AAAA5555AAAA5555AAAA5555AAAA5555AAAA"),
                    BlockReward        = (BlockReward)txs[0],
                    StateRootSignature = new byte[64]
                },
                PreparationHash     = new UInt256(Crypto.Default.Hash256(new[] { (byte)'a' })),
                PreparationMessages = new Dictionary <int, RecoveryMessage.PreparationPayloadCompact>()
                {
                    {
                        0,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex     = 0,
                            InvocationScript   = new[] { (byte)'t', (byte)'e' },
                            StateRootSignature = new byte[64]
                        }
                    },
                    {
                        1,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex     = 1,
                            InvocationScript   = new[] { (byte)'s', (byte)'t' },
                            StateRootSignature = new byte[64]
                        }
                    },
                    {
                        3,
                        new RecoveryMessage.PreparationPayloadCompact
                        {
                            ValidatorIndex     = 3,
                            InvocationScript   = new[] { (byte)'1', (byte)'2' },
                            StateRootSignature = new byte[64]
                        }
                    }
                },
                CommitMessages = new Dictionary <int, RecoveryMessage.CommitPayloadCompact>()
            };

            var copiedMsg = TestUtils.CopyMsgBySerialization(msg, new RecoveryMessage());;

            copiedMsg.ChangeViewMessages.ShouldAllBeEquivalentTo(msg.ChangeViewMessages);
            copiedMsg.PrepareRequestMessage.ShouldBeEquivalentTo(msg.PrepareRequestMessage);
            copiedMsg.PreparationHash.Should().Be(null);
            copiedMsg.PreparationMessages.ShouldAllBeEquivalentTo(msg.PreparationMessages);
            copiedMsg.CommitMessages.Count.Should().Be(0);
        }