public async Task Update_ZeroContract_Test() { var code = Codes.Single(kv => kv.Key.Contains("GenesisUpdate")).Value; var contractUpdateInput = new ContractUpdateInput { Address = BasicContractZeroAddress, Code = ByteString.CopyFrom(code) }; const string methodName = nameof(BasicContractZero.UpdateSmartContract); var proposalId = await CreateProposalAsync(methodName, contractUpdateInput); var txResult1 = await ApproveWithMinersAsync(proposalId); txResult1.Status.ShouldBe(TransactionResultStatus.Mined); var txResult2 = await ReleaseProposalAsync(proposalId); txResult2.Status.ShouldBe(TransactionResultStatus.Mined); var contractAddress = CodeUpdated.Parser.ParseFrom(txResult2.Logs[0].Indexed[0]).Address; contractAddress.ShouldBe(BasicContractZeroAddress); var codeHash = Hash.FromRawBytes(code); var newHash = CodeUpdated.Parser.ParseFrom(txResult2.Logs[0].NonIndexed).NewCodeHash; newHash.ShouldBe(codeHash); }
public async Task UpdateSmartContractWithCodeCheck_Test() { var contractDeploymentInput = new ContractDeploymentInput { Category = KernelConstants.DefaultRunnerCategory, // test the default runner Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.Contains("TokenConverter")).Value) }; var newAddress = await DeployAsync(Tester, ParliamentAddress, contractDeploymentInput); var code = Codes.Single(kv => kv.Key.Contains("ReferendumAuth")).Value; var contractUpdateInput = new ContractUpdateInput { Address = newAddress, Code = ByteString.CopyFrom(code) }; var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput); proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var proposalId = ProposalCreated.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed) .ProposalId; proposalId.ShouldNotBeNull(); var proposedContractInputHash = ContractProposed.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed) .ProposedContractInputHash; await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput { ProposalId = proposalId, ProposedContractInputHash = proposedContractInputHash }); releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var codeCheckProposalId = ProposalCreated.Parser .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))) .NonIndexed).ProposalId; codeCheckProposalId.ShouldNotBeNull(); // Wait for contract code check event handler to finish its job // Mine a block, should include approval transaction var block = await Tester.MineEmptyBlockAsync(); var txs = await Tester.GetTransactionsAsync(block.TransactionIds); txs.First(tx => tx.To == ParliamentAddress).MethodName .ShouldBe(nameof(ParliamentAuthContractContainer.ParliamentAuthContractStub.ApproveMultiProposals)); }
public override Address UpdateSmartContract(ContractUpdateInput input) { var contractAddress = input.Address; var code = input.Code.ToByteArray(); var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract not found."); RequireSenderAuthority(State.CodeCheckController.Value?.OwnerAddress); var inputHash = CalculateHashFromInput(input); if (!TryClearContractProposingData(inputHash, out _)) { Assert(Context.Sender == info.Author, "No permission."); } var oldCodeHash = info.CodeHash; var newCodeHash = Hash.FromRawBytes(code); Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed."); Assert(State.SmartContractRegistrations[newCodeHash] == null, "Same code has been deployed before."); info.CodeHash = newCodeHash; info.Version++; State.ContractInfos[contractAddress] = info; var reg = new SmartContractRegistration { Category = info.Category, Code = ByteString.CopyFrom(code), CodeHash = newCodeHash, IsSystemContract = info.IsSystemContract, Version = info.Version }; State.SmartContractRegistrations[reg.CodeHash] = reg; Context.UpdateContract(contractAddress, reg, null); Context.Fire(new CodeUpdated() { Address = contractAddress, OldCodeHash = oldCodeHash, NewCodeHash = newCodeHash, Version = info.Version }); Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted()); return(contractAddress); }
public override Hash ProposeUpdateContract(ContractUpdateInput input) { var proposedContractInputHash = CalculateHashFromInput(input); Assert(State.ContractProposingInputMap[proposedContractInputHash] == null, "Already proposed."); State.ContractProposingInputMap[proposedContractInputHash] = new ContractProposingInput { Proposer = Context.Sender, Status = ContractProposingInputStatus.Proposed }; var contractAddress = input.Address; var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract does not exist."); AssertAuthorityByContractInfo(info, Context.Sender); // Create proposal for deployment RequireParliamentContractAddressSet(); var proposalCreationInput = new CreateProposalBySystemContractInput { ProposalInput = new CreateProposalInput { ToAddress = Context.Self, ContractMethodName = nameof(BasicContractZeroContainer.BasicContractZeroBase.ProposeContractCodeCheck), Params = new ContractCodeCheckInput { ContractInput = input.ToByteString(), IsContractDeployment = false }.ToByteString(), OrganizationAddress = State.ContractDeploymentController.Value.OwnerAddress, ExpiredTime = Context.CurrentBlockTime.AddSeconds(ContractProposalExpirationTimePeriod) }, OriginProposer = Context.Sender }; Context.SendInline(State.ContractDeploymentController.Value.ContractAddress, nameof(AuthorizationContractContainer.AuthorizationContractReferenceState .CreateProposalBySystemContract), proposalCreationInput); // Fire event to trigger BPs checking contract code Context.Fire(new ContractProposed { ProposedContractInputHash = proposedContractInputHash }); return(proposedContractInputHash); }
public async Task Update_ZeroContract_Test() { var code = Codes.Single(kv => kv.Key.Contains("GenesisUpdate")).Value; var contractUpdateInput = new ContractUpdateInput { Address = BasicContractZeroAddress, Code = ByteString.CopyFrom(code) }; var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput); proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var proposalId = ProposalCreated.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed) .ProposalId; proposalId.ShouldNotBeNull(); var proposedContractInputHash = ContractProposed.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed) .ProposedContractInputHash; await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput { ProposalId = proposalId, ProposedContractInputHash = proposedContractInputHash }); releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var codeCheckProposalId = ProposalCreated.Parser .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))) .NonIndexed).ProposalId; codeCheckProposalId.ShouldNotBeNull(); await ApproveWithMinersAsync(Tester, ParliamentAddress, codeCheckProposalId); var result = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZeroContainer.BasicContractZeroStub.ReleaseCodeCheckedContract), new ReleaseContractInput { ProposedContractInputHash = proposedContractInputHash, ProposalId = codeCheckProposalId }); result.Status.ShouldBe(TransactionResultStatus.Mined); }
public override Address UpdateSmartContract(ContractUpdateInput input) { var contractAddress = input.Address; var code = input.Code.ToByteArray(); var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract does not exist."); if (info.IsSystemContract) { RequireAuthority(State.GenesisOwner.Value); } else { RequireAuthority(); Assert(info.Author == Context.Origin, "Only author can propose contract update."); } var oldCodeHash = info.CodeHash; var newCodeHash = Hash.FromRawBytes(code); Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed."); info.CodeHash = newCodeHash; State.ContractInfos[contractAddress] = info; var reg = new SmartContractRegistration { Category = info.Category, Code = ByteString.CopyFrom(code), CodeHash = newCodeHash }; State.SmartContractRegistrations[reg.CodeHash] = reg; Context.UpdateContract(contractAddress, reg, null); Context.Fire(new CodeUpdated() { Address = contractAddress, OldCodeHash = oldCodeHash, NewCodeHash = newCodeHash }); Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted()); return(contractAddress); }
public override Hash ProposeUpdateContract(ContractUpdateInput input) { var proposedContractInputHash = CalculateHashFromInput(input); RegisterContractProposingData(proposedContractInputHash); var contractAddress = input.Address; var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract not found."); AssertAuthorityByContractInfo(info, Context.Sender); // Create proposal for contract update var proposalCreationInput = new CreateProposalBySystemContractInput { ProposalInput = new CreateProposalInput { ToAddress = Context.Self, ContractMethodName = nameof(BasicContractZeroImplContainer.BasicContractZeroImplBase.ProposeContractCodeCheck), Params = new ContractCodeCheckInput { ContractInput = input.ToByteString(), CodeCheckReleaseMethod = nameof(UpdateSmartContract), ProposedContractInputHash = proposedContractInputHash, Category = info.Category, IsSystemContract = info.IsSystemContract }.ToByteString(), OrganizationAddress = State.ContractDeploymentController.Value.OwnerAddress, ExpiredTime = Context.CurrentBlockTime.AddSeconds(ContractProposalExpirationTimePeriod), }, OriginProposer = Context.Sender }; Context.SendInline(State.ContractDeploymentController.Value.ContractAddress, nameof(AuthorizationContractContainer.AuthorizationContractReferenceState .CreateProposalBySystemContract), proposalCreationInput); Context.Fire(new ContractProposed { ProposedContractInputHash = proposedContractInputHash }); return(proposedContractInputHash); }
public override Hash ProposeUpdateContract(ContractUpdateInput input) { var proposedContractInputHash = CalculateHashFromInput(input); Assert(State.ContractProposingInputMap[proposedContractInputHash] == null, "Already proposed."); State.ContractProposingInputMap[proposedContractInputHash] = new ContractProposingInput { Proposer = Context.Sender, Status = ContractProposingInputStatus.Proposed }; var contractAddress = input.Address; var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract does not exist."); RequireAuthorityByContractInfo(info); // Create proposal for deployment RequireParliamentAuthAddressSet(); State.ParliamentAuthContract.CreateProposal.Send(new CreateProposalInput { ToAddress = Context.Self, ContractMethodName = nameof(BasicContractZeroContainer.BasicContractZeroBase.ProposeContractCodeCheck), Params = new ContractCodeCheckInput { ContractInput = input.ToByteString(), IsContractDeployment = false }.ToByteString(), OrganizationAddress = State.GenesisOwner.Value, ExpiredTime = Context.CurrentBlockTime.AddMinutes(10) // Maybe, get the interval from configuration }); // Fire event to trigger BPs checking contract code Context.Fire(new ContractProposed { ProposedContractInputHash = proposedContractInputHash }); return(proposedContractInputHash); }
public async Task UpdateContract_Attach_After_ReadOnly_Transaction() { var chain = await _blockchainService.GetChainAsync(); var blockHeight = chain.BestChainHeight; var blockHash = chain.BestChainHash; var input = new ContractUpdateInput { Address = BasicFunctionContractAddress, Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value) }.ToByteString(); var transaction = CreateTransaction(DefaultSender, ContractZeroAddress, nameof(BasicContractZeroStub.UpdateSmartContract), input, blockHeight, blockHash); var block = await ExecuteAsync(transaction, blockHeight, blockHash); var transactionResult = await _transactionResultManager.GetTransactionResultAsync(transaction.GetHash(), block.Header.GetDisambiguatingHash()); var basicFunctionContractStub = GetTestBasicFunctionContractStub(DefaultSenderKeyPair); await basicFunctionContractStub.QueryWinMoney.CallAsync(new Empty()); await _blockAttachService.AttachBlockAsync(block); var basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair); // //execute new action method var transactionResult1 = (await basic11ContractStub.UpdateStopBet.SendAsync( new Empty())).TransactionResult; transactionResult1.Status.ShouldBe(TransactionResultStatus.Mined); //call new view method var result = (await basic11ContractStub.QueryBetStatus.CallAsync( new Empty())).BoolValue; result.ShouldBeTrue(); await _blockchainService.SetIrreversibleBlockAsync(chain, block.Height, block.GetHash()); }
public override Address UpdateSmartContract(ContractUpdateInput input) { var contractAddress = input.Address; var code = input.Code.ToByteArray(); var info = State.ContractInfos[contractAddress]; Assert(info != null, "Contract does not exist."); Assert(info.Owner.Equals(Context.Sender), "Only owner is allowed to update code."); var oldCodeHash = info.CodeHash; var newCodeHash = Hash.FromRawBytes(code); Assert(!oldCodeHash.Equals(newCodeHash), "Code is not changed."); info.CodeHash = newCodeHash; State.ContractInfos[contractAddress] = info; var reg = new SmartContractRegistration { Category = info.Category, Code = ByteString.CopyFrom(code), CodeHash = newCodeHash }; State.SmartContractRegistrations[reg.CodeHash] = reg; Context.UpdateContract(contractAddress, reg, null); Context.Fire(new CodeUpdated() { Address = contractAddress, OldCodeHash = oldCodeHash, NewCodeHash = newCodeHash }); Context.LogDebug(() => "BasicContractZero - update success: " + contractAddress.GetFormatted()); return(contractAddress); }
public async Task UpdateSmartContract_Test() { var contractDeploymentInput = new ContractDeploymentInput { Category = KernelConstants.DefaultRunnerCategory, // test the default runner Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.Contains("TokenConverter")).Value) }; var newAddress = await DeployAsync(Tester, ParliamentAddress, contractDeploymentInput); var code = Codes.Single(kv => kv.Key.Contains("Treasury")).Value; var contractUpdateInput = new ContractUpdateInput { Address = newAddress, Code = ByteString.CopyFrom(code) }; var proposingTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ProposeUpdateContract), contractUpdateInput); proposingTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var proposalId = ProposalCreated.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))).NonIndexed) .ProposalId; proposalId.ShouldNotBeNull(); var proposedContractInputHash = ContractProposed.Parser .ParseFrom(proposingTxResult.Logs.First(l => l.Name.Contains(nameof(ContractProposed))).NonIndexed) .ProposedContractInputHash; await ApproveWithMinersAsync(Tester, ParliamentAddress, proposalId); var releaseApprovedContractTxResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZero.ReleaseApprovedContract), new ReleaseContractInput { ProposalId = proposalId, ProposedContractInputHash = proposedContractInputHash }); releaseApprovedContractTxResult.Status.ShouldBe(TransactionResultStatus.Mined); var codeCheckProposalId = ProposalCreated.Parser .ParseFrom(releaseApprovedContractTxResult.Logs.First(l => l.Name.Contains(nameof(ProposalCreated))) .NonIndexed).ProposalId; codeCheckProposalId.ShouldNotBeNull(); await ApproveWithMinersAsync(Tester, ParliamentAddress, codeCheckProposalId); var updateResult = await Tester.ExecuteContractWithMiningAsync(BasicContractZeroAddress, nameof(BasicContractZeroContainer.BasicContractZeroStub.ReleaseCodeCheckedContract), new ReleaseContractInput { ProposedContractInputHash = proposedContractInputHash, ProposalId = codeCheckProposalId }); updateResult.Status.ShouldBe(TransactionResultStatus.Mined); var contractAddress = CodeUpdated.Parser .ParseFrom(updateResult.Logs.First(l => l.Name.Contains(nameof(CodeUpdated))).Indexed[0]).Address; contractAddress.ShouldBe(newAddress); var codeHash = Hash.FromRawBytes(code); var newHash = CodeUpdated.Parser .ParseFrom(updateResult.Logs.First(l => l.Name.Contains(nameof(CodeUpdated))).NonIndexed).NewCodeHash; newHash.ShouldBe(codeHash); }
public async Task UpdateContract_With_Two_Branch() { var blockHeader = await _blockchainService.GetBestChainLastBlockHeaderAsync(); var startBlockHeight = blockHeader.Height; var startBlockHash = blockHeader.GetHash(); var transactionResult = (await BasicContractZeroStub.UpdateSmartContract.SendAsync( new ContractUpdateInput { Address = BasicFunctionContractAddress, Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value) } )).TransactionResult; transactionResult.Status.ShouldBe(TransactionResultStatus.Mined); var basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair); // //execute new action method var transactionResult1 = (await basic11ContractStub.UpdateStopBet.SendAsync( new Empty())).TransactionResult; transactionResult1.Status.ShouldBe(TransactionResultStatus.Mined); var transaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress, nameof(TestBasicFunctionContractStub.QueryWinMoney), new Empty().ToByteString(), startBlockHeight, startBlockHash); var block = await ExecuteAsync(transaction, startBlockHeight, startBlockHash); await _blockAttachService.AttachBlockAsync(block); transaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress, nameof(TestBasicFunctionContractStub.QueryWinMoney), new Empty().ToByteString(), block.Height, block.GetHash()); block = await ExecuteAsync(transaction, block.Height, block.GetHash()); await _blockAttachService.AttachBlockAsync(block); var input = new Empty().ToByteString(); var failedTransaction = CreateTransaction(DefaultSender, BasicFunctionContractAddress, nameof(basic11ContractStub.UpdateStopBet), input, block.Height, block.GetHash()); block = await ExecuteAsync(failedTransaction, block.Height, block.GetHash()); await _blockAttachService.AttachBlockAsync(block); transactionResult = await _transactionResultManager.GetTransactionResultAsync(failedTransaction.GetHash(), block.Header.GetDisambiguatingHash()); transactionResult.Status.ShouldBe(TransactionResultStatus.Failed); transactionResult.Error.ShouldContain("Failed to find handler for UpdateStopBet."); input = new ContractUpdateInput { Address = BasicFunctionContractAddress, Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicFunction")).Value) }.ToByteString(); var updateTransaction = CreateTransaction(DefaultSender, ContractZeroAddress, nameof(BasicContractZeroStub.UpdateSmartContract), input, block.Height, block.GetHash()); var updateBlock = await ExecuteAsync(updateTransaction, block.Height, block.GetHash()); await _blockAttachService.AttachBlockAsync(updateBlock); // transactionResult = await _transactionResultManager.GetTransactionResultAsync(updateTransaction.GetHash(), updateBlock.Header.GetDisambiguatingHash()); transactionResult.Status.ShouldBe(TransactionResultStatus.Failed); transactionResult.Error.Contains("Code is not changed").ShouldBeTrue(); input = new ContractUpdateInput { Address = BasicFunctionContractAddress, Code = ByteString.CopyFrom(Codes.Single(kv => kv.Key.EndsWith("BasicUpdate")).Value) }.ToByteString(); updateTransaction = CreateTransaction(DefaultSender, ContractZeroAddress, nameof(BasicContractZeroStub.UpdateSmartContract), input, updateBlock.Height, updateBlock.GetHash()); updateBlock = await ExecuteAsync(updateTransaction, updateBlock.Height, updateBlock.GetHash()); await _blockAttachService.AttachBlockAsync(updateBlock); transactionResult = await _transactionResultManager.GetTransactionResultAsync(updateTransaction.GetHash(), updateBlock.Header.GetDisambiguatingHash()); transactionResult.Status.ShouldBe(TransactionResultStatus.Mined); basic11ContractStub = GetTestBasicUpdateContractStub(DefaultSenderKeyPair); //execute new action method transactionResult = (await basic11ContractStub.UpdateStopBet.SendAsync( new Empty())).TransactionResult; transactionResult.Status.ShouldBe(TransactionResultStatus.Mined); //call new view method var result = (await basic11ContractStub.QueryBetStatus.CallAsync( new Empty())).BoolValue; result.ShouldBeTrue(); }