itns-sidechain/lib/script/sigcache.js

158 lines
2.9 KiB
JavaScript
Raw Normal View History

2016-07-02 07:09:22 -07:00
/*!
* sigcache.js - signature cache for bcoin
2017-02-03 22:47:26 -08:00
* Copyright (c) 2014-2017, Christopher Jeffrey (MIT License).
2016-07-02 07:09:22 -07:00
* https://github.com/bcoin-org/bcoin
*/
'use strict';
2017-01-06 10:18:21 -08:00
var assert = require('assert');
2016-11-19 10:45:31 -08:00
var util = require('../utils/util');
2016-10-02 01:01:16 -07:00
var ec = require('../crypto/ec');
2016-07-02 07:09:22 -07:00
/**
* Signature cache.
2017-02-03 22:47:26 -08:00
* @alias module:script.SigCache
2016-07-02 07:09:22 -07:00
* @constructor
* @param {Number} [size=50000]
* @property {Number} size
* @property {Hash[]} keys
* @property {Object} valid
*/
function SigCache(size) {
if (!(this instanceof SigCache))
return new SigCache(size);
if (size == null)
size = 10000;
2016-11-19 10:45:31 -08:00
assert(util.isNumber(size));
2016-07-02 07:09:22 -07:00
assert(size >= 0);
this.size = size;
this.keys = [];
this.valid = {};
}
2016-07-29 15:40:39 -07:00
/**
* Resize the sigcache.
* @param {Number} size
*/
SigCache.prototype.resize = function resize(size) {
2016-11-19 10:45:31 -08:00
assert(util.isNumber(size));
2016-07-29 15:40:39 -07:00
assert(size >= 0);
this.size = size;
this.keys.length = 0;
this.valid = {};
};
2016-07-02 07:09:22 -07:00
/**
* Add item to the sigcache.
* Potentially evict a random member.
* @param {Hash} hash - Sig hash.
* @param {Buffer} sig
* @param {Buffer} key
*/
SigCache.prototype.add = function add(hash, sig, key) {
2016-07-02 17:36:39 -07:00
var i, k;
2016-07-02 07:09:22 -07:00
if (this.size === 0)
return;
this.valid[hash] = new SigCacheEntry(sig, key);
2016-07-04 05:36:06 -07:00
if (this.keys.length >= this.size) {
2016-07-02 17:36:39 -07:00
i = Math.floor(Math.random() * this.keys.length);
k = this.keys[i];
delete this.valid[k];
this.keys[i] = hash;
2016-07-02 07:09:22 -07:00
} else {
this.keys.push(hash);
}
};
/**
* Test whether the sig exists.
* @param {Hash} hash - Sig hash.
* @param {Buffer} sig
* @param {Buffer} key
* @returns {Boolean}
*/
SigCache.prototype.has = function has(hash, sig, key) {
var entry = this.valid[hash];
if (!entry)
return false;
return entry.equal(sig, key);
};
/**
* Verify a signature, testing
* it against the cache first.
* @param {Buffer} msg
* @param {Buffer} sig
* @param {Buffer} key
* @param {Boolean?} historical
* @param {Boolean?} high
* @returns {Boolean}
*/
SigCache.prototype.verify = function verify(msg, sig, key, historical, high) {
var hash, result;
if (historical || this.size === 0)
2016-10-02 01:01:16 -07:00
return ec.verify(msg, sig, key, historical, high);
2016-07-02 07:09:22 -07:00
hash = msg.toString('hex');
if (this.has(hash, sig, key))
return true;
2016-10-02 01:01:16 -07:00
result = ec.verify(msg, sig, key, historical, high);
2016-07-02 07:09:22 -07:00
if (!result)
return false;
this.add(hash, sig, key);
return true;
};
/**
* Signature cache entry.
* @constructor
2017-02-03 22:47:26 -08:00
* @ignore
2016-07-02 07:09:22 -07:00
* @param {Buffer} sig
* @param {Buffer} key
* @property {Buffer} sig
* @property {Buffer} key
*/
function SigCacheEntry(sig, key) {
this.sig = sig;
this.key = key;
}
/**
* Compare an entry to a sig and key.
* @param {Buffer} sig
* @param {Buffer} key
* @returns {Boolean}
*/
SigCacheEntry.prototype.equal = function equal(sig, key) {
2016-11-19 10:45:31 -08:00
return util.equal(this.sig, sig) && util.equal(this.key, key);
2016-07-02 07:09:22 -07:00
};
/*
* Expose
*/
module.exports = new SigCache(+process.env.BCOIN_SIGCACHE_SIZE || 0);