neo-blockchain-impl
Version:
NEO Blockchain core implementation.
1,592 lines (1,403 loc) • 107 kB
JavaScript
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var neoBlockchainCore = require('neo-blockchain-core');
var neoBlockchainNodeCore = require('neo-blockchain-node-core');
var PriorityQueue = _interopDefault(require('js-priority-queue'));
var _ = _interopDefault(require('lodash'));
var perf_hooks = require('perf_hooks');
var rxjs = require('rxjs');
function _typeof(obj) {
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _next(value) {
step("next", value);
}
function _throw(err) {
step("throw", err);
}
_next();
});
};
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _slicedToArray(arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return _sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
}
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
}
var _fixBabelExtend = function (O) {
var gOPD = O.getOwnPropertyDescriptor,
gPO = O.getPrototypeOf || function (o) {
return o.__proto__;
},
sPO = O.setPrototypeOf || function (o, p) {
o.__proto__ = p;
return o;
},
construct = _typeof(Reflect) === 'object' ? Reflect.construct : function (Parent, args, Class) {
var Constructor,
a = [null];
a.push.apply(a, args);
Constructor = Parent.bind.apply(Parent, a);
return sPO(new Constructor(), Class.prototype);
};
return function fixBabelExtend(Class) {
var Parent = gPO(Class);
return sPO(Class, sPO(function Super() {
return construct(Parent, arguments, gPO(this).constructor);
}, Parent));
};
}(Object);
var GenesisBlockNotRegisteredError = _fixBabelExtend(
/*#__PURE__*/
function (_Error) {
_inherits(GenesisBlockNotRegisteredError, _Error);
function GenesisBlockNotRegisteredError() {
_classCallCheck(this, GenesisBlockNotRegisteredError);
return _possibleConstructorReturn(this, (GenesisBlockNotRegisteredError.__proto__ || Object.getPrototypeOf(GenesisBlockNotRegisteredError)).call(this, 'Genesis block was not registered with storage.'));
}
return GenesisBlockNotRegisteredError;
}(Error));
var VerifyError = _fixBabelExtend(
/*#__PURE__*/
function (_Error2) {
_inherits(VerifyError, _Error2);
function VerifyError() {
_classCallCheck(this, VerifyError);
return _possibleConstructorReturn(this, (VerifyError.__proto__ || Object.getPrototypeOf(VerifyError)).call(this, 'Script verification failed.'));
}
return VerifyError;
}(Error));
var WitnessVerifyError = _fixBabelExtend(
/*#__PURE__*/
function (_Error3) {
_inherits(WitnessVerifyError, _Error3);
function WitnessVerifyError() {
_classCallCheck(this, WitnessVerifyError);
return _possibleConstructorReturn(this, (WitnessVerifyError.__proto__ || Object.getPrototypeOf(WitnessVerifyError)).call(this, 'Witness verification failed.'));
}
return WitnessVerifyError;
}(Error));
function createGet(_ref) {
var tryGetTracked = _ref.tryGetTracked,
readStorage = _ref.readStorage;
return function () {
var _ref2 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(key) {
var trackedChange, value;
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
trackedChange = tryGetTracked(key);
if (!(trackedChange != null)) {
_context.next = 5;
break;
}
if (!(trackedChange.type === 'delete')) {
_context.next = 4;
break;
}
throw new Error('Not found');
case 4:
return _context.abrupt("return", trackedChange.value);
case 5:
_context.next = 7;
return readStorage.get(key);
case 7:
value = _context.sent;
return _context.abrupt("return", value);
case 9:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
return function (_x) {
return _ref2.apply(this, arguments);
};
}();
}
function createTryGet(_ref3) {
var tryGetTracked = _ref3.tryGetTracked,
readStorage = _ref3.readStorage;
return function () {
var _ref4 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(key) {
var trackedChange, value;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
trackedChange = tryGetTracked(key);
if (!(trackedChange != null)) {
_context2.next = 5;
break;
}
if (!(trackedChange.type === 'delete')) {
_context2.next = 4;
break;
}
return _context2.abrupt("return", null);
case 4:
return _context2.abrupt("return", trackedChange.value);
case 5:
_context2.next = 7;
return readStorage.tryGet(key);
case 7:
value = _context2.sent;
return _context2.abrupt("return", value);
case 9:
case "end":
return _context2.stop();
}
}
}, _callee2, this);
}));
return function (_x2) {
return _ref4.apply(this, arguments);
};
}();
}
var BaseReadStorageCache =
/*#__PURE__*/
function () {
function BaseReadStorageCache(options) {
_classCallCheck(this, BaseReadStorageCache);
this._readStorage = options.readStorage;
this._name = options.name;
this._createAddChange = options.createAddChange;
this._createDeleteChange = options.createDeleteChange;
this._onAdd = options.onAdd;
this._values = {};
this.get = createGet({
readStorage: this._readStorage,
tryGetTracked: this._tryGetTracked.bind(this)
});
this.tryGet = createTryGet({
readStorage: this._readStorage,
tryGetTracked: this._tryGetTracked.bind(this)
});
}
_createClass(BaseReadStorageCache, [{
key: "getChangeSet",
value: function getChangeSet() {
var _this = this;
var createDeleteChange = this._createDeleteChange;
return neoBlockchainCore.utils.values(this._values).map(function (value) {
if (value.type === 'delete') {
if (createDeleteChange == null) {
// TODO: Make better
throw new Error('Invalid delete');
}
return {
type: 'delete',
change: createDeleteChange(value.key)
};
}
return {
type: 'add',
change: _this._createAddChange(value.addValue)
};
});
} // eslint-disable-next-line
}, {
key: "_tryGetTracked",
value: function _tryGetTracked(key) {
throw new Error('Not Implemented');
}
}]);
return BaseReadStorageCache;
}();
var ReadStorageCache =
/*#__PURE__*/
function (_BaseReadStorageCache) {
_inherits(ReadStorageCache, _BaseReadStorageCache);
function ReadStorageCache(options) {
var _this2;
_classCallCheck(this, ReadStorageCache);
_this2 = _possibleConstructorReturn(this, (ReadStorageCache.__proto__ || Object.getPrototypeOf(ReadStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this2._getKeyString = options.getKeyString;
return _this2;
}
_createClass(ReadStorageCache, [{
key: "_tryGetTracked",
value: function _tryGetTracked(key) {
return this._values[this._getKeyString(key)];
}
}]);
return ReadStorageCache;
}(BaseReadStorageCache);
var ReadAllStorageCache =
/*#__PURE__*/
function (_ReadStorageCache) {
_inherits(ReadAllStorageCache, _ReadStorageCache);
function ReadAllStorageCache(options) {
var _this3;
_classCallCheck(this, ReadAllStorageCache);
_this3 = _possibleConstructorReturn(this, (ReadAllStorageCache.__proto__ || Object.getPrototypeOf(ReadAllStorageCache)).call(this, {
readStorage: {
get: options.readAllStorage.get,
tryGet: options.readAllStorage.tryGet
},
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this3._readAllStorage = options.readAllStorage;
_this3._getKeyFromValue = options.getKeyFromValue;
_this3.all = rxjs.Observable.concat(rxjs.Observable.defer(function () {
return rxjs.Observable.of.apply(rxjs.Observable, _toConsumableArray(neoBlockchainCore.utils.values(_this3._values).map(function (value) {
return value.type === 'add' ? value.value : null;
}).filter(Boolean)));
}), _this3._readAllStorage.all.concatMap(function (value) {
var trackedChange = _this3._tryGetTracked(_this3._getKeyFromValue(value));
if (trackedChange != null && trackedChange.type === 'delete') {
return rxjs.Observable.of();
}
return rxjs.Observable.of(value);
}));
return _this3;
}
return ReadAllStorageCache;
}(ReadStorageCache);
var ReadGetAllStorageCache =
/*#__PURE__*/
function (_ReadStorageCache2) {
_inherits(ReadGetAllStorageCache, _ReadStorageCache2);
function ReadGetAllStorageCache(options) {
var _this4;
_classCallCheck(this, ReadGetAllStorageCache);
_this4 = _possibleConstructorReturn(this, (ReadGetAllStorageCache.__proto__ || Object.getPrototypeOf(ReadGetAllStorageCache)).call(this, {
readStorage: {
get: options.readGetAllStorage.get,
tryGet: options.readGetAllStorage.tryGet
},
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this4._readGetAllStorage = options.readGetAllStorage;
_this4._getKeyFromValue = options.getKeyFromValue;
_this4._matchesPartialKey = options.matchesPartialKey;
_this4.getAll = function (key) {
var createdValues = neoBlockchainCore.utils.values(_this4._values).map(function (value) {
return value.type === 'add' && _this4._matchesPartialKey(value.value, key) ? value.value : null;
}).filter(Boolean);
return rxjs.Observable.concat(rxjs.Observable.of.apply(rxjs.Observable, _toConsumableArray(createdValues)), _this4._readGetAllStorage.getAll(key).concatMap(function (value) {
var trackedChange = _this4._tryGetTracked(_this4._getKeyFromValue(value));
if (trackedChange != null && trackedChange.type === 'delete') {
return rxjs.Observable.of();
}
return rxjs.Observable.of(value);
}));
};
return _this4;
}
return ReadGetAllStorageCache;
}(ReadStorageCache);
function createAdd(_ref5) {
var cache = _ref5.cache,
getKeyFromValue = _ref5.getKeyFromValue,
getKeyString = _ref5.getKeyString;
return function () {
var _ref6 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee3(value, force) {
var key, currentValue;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
key = getKeyFromValue(value);
if (force) {
_context3.next = 7;
break;
}
_context3.next = 4;
return cache.tryGet(key);
case 4:
currentValue = _context3.sent;
if (!(currentValue != null)) {
_context3.next = 7;
break;
}
throw new Error("Attempted to add an already existing object for key " + "".concat(cache._name, ":").concat(getKeyString(key), "."));
case 7:
if (!(cache._onAdd != null)) {
_context3.next = 10;
break;
}
_context3.next = 10;
return cache._onAdd(value);
case 10:
// eslint-disable-next-line
cache._values[cache._getKeyString(key)] = {
type: 'add',
addValue: value,
value: value
};
case 11:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function (_x3, _x4) {
return _ref6.apply(this, arguments);
};
}();
}
function createUpdate(_ref7) {
var cache = _ref7.cache,
updateFunc = _ref7.update,
getKeyFromValue = _ref7.getKeyFromValue;
return function () {
var _ref8 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee4(value, update) {
var key, updatedValue;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
key = getKeyFromValue(value);
updatedValue = updateFunc(value, update); // eslint-disable-next-line
cache._values[cache._getKeyString(key)] = {
type: 'add',
addValue: updatedValue,
value: updatedValue
};
return _context4.abrupt("return", updatedValue);
case 4:
case "end":
return _context4.stop();
}
}
}, _callee4, this);
}));
return function (_x5, _x6) {
return _ref8.apply(this, arguments);
};
}();
}
function createDelete(_ref9) {
var cache = _ref9.cache;
return function () {
var _ref10 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee5(key) {
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
// eslint-disable-next-line
cache._values[cache._getKeyString(key)] = {
type: 'delete',
key: key
};
case 1:
case "end":
return _context5.stop();
}
}
}, _callee5, this);
}));
return function (_x7) {
return _ref10.apply(this, arguments);
};
}();
}
var ReadAddUpdateDeleteStorageCache =
/*#__PURE__*/
function (_ReadStorageCache3) {
_inherits(ReadAddUpdateDeleteStorageCache, _ReadStorageCache3);
function ReadAddUpdateDeleteStorageCache(options) {
var _this5;
_classCallCheck(this, ReadAddUpdateDeleteStorageCache);
_this5 = _possibleConstructorReturn(this, (ReadAddUpdateDeleteStorageCache.__proto__ || Object.getPrototypeOf(ReadAddUpdateDeleteStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this5.add = createAdd({
cache: _this5,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
_this5.update = createUpdate({
cache: _this5,
update: options.update,
getKeyFromValue: options.getKeyFromValue
});
_this5.delete = createDelete({
cache: _this5
});
return _this5;
}
return ReadAddUpdateDeleteStorageCache;
}(ReadStorageCache);
var ReadAddUpdateStorageCache =
/*#__PURE__*/
function (_ReadStorageCache4) {
_inherits(ReadAddUpdateStorageCache, _ReadStorageCache4);
function ReadAddUpdateStorageCache(options) {
var _this6;
_classCallCheck(this, ReadAddUpdateStorageCache);
_this6 = _possibleConstructorReturn(this, (ReadAddUpdateStorageCache.__proto__ || Object.getPrototypeOf(ReadAddUpdateStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this6.add = createAdd({
cache: _this6,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
_this6.update = createUpdate({
cache: _this6,
update: options.update,
getKeyFromValue: options.getKeyFromValue
});
return _this6;
}
return ReadAddUpdateStorageCache;
}(ReadStorageCache);
var ReadAddDeleteStorageCache =
/*#__PURE__*/
function (_ReadStorageCache5) {
_inherits(ReadAddDeleteStorageCache, _ReadStorageCache5);
function ReadAddDeleteStorageCache(options) {
var _this7;
_classCallCheck(this, ReadAddDeleteStorageCache);
_this7 = _possibleConstructorReturn(this, (ReadAddDeleteStorageCache.__proto__ || Object.getPrototypeOf(ReadAddDeleteStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this7.add = createAdd({
cache: _this7,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
_this7.delete = createDelete({
cache: _this7
});
return _this7;
}
return ReadAddDeleteStorageCache;
}(ReadStorageCache);
var ReadAddStorageCache =
/*#__PURE__*/
function (_ReadStorageCache6) {
_inherits(ReadAddStorageCache, _ReadStorageCache6);
function ReadAddStorageCache(options) {
var _this8;
_classCallCheck(this, ReadAddStorageCache);
_this8 = _possibleConstructorReturn(this, (ReadAddStorageCache.__proto__ || Object.getPrototypeOf(ReadAddStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd
}));
_this8.add = createAdd({
cache: _this8,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
return _this8;
}
return ReadAddStorageCache;
}(ReadStorageCache);
var ReadGetAllAddUpdateDeleteStorageCache =
/*#__PURE__*/
function (_ReadGetAllStorageCac) {
_inherits(ReadGetAllAddUpdateDeleteStorageCache, _ReadGetAllStorageCac);
function ReadGetAllAddUpdateDeleteStorageCache(options) {
var _this9;
_classCallCheck(this, ReadGetAllAddUpdateDeleteStorageCache);
_this9 = _possibleConstructorReturn(this, (ReadGetAllAddUpdateDeleteStorageCache.__proto__ || Object.getPrototypeOf(ReadGetAllAddUpdateDeleteStorageCache)).call(this, {
readGetAllStorage: options.readGetAllStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd,
getKeyFromValue: options.getKeyFromValue,
matchesPartialKey: options.matchesPartialKey
}));
_this9.add = createAdd({
cache: _this9,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
_this9.update = createUpdate({
cache: _this9,
update: options.update,
getKeyFromValue: options.getKeyFromValue
});
_this9.delete = createDelete({
cache: _this9
});
return _this9;
}
return ReadGetAllAddUpdateDeleteStorageCache;
}(ReadGetAllStorageCache);
var ReadGetAllAddStorageCache =
/*#__PURE__*/
function (_ReadGetAllStorageCac2) {
_inherits(ReadGetAllAddStorageCache, _ReadGetAllStorageCac2);
function ReadGetAllAddStorageCache(options) {
var _this10;
_classCallCheck(this, ReadGetAllAddStorageCache);
_this10 = _possibleConstructorReturn(this, (ReadGetAllAddStorageCache.__proto__ || Object.getPrototypeOf(ReadGetAllAddStorageCache)).call(this, {
readGetAllStorage: options.readGetAllStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd,
getKeyFromValue: options.getKeyFromValue,
matchesPartialKey: options.matchesPartialKey
}));
_this10.add = createAdd({
cache: _this10,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
return _this10;
}
return ReadGetAllAddStorageCache;
}(ReadGetAllStorageCache);
var ReadAllAddUpdateDeleteStorageCache =
/*#__PURE__*/
function (_ReadAllStorageCache) {
_inherits(ReadAllAddUpdateDeleteStorageCache, _ReadAllStorageCache);
function ReadAllAddUpdateDeleteStorageCache(options) {
var _this11;
_classCallCheck(this, ReadAllAddUpdateDeleteStorageCache);
_this11 = _possibleConstructorReturn(this, (ReadAllAddUpdateDeleteStorageCache.__proto__ || Object.getPrototypeOf(ReadAllAddUpdateDeleteStorageCache)).call(this, {
readAllStorage: options.readAllStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd,
getKeyFromValue: options.getKeyFromValue
}));
_this11.add = createAdd({
cache: _this11,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
_this11.update = createUpdate({
cache: _this11,
update: options.update,
getKeyFromValue: options.getKeyFromValue
});
_this11.delete = createDelete({
cache: _this11
});
return _this11;
}
return ReadAllAddUpdateDeleteStorageCache;
}(ReadAllStorageCache);
var ReadAllAddStorageCache =
/*#__PURE__*/
function (_ReadAllStorageCache2) {
_inherits(ReadAllAddStorageCache, _ReadAllStorageCache2);
function ReadAllAddStorageCache(options) {
var _this12;
_classCallCheck(this, ReadAllAddStorageCache);
_this12 = _possibleConstructorReturn(this, (ReadAllAddStorageCache.__proto__ || Object.getPrototypeOf(ReadAllAddStorageCache)).call(this, {
readAllStorage: options.readAllStorage,
name: options.name,
getKeyString: options.getKeyString,
createAddChange: options.createAddChange,
createDeleteChange: options.createDeleteChange,
onAdd: options.onAdd,
getKeyFromValue: options.getKeyFromValue
}));
_this12.add = createAdd({
cache: _this12,
getKeyFromValue: options.getKeyFromValue,
getKeyString: options.getKeyString
});
return _this12;
}
return ReadAllAddStorageCache;
}(ReadAllStorageCache);
var BlockLikeStorageCache =
/*#__PURE__*/
function (_BaseReadStorageCache2) {
_inherits(BlockLikeStorageCache, _BaseReadStorageCache2);
function BlockLikeStorageCache(options) {
var _this13;
_classCallCheck(this, BlockLikeStorageCache);
_this13 = _possibleConstructorReturn(this, (BlockLikeStorageCache.__proto__ || Object.getPrototypeOf(BlockLikeStorageCache)).call(this, {
readStorage: options.readStorage,
name: options.name,
createAddChange: options.createAddChange
}));
_this13._indexValues = {};
return _this13;
}
_createClass(BlockLikeStorageCache, [{
key: "add",
value: function () {
var _ref11 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee6(value, force) {
var currentValue, addValue;
return regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
if (force) {
_context6.next = 6;
break;
}
_context6.next = 3;
return this.tryGet({
hashOrIndex: value.index
});
case 3:
currentValue = _context6.sent;
if (!(currentValue != null)) {
_context6.next = 6;
break;
}
throw new Error('Attempted to add an already existing object.');
case 6:
addValue = {
type: 'add',
addValue: value,
value: value
};
this._values[neoBlockchainCore.common.uInt256ToString(value.hash)] = addValue;
this._indexValues["".concat(value.index)] = addValue;
case 9:
case "end":
return _context6.stop();
}
}
}, _callee6, this);
}));
function add(_x8, _x9) {
return _ref11.apply(this, arguments);
}
return add;
}()
}, {
key: "_tryGetTracked",
value: function _tryGetTracked(key) {
if (typeof key.hashOrIndex !== 'number') {
return this._values[neoBlockchainCore.common.uInt256ToString(key.hashOrIndex)];
}
return this._indexValues["".concat(key.hashOrIndex)];
}
}]);
return BlockLikeStorageCache;
}(BaseReadStorageCache);
var getOutputValueKeyString = function getOutputValueKeyString(key) {
return "".concat(neoBlockchainCore.common.uInt256ToHex(key.hash), ":").concat(key.index);
};
var OutputStorageCache =
/*#__PURE__*/
function (_ReadStorageCache7) {
_inherits(OutputStorageCache, _ReadStorageCache7);
function OutputStorageCache(readStorage) {
var _this14;
_classCallCheck(this, OutputStorageCache);
_this14 = _possibleConstructorReturn(this, (OutputStorageCache.__proto__ || Object.getPrototypeOf(OutputStorageCache)).call(this, {
readStorage: readStorage,
name: 'output',
getKeyString: getOutputValueKeyString,
createAddChange: function createAddChange(value) {
return {
type: 'output',
value: value
};
}
}));
_this14.add = function () {
var _ref12 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee7(value, force) {
var key, currentValue;
return regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
key = {
hash: value.hash,
index: value.index
};
if (force) {
_context7.next = 7;
break;
}
_context7.next = 4;
return _this14.tryGet(key);
case 4:
currentValue = _context7.sent;
if (!(currentValue != null)) {
_context7.next = 7;
break;
}
throw new Error("Attempted to add an already existing object for key " + "".concat(_this14._name, ":").concat(_this14._getKeyString(key), "."));
case 7:
// eslint-disable-next-line
_this14._values[_this14._getKeyString(key)] = {
type: 'add',
addValue: value,
value: value.output
};
case 8:
case "end":
return _context7.stop();
}
}
}, _callee7, this);
}));
return function (_x10, _x11) {
return _ref12.apply(this, arguments);
};
}();
return _this14;
}
return OutputStorageCache;
}(ReadStorageCache);
var WriteBatchBlockchain =
/*#__PURE__*/
function () {
function WriteBatchBlockchain(options) {
_classCallCheck(this, WriteBatchBlockchain);
this.settings = options.settings;
this._currentBlock = options.currentBlock;
this._currentHeader = options.currentHeader;
this._storage = options.storage;
this._vm = options.vm;
this._onStep = options.onStep;
var output = new OutputStorageCache(this._storage.output);
this._caches = {
account: new ReadAllAddUpdateDeleteStorageCache({
name: 'account',
readAllStorage: this._storage.account,
update: function update(value, _update) {
return value.update(_update);
},
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt160ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'account',
value: value
};
},
createDeleteChange: function createDeleteChange(key) {
return {
type: 'account',
key: key
};
}
}),
action: new ReadGetAllAddStorageCache({
name: 'action',
readGetAllStorage: this._storage.action,
getKeyFromValue: function getKeyFromValue(value) {
return {
blockIndex: value.blockIndex,
transactionIndex: value.transactionIndex,
index: value.index
};
},
getKeyString: function getKeyString(key) {
return "".concat(key.blockIndex, ":").concat(key.transactionIndex, ":").concat(key.index);
},
// eslint-disable-next-line
matchesPartialKey: function matchesPartialKey(value, key) {
// TODO: Implement me
throw new Error('Not implemented');
},
createAddChange: function createAddChange(value) {
return {
type: 'action',
value: value
};
}
}),
asset: new ReadAddUpdateStorageCache({
name: 'asset',
readStorage: this._storage.asset,
update: function update(value, _update2) {
return value.update(_update2);
},
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt256ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'asset',
value: value
};
}
}),
block: new BlockLikeStorageCache({
name: 'block',
readStorage: {
get: this._storage.block.get,
tryGet: this._storage.block.tryGet
},
createAddChange: function createAddChange(value) {
return {
type: 'block',
value: value
};
}
}),
blockSystemFee: new ReadAddStorageCache({
name: 'blockSystemFee',
readStorage: this._storage.blockSystemFee,
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt256ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'blockSystemFee',
value: value
};
}
}),
header: new BlockLikeStorageCache({
name: 'header',
readStorage: {
get: this._storage.header.get,
tryGet: this._storage.header.tryGet
},
createAddChange: function createAddChange(value) {
return {
type: 'header',
value: value
};
}
}),
transaction: new ReadAddStorageCache({
name: 'transaction',
readStorage: this._storage.transaction,
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt256ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'transaction',
value: value
};
},
onAdd: function () {
var _ref = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee(value) {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return Promise.all(value.outputs.map(function (out, index) {
return output.add({
hash: value.hash,
index: index,
output: out
});
}));
case 2:
case "end":
return _context.stop();
}
}
}, _callee, this);
}));
function onAdd(_x) {
return _ref.apply(this, arguments);
}
return onAdd;
}()
}),
transactionSpentCoins: new ReadAddUpdateStorageCache({
name: 'transactionSpentCoins',
readStorage: this._storage.transactionSpentCoins,
update: function update(value, _update3) {
return value.update(_update3);
},
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt256ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'transactionSpentCoins',
value: value
};
}
}),
output: output,
contract: new ReadAddDeleteStorageCache({
name: 'contract',
readStorage: this._storage.contract,
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt160ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'contract',
value: value
};
},
createDeleteChange: function createDeleteChange(key) {
return {
type: 'contract',
key: key
};
}
}),
storageItem: new ReadGetAllAddUpdateDeleteStorageCache({
name: 'storageItem',
readGetAllStorage: this._storage.storageItem,
update: function update(value, _update4) {
return value.update(_update4);
},
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash,
key: value.key
};
},
getKeyString: function getKeyString(key) {
return "".concat(neoBlockchainCore.common.uInt160ToString(key.hash), ":").concat(key.key.toString('hex'));
},
matchesPartialKey: function matchesPartialKey(value, key) {
return key.hash == null || neoBlockchainCore.common.uInt160Equal(value.hash, key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'storageItem',
value: value
};
},
createDeleteChange: function createDeleteChange(key) {
return {
type: 'storageItem',
key: key
};
}
}),
validator: new ReadAllAddStorageCache({
name: 'validator',
readAllStorage: this._storage.validator,
getKeyFromValue: function getKeyFromValue(value) {
return {
publicKey: value.publicKey
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.ecPointToString(key.publicKey);
},
createAddChange: function createAddChange(value) {
return {
type: 'validator',
value: value
};
}
}),
invocationData: new ReadAddStorageCache({
name: 'invocationData',
readStorage: this._storage.invocationData,
getKeyFromValue: function getKeyFromValue(value) {
return {
hash: value.hash
};
},
getKeyString: function getKeyString(key) {
return neoBlockchainCore.common.uInt256ToString(key.hash);
},
createAddChange: function createAddChange(value) {
return {
type: 'invocationData',
value: value
};
}
})
};
this.account = this._caches.account;
this.action = this._caches.action;
this.asset = this._caches.asset;
this.block = this._caches.block;
this.blockSystemFee = this._caches.blockSystemFee;
this.header = this._caches.header;
this.transaction = this._caches.transaction;
this.transactionSpentCoins = this._caches.transactionSpentCoins;
this.output = this._caches.output;
this.contract = this._caches.contract;
this.storageItem = this._caches.storageItem;
this.validator = this._caches.validator;
this.invocationData = this._caches.invocationData;
}
_createClass(WriteBatchBlockchain, [{
key: "getChangeSet",
value: function getChangeSet() {
return this.account.getChangeSet().concat(this.asset.getChangeSet()).concat(this.action.getChangeSet()).concat(this.block.getChangeSet()).concat(this.blockSystemFee.getChangeSet()).concat(this.header.getChangeSet()).concat(this.transaction.getChangeSet()).concat(this.output.getChangeSet()).concat(this.transactionSpentCoins.getChangeSet()).concat(this.contract.getChangeSet()).concat(this.storageItem.getChangeSet()).concat(this.validator.getChangeSet()).concat(this.invocationData.getChangeSet());
}
}, {
key: "persistBlock",
value: function () {
var _ref2 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee2(block) {
var _ref3, _ref4, systemFee, _$$1, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _ref7, _ref6, _idx, _transaction2;
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return Promise.all([block.index === 0 ? Promise.resolve(neoBlockchainCore.utils.ZERO) : this.blockSystemFee.get({
hash: block.previousHash
}).then(function (blockSystemFee) {
return blockSystemFee.systemFee;
}), this.block.add(block), this.header.add(block.header)]);
case 2:
_ref3 = _context2.sent;
_ref4 = _slicedToArray(_ref3, 2);
systemFee = _ref4[0];
_$$1 = _ref4[1];
_context2.next = 8;
return this.blockSystemFee.add(new neoBlockchainNodeCore.BlockSystemFee({
hash: block.hash,
systemFee: systemFee.add(block.getSystemFee({
getOutput: this.output.get,
governingToken: this.settings.governingToken,
utilityToken: this.settings.utilityToken,
fees: this.settings.fees
}))
}));
case 8:
_iteratorNormalCompletion = true;
_didIteratorError = false;
_iteratorError = undefined;
_context2.prev = 11;
_iterator = block.transactions.entries()[Symbol.iterator]();
case 13:
if (_iteratorNormalCompletion = (_step = _iterator.next()).done) {
_context2.next = 23;
break;
}
_ref7 = _step.value;
_ref6 = _slicedToArray(_ref7, 2);
_idx = _ref6[0];
_transaction2 = _ref6[1];
_context2.next = 20;
return this._persistTransaction(block, _transaction2, _idx);
case 20:
_iteratorNormalCompletion = true;
_context2.next = 13;
break;
case 23:
_context2.next = 29;
break;
case 25:
_context2.prev = 25;
_context2.t0 = _context2["catch"](11);
_didIteratorError = true;
_iteratorError = _context2.t0;
case 29:
_context2.prev = 29;
_context2.prev = 30;
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
case 32:
_context2.prev = 32;
if (!_didIteratorError) {
_context2.next = 35;
break;
}
throw _iteratorError;
case 35:
return _context2.finish(32);
case 36:
return _context2.finish(29);
case 37:
case "end":
return _context2.stop();
}
}
}, _callee2, this, [[11, 25, 29, 37], [30,, 32, 36]]);
}));
function persistBlock(_x2) {
return _ref2.apply(this, arguments);
}
return persistBlock;
}()
}, {
key: "_persistTransaction",
value: function () {
var _ref8 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee5(block, transaction, transactionIndex) {
var _this = this;
var results, _contract, temporaryBlockchain, result, assetChangeSet, assetHash, contractsChangeSet, contractHashes;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
_context5.next = 2;
return Promise.all([this.transaction.add(transaction), this.transactionSpentCoins.add(new neoBlockchainNodeCore.TransactionSpentCoins({
hash: transaction.hash,
startHeight: block.index
})), this._updateAccounts(transaction.inputs, transaction.outputs), this._updateCoins(transaction.inputs, transaction.type === neoBlockchainCore.TRANSACTION_TYPE.CLAIM && transaction instanceof neoBlockchainCore.ClaimTransaction ? transaction.claims : [], block)]);
case 2:
if (!(transaction.type === neoBlockchainCore.TRANSACTION_TYPE.REGISTER && transaction instanceof neoBlockchainCore.RegisterTransaction)) {
_context5.next = 7;
break;
}
_context5.next = 5;
return this.asset.add(new neoBlockchainCore.Asset({
hash: transaction.hash,
type: transaction.asset.type,
name: transaction.asset.name,
amount: transaction.asset.amount,
precision: transaction.asset.precision,
owner: transaction.asset.owner,
admin: transaction.asset.admin,
issuer: transaction.asset.admin,
expiration: this.currentBlockIndex + 2 * 2000000,
isFrozen: false
}));
case 5:
_context5.next = 47;
break;
case 7:
if (!(transaction.type === neoBlockchainCore.TRANSACTION_TYPE.ISSUE && transaction instanceof neoBlockchainCore.IssueTransaction)) {
_context5.next = 15;
break;
}
_context5.next = 10;
return neoBlockchainCore.utils.entries(transaction.getTransactionResults({
getOutput: this.output.get
}));
case 10:
results = _context5.sent;
_context5.next = 13;
return Promise.all(results.map(function () {
var _ref10 = _asyncToGenerator(
/*#__PURE__*/
regeneratorRuntime.mark(function _callee3(_ref9) {
var _ref11, assetHex, value, hash, asset;
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_ref11 = _slicedToArray(_ref9, 2), assetHex = _ref11[0], value = _ref11[1];
hash = neoBlockchainCore.common.stringToUInt256(assetHex);
_context3.next = 4;
return _this.asset.get({
hash: hash
});
case 4:
asset = _context3.sent;
_context3.next = 7;
return _this.asset.update(asset, {
available: asset.available.add(value.neg())
});
case 7:
case "end":
return _context3.stop();
}
}
}, _callee3, this);
}));
return function (_x6) {
return _ref10.apply(this, arguments);
};
}()));
case 13:
_context5.next = 47;
break;
case 15:
if (!(transaction.type === neoBlockchainCore.TRANSACTION_TYPE.ENROLLMENT && transaction instanceof neoBlockchainCore.EnrollmentTransaction)) {
_context5.next = 20;
break;
}
_context5.next = 18;