2019-07-10 04:01:15 +00:00
|
|
|
/*
|
|
|
|
* @project: TERA
|
|
|
|
* @version: Development (beta)
|
|
|
|
* @license: MIT (not for evil)
|
|
|
|
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
|
|
|
|
* Web: https://terafoundation.org
|
|
|
|
* Twitter: https://twitter.com/terafoundation
|
|
|
|
* Telegram: https://t.me/terafoundation
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
require("../system/dapp");
|
|
|
|
require("../system/accounts");
|
|
|
|
require("../system/smart");
|
|
|
|
require("../system/file");
|
|
|
|
require("../system/messager");
|
|
|
|
require("../system/names");
|
|
|
|
if (global.PROCESS_NAME === "MAIN" || global.PROCESS_NAME === "TX")
|
|
|
|
require("./wallet");
|
|
|
|
module.exports = class CSmartContract extends require("./block-exchange")
|
|
|
|
{
|
2019-07-10 07:59:04 +00:00
|
|
|
BufHashTree
|
2019-07-10 04:01:15 +00:00
|
|
|
constructor(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual) {
|
|
|
|
super(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
2019-07-10 09:28:08 +00:00
|
|
|
this.BufHashTree = new global.RBTree(global.CompareArr)
|
2019-07-10 04:01:15 +00:00
|
|
|
this.BufHashTree.LastAddNum = 0
|
|
|
|
}
|
|
|
|
AddBlockToHashTree(Block) {
|
|
|
|
this.BufHashTree.LastAddNum = Block.BlockNum
|
|
|
|
var arr = Block.arrContent;
|
|
|
|
if (arr) {
|
|
|
|
for (var i = 0; i < arr.length; i++) {
|
|
|
|
var HASH = global.shaarr(arr[i]);
|
|
|
|
this.BufHashTree.insert(HASH)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DeleteBlockFromHashTree(Block) {
|
|
|
|
var arr = Block.arrContent;
|
|
|
|
if (arr) {
|
|
|
|
for (var i = 0; i < arr.length; i++) {
|
|
|
|
var HASH = global.shaarr(arr[i]);
|
|
|
|
this.BufHashTree.remove(HASH)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
OnWriteBlock(Block) {
|
|
|
|
}
|
|
|
|
BlockProcessTX(Block) {
|
|
|
|
if (Block.BlockNum < 1)
|
|
|
|
return;
|
|
|
|
var COUNT_MEM_BLOCKS = 0;
|
|
|
|
var NUM1 = 1240000;
|
|
|
|
var NUM2 = 1400000;
|
|
|
|
if (global.LOCAL_RUN) {
|
|
|
|
NUM1 = 15
|
|
|
|
NUM2 = 100
|
|
|
|
}
|
|
|
|
if (Block.BlockNum > global.BLOCKNUM_TICKET_ALGO) {
|
|
|
|
NUM1 = 1000000000000
|
|
|
|
NUM2 = 1000000000000
|
|
|
|
}
|
|
|
|
if (Block.BlockNum > NUM1) {
|
|
|
|
COUNT_MEM_BLOCKS = 1
|
|
|
|
if (Block.BlockNum > NUM2)
|
|
|
|
COUNT_MEM_BLOCKS = 60
|
|
|
|
if (this.BufHashTree.LastAddNum !== Block.BlockNum - 1) {
|
|
|
|
this.BufHashTree.clear()
|
|
|
|
for (var num = COUNT_MEM_BLOCKS; num >= 1; num--) {
|
|
|
|
var Block2 = this.ReadBlockDB(Block.BlockNum - num);
|
|
|
|
if (Block2) {
|
|
|
|
this.AddBlockToHashTree(Block2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-10 07:59:04 +00:00
|
|
|
for (var key in global.DApps) {
|
|
|
|
global.DApps[key].OnWriteBlockStart(Block)
|
2019-07-10 04:01:15 +00:00
|
|
|
}
|
|
|
|
var arrContentResult = [];
|
|
|
|
var BlockNum = Block.BlockNum;
|
|
|
|
var arr = Block.arrContent;
|
|
|
|
if (arr)
|
|
|
|
for (var i = 0; i < arr.length; i++) {
|
|
|
|
var HASH = global.shaarr(arr[i]);
|
|
|
|
if (this.BufHashTree.find(HASH)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
var type = arr[i][0];
|
2019-07-10 07:59:04 +00:00
|
|
|
var App = global.DAppByType[type];
|
2019-07-10 04:01:15 +00:00
|
|
|
if (App) {
|
|
|
|
App.ResultTx = 0
|
|
|
|
global.DApps.Accounts.BeginTransaction()
|
2019-07-10 07:59:04 +00:00
|
|
|
var StrHex = global.GetHexFromArr(global.sha3(arr[i]));
|
2019-07-10 04:01:15 +00:00
|
|
|
var item;
|
|
|
|
global.CurTrItem = undefined
|
|
|
|
if (global.TreeFindTX) {
|
|
|
|
item = global.TreeFindTX.LoadValue(StrHex)
|
|
|
|
if (item)
|
|
|
|
global.CurTrItem = item.TX
|
|
|
|
}
|
|
|
|
var Result = App.OnWriteTransaction(Block, arr[i], BlockNum, i);
|
|
|
|
var SetResult = Result;
|
|
|
|
if (Result === true) {
|
|
|
|
if (App.ResultTx)
|
|
|
|
SetResult = App.ResultTx
|
2019-07-10 07:59:04 +00:00
|
|
|
if (!global.DApps.Accounts.CommitTransaction(BlockNum, i))
|
2019-07-10 04:01:15 +00:00
|
|
|
SetResult = 0
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
global.DApps.Accounts.RollBackTransaction()
|
|
|
|
SetResult = 0
|
|
|
|
}
|
|
|
|
if (SetResult === true)
|
|
|
|
SetResult = 1
|
|
|
|
arrContentResult[i] = SetResult
|
|
|
|
if (item) {
|
|
|
|
var ResultStr = Result;
|
|
|
|
if (Result === true || typeof Result === "number") {
|
|
|
|
ResultStr = "Add to blockchain"
|
|
|
|
if (type === global.TYPE_TRANSACTION_FILE)
|
|
|
|
ResultStr += ": file/" + BlockNum + "/" + i
|
|
|
|
}
|
|
|
|
item.cmd = "RetFindTX"
|
|
|
|
item.ResultStr = "" + ResultStr
|
|
|
|
item.bFinal = 1
|
|
|
|
item.Result = SetResult
|
|
|
|
process.send(item)
|
|
|
|
}
|
|
|
|
global.CurTrItem = undefined
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (COUNT_MEM_BLOCKS) {
|
|
|
|
var Block2 = this.ReadBlockDB(Block.BlockNum - COUNT_MEM_BLOCKS);
|
|
|
|
if (Block2)
|
|
|
|
this.DeleteBlockFromHashTree(Block2)
|
|
|
|
this.AddBlockToHashTree(Block)
|
|
|
|
}
|
|
|
|
if (arrContentResult.length)
|
|
|
|
process.send({ cmd: "WriteBodyResult", BlockNum: Block.BlockNum, arrContentResult: arrContentResult })
|
2019-07-10 07:59:04 +00:00
|
|
|
for (var key in global.DApps) {
|
|
|
|
global.DApps[key].OnWriteBlockFinish(Block)
|
2019-07-10 04:01:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
BlockDeleteTX(Block) {
|
|
|
|
this.BufHashTree.LastAddNum = 0
|
2019-07-10 07:59:04 +00:00
|
|
|
for (var key in global.DApps) {
|
|
|
|
global.DApps[key].OnDeleteBlock(Block)
|
2019-07-10 04:01:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
OnDelete(Block) {
|
|
|
|
}
|
|
|
|
IsValidTicket(Tr, BlockNum) {
|
|
|
|
this.CheckCreateTicketObject(Tr, BlockNum)
|
2019-07-10 07:59:04 +00:00
|
|
|
if (Tr.power < global.MIN_POWER_POW_TR)
|
2019-07-10 04:01:15 +00:00
|
|
|
return - 2;
|
|
|
|
if (Tr.num !== BlockNum)
|
|
|
|
return - 3;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
IsValidTransaction(Tr, BlockNum) {
|
2019-07-10 07:59:04 +00:00
|
|
|
if (!Tr.body || Tr.body.length < global.MIN_TRANSACTION_SIZE || Tr.body.length > global.MAX_TRANSACTION_SIZE)
|
2019-07-10 04:01:15 +00:00
|
|
|
return - 1;
|
|
|
|
this.CheckCreateTransactionObject(Tr)
|
2019-07-10 07:59:04 +00:00
|
|
|
if (Tr.power - Math.log2(Tr.body.length / 128) < global.MIN_POWER_POW_TR)
|
2019-07-10 04:01:15 +00:00
|
|
|
return - 2;
|
|
|
|
if (Tr.num !== BlockNum)
|
|
|
|
return - 3;
|
2019-07-10 07:59:04 +00:00
|
|
|
if (Tr.body[0] === global.TYPE_TRANSACTION_ACC_HASH)
|
2019-07-10 04:01:15 +00:00
|
|
|
return - 4;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
ReWriteDAppTransactions(Length) {
|
2019-07-10 07:59:04 +00:00
|
|
|
if (!global.TX_PROCESS.Worker)
|
2019-07-10 04:01:15 +00:00
|
|
|
return 0;
|
|
|
|
if (!Length)
|
|
|
|
return 0;
|
|
|
|
var StartNum = this.BlockNumDB - Length + 1;
|
|
|
|
if (StartNum < 0)
|
|
|
|
StartNum = 0
|
|
|
|
var EndNum = this.BlockNumDB;
|
|
|
|
var MinBlock = global.DApps.Accounts.GetMinBlockAct();
|
|
|
|
if (MinBlock > StartNum) {
|
|
|
|
global.ToLog("Cant rewrite transactions. Very long length of the rewriting chain. Max length=" + (this.BlockNumDB - MinBlock))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
|
|
|
global.TX_PROCESS.RunRPC("ReWriteDAppTransactions", { StartNum: StartNum, EndNum: EndNum })
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
AddDAppTransactions(BlockNum, Arr) {
|
2019-07-10 07:59:04 +00:00
|
|
|
if (BlockNum % global.PERIOD_ACCOUNT_HASH !== 0)
|
2019-07-10 04:01:15 +00:00
|
|
|
return;
|
2019-07-10 07:59:04 +00:00
|
|
|
var BlockNumHash = BlockNum - global.DELTA_BLOCK_ACCOUNT_HASH;
|
2019-07-10 04:01:15 +00:00
|
|
|
if (BlockNumHash < 0)
|
|
|
|
return;
|
|
|
|
var Item = global.DApps.Accounts.GetAccountHashItem(BlockNumHash);
|
|
|
|
if (Item) {
|
2019-07-10 07:59:04 +00:00
|
|
|
var Body = [global.TYPE_TRANSACTION_ACC_HASH];
|
|
|
|
global.WriteUintToArr(Body, BlockNumHash)
|
|
|
|
global.WriteArrToArr(Body, Item.AccHash, 32)
|
|
|
|
if (BlockNumHash >= global.START_BLOCK_ACCOUNT_HASH3) {
|
|
|
|
global.WriteUintToArr(Body, Item.AccountMax)
|
|
|
|
global.WriteArrToArr(Body, Item.SmartHash, 32)
|
|
|
|
global.WriteUintToArr(Body, Item.SmartCount)
|
|
|
|
global.WriteUintToArr(Body, BlockNum)
|
|
|
|
global.WriteUintToArr(Body, 0)
|
2019-07-10 04:01:15 +00:00
|
|
|
}
|
|
|
|
var Tr = { body: Body };
|
|
|
|
this.CheckCreateTransactionObject(Tr)
|
|
|
|
Arr.unshift(Tr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
AddTransactionOwn(Tr) {
|
|
|
|
if (!global.TX_PROCESS.Worker)
|
|
|
|
return - 6;
|
2019-07-10 07:59:04 +00:00
|
|
|
var StrHex = global.GetHexFromArr(global.sha3(Tr.body));
|
2019-07-10 04:01:15 +00:00
|
|
|
global.TX_PROCESS.Worker.send({ cmd: "FindTX", TX: StrHex })
|
|
|
|
return this.AddTransaction(Tr, 1);
|
|
|
|
}
|
|
|
|
};
|