gamegold 5.4.3 → 5.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/gamegold-worker.js +2 -2
- package/lib/gamegold.js +3 -3
- package/package.json +1 -1
package/lib/gamegold-worker.js
CHANGED
|
@@ -196,7 +196,7 @@ var r=i(126),a=r.Buffer;function s(e,t){for(var i in e)t[i]=e[i]}function n(e,t,
|
|
|
196
196
|
* pkg.js - package constants
|
|
197
197
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
198
198
|
* https://github.com/bookmansoft/gamegold
|
|
199
|
-
*/t.protocol="vallnet",t.version="5.4.
|
|
199
|
+
*/t.protocol="vallnet",t.version="5.4.4",t.url="https://github.com/bookmansoft/gamegold"},function(e,t,i){"use strict";
|
|
200
200
|
/*!
|
|
201
201
|
* common.js - p2p constants for vallnet
|
|
202
202
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
@@ -830,7 +830,7 @@ const r=i(5).ContractType;e.exports=function(e){if(!e)return i(188);switch(e.ope
|
|
|
830
830
|
/*!
|
|
831
831
|
* accountdb.js - storage for account management
|
|
832
832
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
833
|
-
*/const r=i(8),a=i(0),s=i(73),n=i(119),o=i(157),c=i(610),u=i(85),h=u.walletdb,l=i(6),p=i(158),d=i(125),f=i(167);var{}=i(32);const m=i(45),g=i(13);i(20),i(69);const v=i(197),y=i(68),b=i(50),{BlockFinalType:w,ContractEnvType:x}=i(5),k=i(159),S=i(612),_=i(37);var E=i(72);const j=i(2),A=i(141).sortWithSeq,R=i(35),I=i(198),O=i(64),C=i(100),P=i(3),T=P.U32,B=i(338),N=i(339),z=i(340),F=z.vpItem,L=i(617),M=L.vpItem,D=i(312);i(618);const H=D.cpItem,U=i(154),q=U.ErAbolishItem,V=i(38).broadcast,K=i(132),W=K.vpItem,$=i(153),Y=$.ErItem,G=i(619),X=G.AuditItem,J=i(305),Q=i(109),Z=i(620),ee=i(306),te=i(120),ie=i(621),re=i(217),ae=i(39),se=i(36),ne=i(59),oe=i(78),ce=oe.errors,ue=i(77);class he extends E{constructor(e){super(),this.readyLoad=!1,this.options=new c(e),this.network=this.options.network,this.logger=this.options.logger.context("wallet"),this.workers=this.options.workers,this.keys={hmacSalt:P.DefaultChainCode},e.keys&&e.keys.hmacSalt&&(a(Buffer.isBuffer(e.keys.hmacSalt)),this.keys.hmacSalt=e.keys.hmacSalt),this.client=this.options.client,this.client&&(this.client.wdb=this),this.jsonp=this.options.jsonp,this.jsonp&&(this.jsonp.wdb=this),this.spv=this.options.spv,this.feeRate=this.options.feeRate,this.db=f(this.options),this.rpc=new B(this),this.primary=null,this.state=new Z,this.wallets=new Map,this.depth=0,this.rescanning=!1,this.bound=!1,this.newRecord=!0,this.readLock=new I,this.writeLock=new R,this.txLock=new R,this.scanLock=new R,this.widCache=new O(1e4),this.pathMapCache=new O(1e5),this.filter=new C,this.middleHashMem=new Set,this.middleHashChain=new Set,this.autoTaskMgr=new k(this),this.transactionList=new N(this),this.htlcList=new z(this),this.commentList=new L(this),this.NotifyList=new _,this.propList=new K(this),this.$contacts=new _,this.cpList=new D(this),this.cpMemList=new D(this),this.auditList=new G(this),this.erList=new $(this),this.erAbList=new U(this),this.hmacConnection=[],this._init()}async logAudit(e){e.height=this.curHeight,e.time=j.now(),e.erid=l.sha256(j.stringify(e)).toString("hex"),e=new X(e),await this.auditList.setAudit(e)}async getAccountByAddress(e,t){if(e){let a=null;if(a=t?await this.getWalletsByTX(t):await this.getWallets())for(const t of a){var i=await this.get(t);if(i){var r=await i.getPath(e);if(r)return[i.wid,r.name,i.id]}}}return[0,"",""]}_init(){let e=1e6,t=-1;this.spv&&(e=2e4,t=C.flags.ALL),this.filter=C.fromRate(e,.001,t)}get mode(){return x.Wallet}async getTXFromAll(e){return this.getTXFromDb(e)}async checkNewRecord(){var e={createIfMissing:this.db.options.createIfMissing,errorIfExists:this.db.options.errorIfExists};this.db.options.createIfMissing=!1,this.db.options.errorIfExists=!0;try{await this.db.open();var t=await this.db.checkVersion(h,6);this.newRecord="new"==t}catch(e){if(-1!=e.message.indexOf("does not exist (create_if_missing is false)"))this.newRecord=!0;else{if(-1==e.message.indexOf("exists (error_if_exists is true)"))throw e;this.newRecord=!1}}try{await this.db.close()}catch(e){}this.db.options.createIfMissing=e.createIfMissing,this.db.options.errorIfExists=e.errorIfExists}async isNewRecord(){return await this.checkNewRecord(),this.newRecord}setmnemonic(e){if(this.options.mnemonic=this.options.mnemonic||{},e.bits)this.options.mnemonic={bits:e.bits};else if(e.entropy)this.options.mnemonic={entropy:Buffer.from(e.entropy,"hex")};else if(e.phrase){var t=this.testmnemonic(e.phrase);if(0!=t.code)throw t.msg;this.options.mnemonic={phrase:e.phrase}}e.passphrase&&(this.options.mnemonic.passphrase=e.passphrase),e.language&&(this.options.mnemonic.language=e.language)}testmnemonic(e){try{return new v(e),{code:0}}catch(e){return{code:-1,msg:e.message}}}async getContracts(e){var t=await this.db.values({gte:u.txdb.tx(P.NULL_HASH),lte:u.txdb.tx(P.HIGH_HASH),parse:e=>j.parseJson(e.toString())});return e?t.filter(t=>t.srcact==e||t.dstact==e):t}isFull(){return this.spv||this.synced||!1}async _open(e){}async handleNotify(e,t=!1){if(!t){let i=e.body.content;if("string"==typeof i)try{i=JSON.parse(e.body.content)}catch(e){return}"object"==typeof i&&"secret"===i.type&&(t={contact:e.body.src,messenger:e.body.dst},i.init&&(t.init=Buffer.from(i.init,"hex")),i.packet&&(t.packet=Buffer.from(i.packet)),await this.handleSecret(t))}}async handleSecret(e){if(e.contact&&e.messenger&&e.contact!=e.messenger){try{g.fromString(e.contact,this.network.type),g.fromString(e.messenger,this.network.type)}catch(e){return}var t=await this.ensureContact(e);t&&await t.ensureMessenger(e).answer(e)}}async scanContact(e,t=-1){var i=async e=>{var t;e.witness&&"witnesspubkeyhash"==e.getType()&&(t=e.witness.getPubkeyhashInput()[1],e=g.fromWitness(e.witness).toString(),t)&&e&&await this.ensureContact({contact:e,publicKey:t})};if(0<=t&&t<e.inputs.length)await i(e.inputs[t]);else for(var r of e.inputs)await i(r)}async ensureContact(e){if(!e.contact||e.contact==e.messenger)return null;try{g.fromString(e.contact,this.network.type),e.messenger&&g.fromString(e.messenger,this.network.type)}catch(e){return null}e.network=this.network.type,this.$contacts.get(e.contact)||this.$contacts.set(e.contact,new S(e));var t=this.$contacts.get(e.contact);if(e.messenger&&!(e=t.ensureMessenger(e)).wallet){var i,[i,r]=await this.getAccountByAddress(e.address);if(!(i=await this.get(i)))return;e.wallet=i,e.account=r}return t}getCps(){return this.db.values({gte:u.txdb.cp(P.ZERO_CID,"hex"),lte:u.txdb.cp(P.MAX_CID,"hex"),parse:e=>H.fromRaw(e)})}async _close(){await this.disconnect(),this.http&&this.options.listen&&await this.http.close();for(const e of this.wallets.values())await e.destroy();await this.db.close(),this.options.listen&&await this.logger.close()}async destroy(){await this.db.destroy(),this.widCache.reset(),this.pathMapCache.reset()}async load(e){if(this.readyLoad){var t=await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),i=await this.txLock.lock();try{await this.init(e),await this.watch(),await t.createReceive(0,1,t.master,this.network.type),await t.ensureNotifyKey(),await this.sync()}finally{i()}setTimeout(()=>{this.resend()},5e3)}}async disconnect(){this.client&&await this.client._close(),this.jsonp&&await this.jsonp._close()}async flushCP(e,t=!1){this.client&&(e=e||[],t||(e=this.cpList.excludeCids(e),t=t||0<e.length),t)&&await this.client.execute("cp.remoteQuery",[[["cid","include",e]]])}async watch(){let e=this.db.iterator({gte:h.p(P.NULL_HASH),lte:h.p(P.HIGH_HASH)}),t=0,i=0;for(;;){var r=await e.next();if(!r)break;try{var a=h.pp(r.key);this.addHash(a,!1)}catch(t){throw await e.end(),t}t++}for(e=this.db.iterator({gte:h.o(P.NULL_HASH,0),lte:h.o(P.HIGH_HASH,4294967295)});;){var s=await e.next();if(!s)break;try{var[n,o]=h.oo(s.key);this.addOutpoint(n,o)}catch(t){throw await e.end(),t}i++}this.logger.info("Filter: Added %d hashes to AccountDB filter.",t),this.logger.info("Filter: Added %d outpoints to AccountDB filter.",i),await this.setFilter()}async sync(){if(this.client){let t,i=this.curHeight;for(;0<=i;){var e=await this.getBlock(i);if(!e)break;if(t=await this.client.getEntry(e.hash))break;i--}t||(i=this.state.startHeight,t=await this.client.getEntry(this.state.startHash))||(i=0),await this.cpList.loadHistory(),await this.cpMemList.loadHistory(),await this.propList.loadHistory(),await this.htlcList.loadHistory(),await this.commentList.loadHistory(),await this.transactionList.loadHistory(),await this.loadContact(),await this.erList.loadHistory(),await this.auditList.loadHistory(),await this.erAbList.loadHistory(),await this._rescan(i,!1)}}async _rescan(e,t=!0){if(this.client){null==e&&(e=this.state.startHeight),a(e>>>0===e,"WDB: Must pass in a height.");var i=this.curHeight;t=(await this.rollback(e,t),this.logger.info("AccountDB is scanning %d blocks.",i-e+1),await this.getTip());try{this.rescanning=!0,await this.client.rescan(t.hash,this.eid)}finally{this.rescanning=!1}}}async rescan(e){var t=await this.txLock.lock();try{return await this._rescan(e,!1)}finally{t()}}async send(e){return this.client?this.client.send(e):(this.emit("send",e),Promise.resolve())}async getTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getTXFromDb(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getExtendTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t}return null}async removeTX(e){this.client?await this.client.removeTX(e):this.emit("remove",e)}async estimateFee(e){return 0<this.feeRate?this.feeRate:!this.client||(e=await this.client.estimateFee(e))<this.network.feeRate?this.network.feeRate:e>this.network.maxFeeRate?this.network.maxFeeRate:e}setFilter(){return this.client?this.client.setFilter(this.filter):(this.emit("filter.set",this.filter),Promise.resolve())}resetFilter(){return this.client?this.client.resetFilter():(this.emit("filter.reset"),Promise.resolve())}backup(e){return this.db.backup(e)}async wipe(){this.logger.warning("Wiping AccountDB TXDB..."),this.logger.warning("I hope you know what you're doing.");var e=this.db.iterator({gte:Buffer.from([0]),lte:Buffer.from([255])}),t=this.db.batch();let i=0;for(;;){var r=await e.next();if(!r)break;try{switch(r.key[0]){case 98:case 99:case 101:case 116:case 111:case 104:case 82:t.del(r.key),i++}}catch(t){throw await e.end(),t}}this.logger.warning("Wiped %d txdb records.",i),await t.write()}async getDepth(){var e=this.db.iterator({gte:h.w(0),lte:h.w(4294967295),reverse:!0,limit:1}),t=await e.next();return t?(await e.end(),h.ww(t.key)+1):1}start(e){return a(!e.current,"WDB: Batch already started."),e.current=this.db.batch(),e.accountCache.start(),e.pathCache.start(),e.current}drop(e){var t=this.batch(e);e.current=null,e.accountCache.drop(),e.pathCache.drop(),t.clear()}clear(e){var t=this.batch(e);e.accountCache.clear(),e.pathCache.clear(),t.clear()}batch(e){return a(e.current,"WDB: Batch does not exist."),e.current}async commit(e){var t=this.batch(e);try{await t.write()}catch(e){throw this.drop(),e}e.current=null,e.accountCache.commit(),e.pathCache.commit()}testFilter(e){return this.filter.test(e,"hex")}addHash(e,t=!0){this.filter.add(e,"hex"),t&&(t=Buffer.from(e,"hex"),this.client?this.client.addFilter(t):this.emit("filter.add",t))}addOutpoint(e,t){e=new m(e,t),this.filter.add(e.toRaw())}dump(){return this.db.dump()}register(e){a(!this.wallets.has(e.wid)),this.wallets.set(e.wid,e)}unregister(e){a(this.wallets.has(e.wid)),this.wallets.delete(e.wid)}async getWalletID(e){var t;return e?"number"==typeof e?e:this.widCache.get(e)||((t=await this.db.get(h.l(e)))?(t=t.readUInt32LE(0,!0),this.widCache.set(e,t),t):null):null}async get(e){if(!(e=await this.getWalletID(e)))return null;var t=await this.readLock.lock(e);try{return await this._get(e)}finally{t()}}async _get(e){var t=this.wallets.get(e);return t||((t=await this.db.get(h.w(e)))?(await(e=n.fromRaw(this,t)).open(),this.register(e),e):null)}async loadBackup(e){if(ne.unsupported)throw new ue(ce.INTERNAL_ERROR,"FS not available.");let t=null;var i;for(i of(await ne.readFile(e,"utf8")).split(/\n+/))if(0!==(i=i.trim()).length&&!/^\s*#/.test(i)){var r=i.split(/\s+/);if(r.length<4)throw new ue(ce.DESERIALIZATION_ERROR,"Malformed wallet Data File.");switch(r[0]){case"W":var s=Buffer.from(r[1],"base64");s=n.fromRaw(this,s);await this.replace(s),t=await this.get(s.id),this.logger.info("Import Wallet %s(%s)",t.id,t.wid);break;case"C":s=Buffer.from(r[1],"base64");(c=((u=o.fromRaw(this,s)).wallet=t,u.wid=t.wid,u.id=t.id,u.initialized=!0,u.watchOnly=t.watchOnly,u.receive=u.deriveReceive(u.receiveDepth-1),u.change=u.deriveChange(u.changeDepth-1),u.witness&&(u.nested=u.deriveNested(u.nestedDepth-1)),t.master.key.deriveAccount(44,u.accountIndex))).publicKey.toString("hex")!==u.accountKey.publicKey.toString("hex")&&a(c.publicKey.toString("hex")==u.accountKey.publicKey.toString("hex")),await t.saveAccount(u),this.logger.info("Import Account %s(%s)",u.name,u.accountIndex);break;case"A":var c=oe.parseSecret(r[1],this.network),u=parseInt(r[5]),h=parseInt(r[7]),l=parseInt(r[9]),p=r[11].trim();if(h<0||l<0)try{await t.importKey(u,c)}catch(e){this.logger.error(`loadBackup: ${e.message} account/secret: ${u}/`+p)}else{var d=await t.deriveKey(u,h,l),f=await t.deriveKey(u,h,l,t.master);d.getAddress("string")!==f.getAddress("string")&&this.logger.error(`loadBackup: not-equal-1: ${d.getAddress("string")} != `+f.getAddress("string")),d.getAddress("string")!==p&&this.logger.error(`loadBackup: not-equal-2: ${d.getAddress("string")} != `+p)}this.logger.info("Import Address %s %s %s %s",u,h,l,p)}}return t.accountCache.reset(),t}save(e){var t=e.wid,i=e.id,r=this.batch(e);this.widCache.set(i,t),r.put(h.w(t),e.toRaw()),r.put(h.l(i),T(t))}async rename(e,t){var i=await this.writeLock.lock();try{return await this._rename(e,t)}finally{i()}}async _rename(e,t){var i=e.id;if(!s.isName(t))throw new Error("WDB: Bad wallet ID.");if(await this.has(t))throw new Error("WDB: ID not available.");this.start(e).del(h.l(i)),e.id=t,this.save(e),await this.commit(e),this.widCache.remove(i),i=e.pathCache.values();for(const e of i)e.id=t}async replace(e){var t=await this.writeLock.lock();try{return await this._replace(e)}finally{t()}}async _replace(e){var t=this.start(e);t.del(h.l(e.id)),t.del(h.w(e.wid)),this.save(e),await this.commit(e),this.widCache.remove(e.id),this.wallets.delete(e.wid)}renameAccount(e,t){var i=e.wallet;this.batch(i).del(h.i(e.wid,e.name)),e.name=t,this.saveAccount(e)}async auth(e,t){if("string"==typeof t){if(!j.isHex256(t))throw new Error("WDB Authentication: Invalid Token.");t=Buffer.from(t,"hex")}e=y.getHmac(e.toString(),this.keys.hmacSalt);var i=r.createHmac("sha256",e.random);i=Buffer.from(i.update(e.token).digest("hex"),"hex");if(!p(t,i))throw new Error("WDB Authentication: CRC Error.")}async create(e){var t=await this.writeLock.lock();e=e||{};try{return await this._create(e)}finally{t()}}async _create(e){if(await this.has(e.id))throw new Error("WDB: Wallet already exists.");"string"==typeof e.mnemonic&&(e.mnemonic={phrase:e.mnemonic}),e.mnemonic=e.mnemonic||{},!e.mnemonic.language&&this.options.mnemonic&&this.options.mnemonic.language&&(e.mnemonic.language=this.options.mnemonic.language);var t=n.fromOptions(this,e);return t.wid=this.depth++,await t.init(e),this.register(t),this.logger.info("Created wallet %s in AccountDB.",t.id),t}async has(e){return null!=await this.getWalletID(e)}async ensure(e){return await this.get(e.id)||this.create(e)}async getAccount(e,t){return(e=await this.db.get(h.a(e,t)))?o.fromRaw(this,e):null}getAccounts(e){return this.db.values({gte:h.n(e,0),lte:h.n(e,4294967295),parse:e=>e.toString("ascii")})}async getAccountMap(e){for(var t={},i=this.db.iterator({gte:h.n(e,0),lte:h.n(e,4294967295),values:!0});;){var r=await i.next();if(!r)break;try{var[,a]=h.nn(r.key);t[a]=r.value.toString("ascii")}catch(e){throw await i.end(),e}}return t}async getAccountIndex(e,t){return(e=await this.db.get(h.i(e,t)))?e.readUInt32LE(0,!0):-1}async getAccountName(e,t){return(e=await this.db.get(h.n(e,t)))?e.toString("ascii"):null}saveAccount(e){var t=e.wid,i=e.wallet,r=e.accountIndex,a=e.name,s=this.batch(i);s.put(h.a(t,r),e.toRaw()),s.put(h.i(t,a),T(r)),s.put(h.n(t,r),Buffer.from(a,"ascii")),i.accountCache.push(r,e)}hasAccount(e,t){return"number"==typeof e&&"number"==typeof t&&this.db.has(h.a(e,t))}async getPathMap(e){var t=this.pathMapCache.get(e);return t||((t=await this.db.get(h.p(e)))?(t=ie.fromRaw(e,t),this.pathMapCache.set(e,t),t):null)}saveKey(e,t){return this.savePath(e,t.toPath())}async savePath(e,t){var i=e.wid,r=t.hash,a=this.batch(e);this.addHash(r);let s=await this.getPathMap(r);(s=s||new ie(r)).add(i)&&(this.pathMapCache.set(r,s),e.pathCache.push(r,t),a.put(h.p(r),s.toRaw()),a.put(h.P(i,r),t.toRaw()),a.put(h.r(i,t.account,r),null))}async getPath(e,t){var i=await this.db.get(h.P(e,t));return i?((i=Q.fromRaw(i)).wid=e,i.hash=t,i):null}hasPath(e,t){return this.db.has(h.P(e,t))}getHashes(){return this.db.keys({gte:h.p(P.NULL_HASH),lte:h.p(P.HIGH_HASH),parse:h.pp})}getOutpoints(){return this.db.keys({gte:h.o(P.NULL_HASH,0),lte:h.o(P.HIGH_HASH,4294967295),parse:e=>{var[e,t]=h.oo(e);return new m(e,t)}})}getWalletHashes(e){return this.db.keys({gte:h.P(e,P.NULL_HASH),lte:h.P(e,P.HIGH_HASH),parse:h.Pp})}getAccountHashes(e,t){return this.db.keys({gte:h.r(e,t,P.NULL_HASH),lte:h.r(e,t,P.HIGH_HASH),parse:h.rr})}async getWalletPaths(e){var t=[];for(const a of await this.db.range({gte:h.P(e,P.NULL_HASH),lte:h.P(e,P.HIGH_HASH)})){var i=h.Pp(a.key),r=Q.fromRaw(a.value);r.hash=i,r.wid=e,t.push(r)}return t}async encryptKeys(e,t){var i,r,s=e.wid,n=await e.getPaths(),o=this.batch(e);for(i of n)i.data&&(a(!i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.encipher(i.data,t,r),i.encrypted=!0,e.pathCache.push(i.hash,i),o.put(h.P(s,i.hash),i.toRaw()))}async decryptKeys(e,t){var i,r,s=e.wid,n=await e.getPaths(),o=this.batch(e);for(i of n)i.data&&(a(i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.decipher(i.data,t,r),i.encrypted=!1,e.pathCache.push(i.hash,i),o.put(h.P(s,i.hash),i.toRaw()))}async resend(){var e,t={};for(const e of await this.db.keys({gte:h.w(0),lte:h.w(4294967295)})){var i=h.ww(e),r=await this.resendPending(i);r&&Array.isArray(r)&&(t[i]=r)}for(e of Object.keys(t))if(await this.get(parseInt(e)))for(const i of t[e]){try{await this.send(i)}catch(e){this.logger.warning("wdb resend:",e.message)}await se.timeout(50)}}async resendPending(e){var t=await this.get(e),i=await this.db.keys({gte:u.txdb.prefix(e,u.txdb.p(P.NULL_HASH)),lte:u.txdb.prefix(e,u.txdb.p(P.HIGH_HASH))});if(0!==i.length){this.logger.info("Rebroadcasting %d transactions for %d.",i.length,e);var r=[];for(const o of i){var a=u.txdb.pp(o),s=u.txdb.prefix(e,u.txdb.t(a));if((s=await this.db.get(s))&&!(s=re.fromRaw(s)).tx.isCoinbase())try{var n=await b.FactoryOfContract({tx:s.tx,env:this});await n.isBlockFinal()==w.Expired?t&&(await this.removeTX(s.tx),await t.remove(a),await n.erase()):"notify"!=n.oper&&r.push(s.tx)}catch(e){this.logger.error("TX(%s) Smart Contract Error: %s",s.tx.txid(),e.message)}}return A(r)}}getWallets(){return this.db.keys({gte:h.l("\0"),lte:h.l("ÿ"),parse:h.ll})}async getWalletsByTX(e){var t=new Set;if(!e.isCoinbase())for(const r of e.inputs){var i=r.prevout;if(this.testFilter(i.toRaw())&&(i=await this.getOutpointMap(i.hash,i.index)))for(const e of i.wids)t.add(e)}for(const i of e.getOutputHashes("hex"))if(this.testFilter(i)){var r=await this.getPathMap(i);if(r)for(const e of r.wids)t.add(e)}return 0===t.size?null:t}async getState(){var e=await this.db.get(h.R);return e?Z.fromRaw(e):null}async init(e){var t=this.options.startHeight;let i;if(this.client){if(null!=t){if(!(i=await this.client.getEntry(t)))throw new Error("WDB: Could not find start block.")}else i=await this.client.getTip();i=te.fromEntry(i)}else i=te.fromEntry(this.network.genesis);this.logger.info("Initializing AccountDB chain state (height %d).",i.height),(t=await this.getState())?this.state=t:await this.resetState(i,!1),await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),e&&e.backup&&await this.loadBackup(e.backup)}async resetState(e,t){for(var i=this.state.clone(),r=(i.startHeight=e.height,i.startHash=e.hash,i.height=e.height,i.marked=t,this.db.batch()),a=this.db.iterator({gte:h.h(e.height),lte:h.h(4294967295),values:!1});;){var s=await a.next();if(!s)break;try{r.del(s.key)}catch(e){throw await a.end(),e}}r.put(h.h(e.height),e.toHash()),r.put(h.R,i.toRaw()),await r.write(),this.state=i}async syncState(e){var t=this.state.clone(),i=this.db.batch();if(e.height<t.height){let a=t.height;var r=a-e.height;for(let e=0;e<r;e++)i.del(h.h(a--))}else e.height>t.height&&a(e.height===t.height+1,`Bad chain sync tip ${e.height} while state `+t.height);t.height=e.height,i.put(h.h(e.height),e.toHash()),i.put(h.R,t.toRaw()),await i.write(),this.state=t,V("block/tips",t)}get curHeight(){return this.state.height}get tidCreator(){return u.txdb.tx}get finder(){return this.getTXFromDb.bind(this)}rpcExecute(){return this.rpc.execute.apply(this.rpc,arguments)}async getBlockMap(e){var t=await this.db.get(h.b(e));return t?ee.fromRaw(e,t):null}writeBlockMap(e,t,i){this.batch(e).put(h.b(t),i.toRaw())}unwriteBlockMap(e,t){this.batch(e).del(h.b(t))}async getOutpointMap(e,t){var i=await this.db.get(h.o(e,t));return i?J.fromRaw(e,t,i):null}writeOutpointMap(e,t,i,r){e=this.batch(e),this.addOutpoint(t,i),e.put(h.o(t,i),r.toRaw())}unwriteOutpointMap(e,t,i){this.batch(e).del(h.o(t,i))}async writeBalanceLog(e,t){var i=h.log(e.wid,t.aidx,t.height,t.hash),r=(t=Buffer.from(JSON.stringify(t)),await this.writeLock.lock());try{this.start(e).put(i,t),await this.commit(e)}finally{r()}}async queryBalanceLog(e,t,i=0){return this.db.values({gte:h.log(e,t,i,P.NULL_HASH),lte:h.log(e,t,this.curHeight,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async getBlock(e){var t,i=await this.db.get(h.h(e));return i?((t=new te).hash=i.toString("hex"),t.height=e,t):null}async getTip(){var e=await this.getBlock(this.curHeight);if(e)return e;throw new Error("WDB: Tip not found!")}async rollback(e,t=!0){if(e>this.curHeight)throw new Error("WDB: Cannot rollback to the future.");if(e===this.curHeight)return this.logger.debug("Rolled back to same height (%d).",e),!0;this.logger.info("Rolling back %d AccountDB blocks to height %d.",this.curHeight-e,e);var i=await this.getBlock(e);let r=!1;return i?(await this.revert(i.height),await this.syncState(i),t):(i=new te,e>=this.state.startHeight?(i.height=this.state.startHeight,i.hash=this.state.startHash,r=this.state.marked,this.logger.warning("Rolling back AccountDB to start block (%d).",i.height)):(i.height=0,i.hash=this.network.genesis.hash,r=!1,this.logger.warning("Rolling back AccountDB to genesis block.")),await this.revert(i.height),await this.resetState(i,r),!1)}async revert(e){var t=this.db.iterator({gte:h.b(e+1),lte:h.b(4294967295),reverse:!0,values:!0});let i=0;for(;;){var r=await t.next();if(!r)break;try{var a=h.bb(r.key),s=ee.fromRaw(a,r.value).toArray();i+=s.length;for(let e=s.length-1;0<=e;e--)await this._unconfirm(s[e])}catch(e){throw await t.end(),e}}this.logger.info("Rolled back %d AccountDB transactions.",i)}async addBlock(e,t){var i=await this.txLock.lock();try{return await this._addBlock(e,t)}finally{i()}}async _addBlock(e,t){var i=te.fromEntry(e);let r=0;if(i.height<this.curHeight)this.logger.warning("AccountDB is connecting low blocks (%d).",i.height);else{if(i.height===this.curHeight)this.logger.warning("Already saw AccountDB block (%d).",i.height);else if(i.height!==this.curHeight+1)throw new Error(`WDB(addBlock): Bad disconnection (height mismatch, tip ${i.height} while state ${this.curHeight})`);if(await this.syncState(i),await this.propList.save(),!(this.options.checkpoints&&i.height<=this.network.lastCheckpoint)){for(const e of t)await this._insert(e,i)&&r++;0<r&&this.logger.info("Connected AccountDB block %s (tx=%d).",j.revHex(i.hash),r)}}return r}async removeBlock(e,t){var i=await this.txLock.lock();try{return await this._removeBlock(e,t)}finally{i()}}async _removeBlock(e,t){if((e=te.fromEntry(e)).height>this.curHeight)return this.logger.warning("AccountDB is disconnecting high blocks (%d).",e.height),0;if(e.height!==this.curHeight)throw new Error(`WDB(removeBlock): Bad disconnection (height mismatch, tip ${e.height} / ${j.revHex(e.hash)} while state ${this.curHeight})`);var i=await this.getBlock(e.height-1);if(!i)throw new Error(`WDB(removeBlock): Bad disconnection (no previous block of ${e.height} / ${j.revHex(e.hash)}).`);var r=await this.getBlockMap(e.height);if(r){for(let e=t.length-1;0<=e;e--){var a=t[e];await this._unconfirm(a,r)}this.logger.warning("Disconnected wallet block %s (tx=%d).",j.revHex(e.hash),r.txs.size)}return await this.syncState(i),await this.propList.save(),r?r.txs.size:0}async rescanBlock(e,t){if(this.rescanning){var i=await this.scanLock.lock();try{await this._addBlock(e,t)}catch(e){throw this.emit("error",e),e}finally{i()}}else this.logger.warning("Unsolicited rescan block: %s.",e.height)}async addTX(e,t,i){var r=await this.txLock.lock();try{return await this._insert(e,t,i)}finally{r()}}listNotify(e){return this.NotifyList.deletes([["h","<",this.curHeight-12]]),this.NotifyList.query(e)}listContact(e,t,i){return this.$contacts.query(e,t,i)}async setCp(e){await this.batchPut(u.txdb.cp(e.cid),e.toRaw())}async delCp(e){await this.batchDel(u.txdb.cp(e))}async delVp(e){var t=this.db.batch();t.del(u.txdb.VP(e.pid)),await t.write()}async setVp(e,t){var i=this.db.batch();i.put(u.txdb.VP(e.pid),e.toRaw()),await i.write()}async getVp(e){return(e=await this.db.get(u.txdb.VP(e)))?W.fromRaw(e):null}async getVpByAddress(e){return{list:[],count:0}}async getVpByOid(e){return{list:[],count:0}}async loadVpList(){return this.db.values({gte:u.txdb.VP(P.ZERO_CID,"hex"),lte:u.txdb.VP(P.MAX_CID,"hex"),parse:e=>W.fromRaw(e)})}async saveContact(e){var t=this.db.batch();t.put(u.txdb.CT(e.getAddress()),e.toRaw()),await t.write()}async loadContact(e){var t;for(t of await this.db.values({gte:u.txdb.CT(P.ZERO_HASH160_HEX),lte:u.txdb.CT(P.MAX_HASH160_HEX),parse:e=>S.fromRaw(e,this)}))t.sender&&(t.sender.wallet=await this.get(t.sender.wid)),this.$contacts.set(t.address,t)}async delHtlc(e){var t;(e=new F(e)).id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(u.txdb.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new F(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.aa)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.ba));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(u.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new F(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.ab)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.bb));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(u.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:u.txdb.VH(P.ZERO_CID,0),lte:u.txdb.VH(P.MAX_CID,4294967295),parse:e=>F.fromRaw(e)})}async delComment(e){var t;(e=new M(e)).id&&(this.commentList.delete(e.id),this.commentList.delAccount(e),(t=this.db.batch()).del(u.txdb.VC(e.shash,e.sidx)),await t.write())}async setComment(e){e=new M(e);var t,[t,i]=(this.commentList.set(e.id,e),await this.getAccountByAddress(e.bob));(t=(t&&(this.commentList.setAccount(e,t,i),this.emit("comm.comment",e)),this.db.batch())).put(u.txdb.VC(e.shash,e.sidx),e.toRaw()),await t.write()}async loadCommentList(){return this.db.values({gte:u.txdb.VC(P.ZERO_CID,0),lte:u.txdb.VC(P.MAX_CID,4294967295),parse:e=>M.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(u.txdb.ER(e.erid)),t.del(u.txdb.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){t&&e.source&&(i=g.fromWitnessPubkeyhash(l.hash160(Buffer.from(e.source.pubkey,"hex")),this.network),[i,t]=await this.getAccountByAddress(i,t),e.wid=i,e.account=t);var i=this.db.batch();t=u.txdb.ERR(e.witness,e.erid,e.txid);i.put(t,e.toRaw()),i.put(u.txdb.ER(e.erid),t),await i.write()}async getEr(e){var t;return(e=await this.db.get(u.txdb.ER(e)))&&([,,t]=u.txdb.ERRR(e),e=await this.db.get(e))?((e=Y.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){var r,a=new _;e=await this.db.values({gte:u.txdb.ERR(e,P.NULL_HASH,P.NULL_HASH),lte:u.txdb.ERR(e,P.HIGH_HASH,P.HIGH_HASH),parse:e=>Y.fromRaw(e)});let s=[],n=new Map;if(i){for(var o of e)(!n.get(o.source.cluster)||o.startHeight>n.get(o.source.cluster).startHeight)&&n.set(o.source.cluster,await this.caVerifyObj(o));s=n.values()}else s=e;for(r of s)a.set(r.erid,r);return a.query(t)}async caVerifyObj(e){var t={verify:!1};if(!e||e.validHeight<=this.curHeight)return t;var i=await this.erAbList.getErAb(e.erid);return i&&i.abolishHeight<this.curHeight?t:(i=ae.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verify(i)?(e.verify=!0,0<(i=this.cpList.query([["pubKey",e.witness]])).list.length&&(e.cpid=i.list[0].cid),e):t)}async delErAbolish(e){var t=this.db.batch();t.del(u.txdb.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(u.txdb.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(u.txdb.ERA(e)))?q.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:u.txdb.ERA(P.ZERO_CID),lte:u.txdb.ERA(P.MAX_CID),parse:e=>q.fromRaw(e)})}async delAudit(e){var t=this.db.batch();t.del(u.txdb.AU(e.erid)),await t.write()}async setAudit(e){var t=this.db.batch();t.put(u.txdb.AU(e.erid),e.toRaw()),await t.write()}async getAudit(e){return(e=await this.db.get(u.txdb.AU(e)))?X.fromRaw(e):null}async loadAuditList(){return this.db.values({gte:u.txdb.AU(P.NULL_HASH),lte:u.txdb.AU(P.HIGH_HASH),parse:e=>X.fromRaw(e)})}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}async _insert(e,t,i){a(!e.mutable,"WDB: Cannot add mutable TX.");let r=await this.getWalletsByTX(e);if(r){this.logger.info("Incoming transaction for %d wallets in AccountDB (%s).",r.size,e.txid()),!t||this.state.marked||(this.logger.info("Marking AccountDB start block at %s (%d).",j.revHex(t.hash),t.height),await this.resetState(t,!0));let n=!1;for(const o of r){var s=await this.get(o);a(s),await s.add(e,t,i)&&(this.logger.info("Added transaction to wallet in AccountDB: %s (%d).",s.id,o),n=!0)}n||(r=null)}try{var n=await b.FactoryOfContract({env:this,block:t,tx:e});t?await n.confirm():await n.insert()}catch(n){t?this.logger.error("TX(%s) Smart Contract Confirm Error: %s",e.txid(),n.message):this.logger.error("TX(%s) Smart Contract Insert Error: %s",e.txid(),n.message)}return r}async _unconfirm(e,t){if(t)try{await(await b.FactoryOfContract({env:this,block:t,tx:e})).unconfirm()}catch(t){this.logger.error("TX(%s) Smart Contract Unconfirm Error: %s",e.txid(),t.message)}let i,r=null;if(i=e.wids?(r=e.wids,e.hash):(r=await this.getWalletsByTX(e),e.hash("hex")),!r)return null;for(const e of r){var s=await this.get(e);a(s),await s.unconfirm(i)}}async resetChain(e){var t=await this.txLock.lock();try{return await this._resetChain(e)}finally{t()}}async _resetChain(e){if(e.height>this.curHeight)throw new Error(`WDB: Bad reset height ${e.height} while curHeight `+this.curHeight);var t;for(t of(await this.rollback(e.height)||await this._rescan(),await this.getWallets())){var i=await this.get(t);for(const t of await i.getPending())try{await i.abandon(t.hash)}catch(e){}}}async saveMSTrans(e){var t=await this.writeLock.lock();try{return await this._saveMSTrans(e)}finally{t()}}async _saveMSTrans(e){var t=this.db.batch();t.put(h.ms(g.getHash(e.addr,"hex"),e.txid),Buffer.from(JSON.stringify(e))),await t.write()}async listMSTrans(e){return e=g.getHash(e,"hex"),this.db.values({gte:h.ms(e,P.NULL_HASH),lte:h.ms(e,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async delMSTrans(e,t){var i=await this.writeLock.lock();try{return await this._delMSTrans(e,t)}finally{i()}}async _delMSTrans(e,t){e=g.getHash(e,"hex");var i=this.db.batch();i.del(h.ms(e,t)),await i.write()}}he.layout=h,e.exports=he},function(e,t,i){"use strict";
|
|
833
|
+
*/const r=i(8),a=i(0),s=i(73),n=i(119),o=i(157),c=i(610),u=i(85),h=u.walletdb,l=i(6),p=i(158),d=i(125),f=i(167);var{}=i(32);const m=i(45),g=i(13);i(20),i(69);const v=i(197),y=i(68),b=i(50),{BlockFinalType:w,ContractEnvType:x}=i(5),k=i(159),S=i(612),_=i(37);var E=i(72);const j=i(2),A=i(141).sortWithSeq,R=i(35),I=i(198),O=i(64),C=i(100),P=i(3),T=P.U32,B=i(338),N=i(339),z=i(340),F=z.vpItem,L=i(617),M=L.vpItem,D=i(312);i(618);const H=D.cpItem,U=i(154),q=U.ErAbolishItem,V=i(38).broadcast,K=i(132),W=K.vpItem,$=i(153),Y=$.ErItem,G=i(619),X=G.AuditItem,J=i(305),Q=i(109),Z=i(620),ee=i(306),te=i(120),ie=i(621),re=i(217),ae=i(39),se=i(36),ne=i(59),oe=i(78),ce=oe.errors,ue=i(77);class he extends E{constructor(e){super(),this.readyLoad=!1,this.options=new c(e),this.network=this.options.network,this.logger=this.options.logger.context("wallet"),this.workers=this.options.workers,this.keys={hmacSalt:P.DefaultChainCode},e.keys&&e.keys.hmacSalt&&(a(Buffer.isBuffer(e.keys.hmacSalt)),this.keys.hmacSalt=e.keys.hmacSalt),this.client=this.options.client,this.client&&(this.client.wdb=this),this.jsonp=this.options.jsonp,this.jsonp&&(this.jsonp.wdb=this),this.spv=this.options.spv,this.feeRate=this.options.feeRate,this.db=f(this.options),this.rpc=new B(this),this.primary=null,this.state=new Z,this.wallets=new Map,this.depth=0,this.rescanning=!1,this.bound=!1,this.newRecord=!0,this.readLock=new I,this.writeLock=new R,this.txLock=new R,this.scanLock=new R,this.widCache=new O(1e4),this.pathMapCache=new O(1e5),this.filter=new C,this.middleHashMem=new Set,this.middleHashChain=new Set,this.autoTaskMgr=new k(this),this.transactionList=new N(this),this.htlcList=new z(this),this.commentList=new L(this),this.NotifyList=new _,this.propList=new K(this),this.$contacts=new _,this.cpList=new D(this),this.cpMemList=new D(this),this.auditList=new G(this),this.erList=new $(this),this.erAbList=new U(this),this.hmacConnection=[],this._init()}async logAudit(e){e.height=this.curHeight,e.time=j.now(),e.erid=l.sha256(j.stringify(e)).toString("hex"),e=new X(e),await this.auditList.setAudit(e)}async getAccountByAddress(e,t){if(e){let a=null;if(a=t?await this.getWalletsByTX(t):await this.getWallets())for(const t of a){var i=await this.get(t);if(i){var r=await i.getPath(e);if(r)return[i.wid,r.name,i.id]}}}return[0,"",""]}_init(){let e=1e6,t=-1;this.spv&&(e=2e4,t=C.flags.ALL),this.filter=C.fromRate(e,.001,t)}get mode(){return x.Wallet}async getTXFromAll(e){return this.getTXFromDb(e)}async checkNewRecord(){var e={createIfMissing:this.db.options.createIfMissing,errorIfExists:this.db.options.errorIfExists};this.db.options.createIfMissing=!1,this.db.options.errorIfExists=!0;try{await this.db.open();var t=await this.db.checkVersion(h,6);this.newRecord="new"==t}catch(e){if(-1!=e.message.indexOf("does not exist (create_if_missing is false)"))this.newRecord=!0;else{if(-1==e.message.indexOf("exists (error_if_exists is true)"))throw e;this.newRecord=!1}}try{await this.db.close()}catch(e){}this.db.options.createIfMissing=e.createIfMissing,this.db.options.errorIfExists=e.errorIfExists}async isNewRecord(){return await this.checkNewRecord(),this.newRecord}setmnemonic(e){if(this.options.mnemonic=this.options.mnemonic||{},e.bits)this.options.mnemonic={bits:e.bits};else if(e.entropy)this.options.mnemonic={entropy:Buffer.from(e.entropy,"hex")};else if(e.phrase){var t=this.testmnemonic(e.phrase);if(0!=t.code)throw t.msg;this.options.mnemonic={phrase:e.phrase}}e.passphrase&&(this.options.mnemonic.passphrase=e.passphrase),e.language&&(this.options.mnemonic.language=e.language)}testmnemonic(e){try{return new v(e),{code:0}}catch(e){return{code:-1,msg:e.message}}}async getContracts(e){var t=await this.db.values({gte:u.txdb.tx(P.NULL_HASH),lte:u.txdb.tx(P.HIGH_HASH),parse:e=>j.parseJson(e.toString())});return e?t.filter(t=>t.srcact==e||t.dstact==e):t}isFull(){return this.spv||this.synced||!1}async _open(e){}async handleNotify(e,t=!1){if(!t){let i=e.body.content;if("string"==typeof i)try{i=JSON.parse(e.body.content)}catch(e){return}"object"==typeof i&&"secret"===i.type&&(t={contact:e.body.src,messenger:e.body.dst},i.init&&(t.init=Buffer.from(i.init,"hex")),i.packet&&(t.packet=Buffer.from(i.packet)),await this.handleSecret(t))}}async handleSecret(e){if(e.contact&&e.messenger&&e.contact!=e.messenger){try{g.fromString(e.contact,this.network.type),g.fromString(e.messenger,this.network.type)}catch(e){return}var t=await this.ensureContact(e);t&&await t.ensureMessenger(e).answer(e)}}async scanContact(e,t=-1){var i=async e=>{var t;e.witness&&"witnesspubkeyhash"==e.getType()&&(t=e.witness.getPubkeyhashInput()[1],e=g.fromWitness(e.witness).toString(),t)&&e&&await this.ensureContact({contact:e,publicKey:t})};if(0<=t&&t<e.inputs.length)await i(e.inputs[t]);else for(var r of e.inputs)await i(r)}async ensureContact(e){if(!e.contact||e.contact==e.messenger)return null;try{g.fromString(e.contact,this.network.type),e.messenger&&g.fromString(e.messenger,this.network.type)}catch(e){return null}e.network=this.network.type,this.$contacts.get(e.contact)||this.$contacts.set(e.contact,new S(e));var t=this.$contacts.get(e.contact);if(e.messenger&&!(e=t.ensureMessenger(e)).wallet){var i,[i,r]=await this.getAccountByAddress(e.address);if(!(i=await this.get(i)))return;e.wallet=i,e.account=r}return t}getCps(){return this.db.values({gte:u.txdb.cp(P.ZERO_CID,"hex"),lte:u.txdb.cp(P.MAX_CID,"hex"),parse:e=>H.fromRaw(e)})}async _close(){await this.disconnect(),this.http&&this.options.listen&&await this.http.close();for(const e of this.wallets.values())await e.destroy();await this.db.close(),this.options.listen&&await this.logger.close()}async destroy(){await this.db.destroy(),this.widCache.reset(),this.pathMapCache.reset()}async load(e){if(this.readyLoad){var t=await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),i=await this.txLock.lock();try{await this.init(e),await this.watch(),await t.createReceive(0,1,t.master,this.network.type),await t.ensureNotifyKey(),await this.sync()}finally{i()}setTimeout(()=>{this.resend()},5e3)}}async disconnect(){this.client&&await this.client._close(),this.jsonp&&await this.jsonp._close()}async flushCP(e,t=!1){this.client&&(e=e||[],t||(e=this.cpList.excludeCids(e),t=t||0<e.length),t)&&await this.client.execute("cp.remoteQuery",[[["cid","include",e]]])}async watch(){let e=this.db.iterator({gte:h.p(P.NULL_HASH),lte:h.p(P.HIGH_HASH)}),t=0,i=0;for(;;){var r=await e.next();if(!r)break;try{var a=h.pp(r.key);this.addHash(a,!1)}catch(t){throw await e.end(),t}t++}for(e=this.db.iterator({gte:h.o(P.NULL_HASH,0),lte:h.o(P.HIGH_HASH,4294967295)});;){var s=await e.next();if(!s)break;try{var[n,o]=h.oo(s.key);this.addOutpoint(n,o)}catch(t){throw await e.end(),t}i++}this.logger.info("Filter: Added %d hashes to AccountDB filter.",t),this.logger.info("Filter: Added %d outpoints to AccountDB filter.",i),await this.setFilter()}async sync(){if(this.client){let t,i=this.curHeight;for(;0<=i;){var e=await this.getBlock(i);if(!e)break;if(t=await this.client.getEntry(e.hash))break;i--}t||(i=this.state.startHeight,t=await this.client.getEntry(this.state.startHash))||(i=0),await this.cpList.loadHistory(),await this.cpMemList.loadHistory(),await this.propList.loadHistory(),await this.htlcList.loadHistory(),await this.commentList.loadHistory(),await this.transactionList.loadHistory(),await this.loadContact(),await this.erList.loadHistory(),await this.auditList.loadHistory(),await this.erAbList.loadHistory(),await this._rescan(i,!1)}}async _rescan(e,t=!0){if(this.client){null==e&&(e=this.state.startHeight),a(e>>>0===e,"WDB: Must pass in a height.");var i=this.curHeight;t=(await this.rollback(e,t),this.logger.info("AccountDB is scanning %d blocks.",i-e+1),await this.getTip());try{this.rescanning=!0,await this.client.rescan(t.hash,this.eid)}finally{this.rescanning=!1}}}async rescan(e){var t=await this.txLock.lock();try{return await this._rescan(e,!1)}finally{t()}}async send(e){return this.client?this.client.send(e):(this.emit("send",e),Promise.resolve())}async getTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getTXFromDb(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getExtendTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t}return null}async removeTX(e){this.client?await this.client.removeTX(e):this.emit("remove",e)}async estimateFee(e){return 0<this.feeRate?this.feeRate:!this.client||(e=await this.client.estimateFee(e))<this.network.feeRate?this.network.feeRate:e>this.network.maxFeeRate?this.network.maxFeeRate:e}setFilter(){return this.client?this.client.setFilter(this.filter):(this.emit("filter.set",this.filter),Promise.resolve())}resetFilter(){return this.client?this.client.resetFilter():(this.emit("filter.reset"),Promise.resolve())}backup(e){return this.db.backup(e)}async wipe(){this.logger.warning("Wiping AccountDB TXDB..."),this.logger.warning("I hope you know what you're doing.");var e=this.db.iterator({gte:Buffer.from([0]),lte:Buffer.from([255])}),t=this.db.batch();let i=0;for(;;){var r=await e.next();if(!r)break;try{switch(r.key[0]){case 98:case 99:case 101:case 116:case 111:case 104:case 82:t.del(r.key),i++}}catch(t){throw await e.end(),t}}this.logger.warning("Wiped %d txdb records.",i),await t.write()}async getDepth(){var e=this.db.iterator({gte:h.w(0),lte:h.w(4294967295),reverse:!0,limit:1}),t=await e.next();return t?(await e.end(),h.ww(t.key)+1):1}start(e){return a(!e.current,"WDB: Batch already started."),e.current=this.db.batch(),e.accountCache.start(),e.pathCache.start(),e.current}drop(e){var t=this.batch(e);e.current=null,e.accountCache.drop(),e.pathCache.drop(),t.clear()}clear(e){var t=this.batch(e);e.accountCache.clear(),e.pathCache.clear(),t.clear()}batch(e){return a(e.current,"WDB: Batch does not exist."),e.current}async commit(e){var t=this.batch(e);try{await t.write()}catch(e){throw this.drop(),e}e.current=null,e.accountCache.commit(),e.pathCache.commit()}testFilter(e){return this.filter.test(e,"hex")}addHash(e,t=!0){this.filter.add(e,"hex"),t&&(t=Buffer.from(e,"hex"),this.client?this.client.addFilter(t):this.emit("filter.add",t))}addOutpoint(e,t){e=new m(e,t),this.filter.add(e.toRaw())}dump(){return this.db.dump()}register(e){a(!this.wallets.has(e.wid)),this.wallets.set(e.wid,e)}unregister(e){a(this.wallets.has(e.wid)),this.wallets.delete(e.wid)}async getWalletID(e){var t;return e?"number"==typeof e?e:this.widCache.get(e)||((t=await this.db.get(h.l(e)))?(t=t.readUInt32LE(0,!0),this.widCache.set(e,t),t):null):null}async get(e){if(!(e=await this.getWalletID(e)))return null;var t=await this.readLock.lock(e);try{return await this._get(e)}finally{t()}}async _get(e){var t=this.wallets.get(e);return t||((t=await this.db.get(h.w(e)))?(await(e=n.fromRaw(this,t)).open(),this.register(e),e):null)}async loadBackup(e){if(ne.unsupported)throw new ue(ce.INTERNAL_ERROR,"FS not available.");let t=null;var i;for(i of(await ne.readFile(e,"utf8")).split(/\n+/))if(0!==(i=i.trim()).length&&!/^\s*#/.test(i)){var r=i.split(/\s+/);if(r.length<4)throw new ue(ce.DESERIALIZATION_ERROR,"Malformed wallet Data File.");switch(r[0]){case"W":var s=Buffer.from(r[1],"base64");s=n.fromRaw(this,s);await this.replace(s),t=await this.get(s.id),this.logger.info("Import Wallet %s(%s)",t.id,t.wid);break;case"C":s=Buffer.from(r[1],"base64");(c=((u=o.fromRaw(this,s)).wallet=t,u.wid=t.wid,u.id=t.id,u.initialized=!0,u.watchOnly=t.watchOnly,u.receive=u.deriveReceive(u.receiveDepth-1),u.change=u.deriveChange(u.changeDepth-1),u.witness&&(u.nested=u.deriveNested(u.nestedDepth-1)),t.master.key.deriveAccount(44,u.accountIndex))).publicKey.toString("hex")!==u.accountKey.publicKey.toString("hex")&&a(c.publicKey.toString("hex")==u.accountKey.publicKey.toString("hex")),await t.saveAccount(u),this.logger.info("Import Account %s(%s)",u.name,u.accountIndex);break;case"A":var c=oe.parseSecret(r[1],this.network),u=parseInt(r[5]),h=parseInt(r[7]),l=parseInt(r[9]),p=r[11].trim();if(h<0||l<0)try{await t.importKey(u,c)}catch(e){this.logger.error(`loadBackup: ${e.message} account/secret: ${u}/`+p)}else{var d=await t.deriveKey(u,h,l),f=await t.deriveKey(u,h,l,t.master);d.getAddress("string")!==f.getAddress("string")&&this.logger.error(`loadBackup: not-equal-1: ${d.getAddress("string")} != `+f.getAddress("string")),d.getAddress("string")!==p&&this.logger.error(`loadBackup: not-equal-2: ${d.getAddress("string")} != `+p)}this.logger.info("Import Address %s %s %s %s",u,h,l,p)}}return t.accountCache.reset(),t}save(e){var t=e.wid,i=e.id,r=this.batch(e);this.widCache.set(i,t),r.put(h.w(t),e.toRaw()),r.put(h.l(i),T(t))}async rename(e,t){var i=await this.writeLock.lock();try{return await this._rename(e,t)}finally{i()}}async _rename(e,t){var i=e.id;if(!s.isName(t))throw new Error("WDB: Bad wallet ID.");if(await this.has(t))throw new Error("WDB: ID not available.");this.start(e).del(h.l(i)),e.id=t,this.save(e),await this.commit(e),this.widCache.remove(i),i=e.pathCache.values();for(const e of i)e.id=t}async replace(e){var t=await this.writeLock.lock();try{return await this._replace(e)}finally{t()}}async _replace(e){var t=this.start(e);t.del(h.l(e.id)),t.del(h.w(e.wid)),this.save(e),await this.commit(e),this.widCache.remove(e.id),this.wallets.delete(e.wid)}renameAccount(e,t){var i=e.wallet;this.batch(i).del(h.i(e.wid,e.name)),e.name=t,this.saveAccount(e)}async auth(e,t){if("string"==typeof t){if(!j.isHex256(t))throw new Error("WDB Authentication: Invalid Token.");t=Buffer.from(t,"hex")}e=y.getHmac(e.toString(),this.keys.hmacSalt);var i=r.createHmac("sha256",e.random);i=Buffer.from(i.update(e.token).digest("hex"),"hex");if(!p(t,i))throw new Error("WDB Authentication: CRC Error.")}async create(e){var t=await this.writeLock.lock();e=e||{};try{return await this._create(e)}finally{t()}}async _create(e){if(await this.has(e.id))throw new Error("WDB: Wallet already exists.");"string"==typeof e.mnemonic&&(e.mnemonic={phrase:e.mnemonic}),e.mnemonic=e.mnemonic||{},!e.mnemonic.language&&this.options.mnemonic&&this.options.mnemonic.language&&(e.mnemonic.language=this.options.mnemonic.language);var t=n.fromOptions(this,e);return t.wid=this.depth++,await t.init(e),this.register(t),this.logger.info("Created wallet %s in AccountDB.",t.id),t}async has(e){return null!=await this.getWalletID(e)}async ensure(e){return await this.get(e.id)||this.create(e)}async getAccount(e,t){return(e=await this.db.get(h.a(e,t)))?o.fromRaw(this,e):null}getAccounts(e){return this.db.values({gte:h.n(e,0),lte:h.n(e,4294967295),parse:e=>e.toString("ascii")})}async getAccountMap(e){for(var t={},i=this.db.iterator({gte:h.n(e,0),lte:h.n(e,4294967295),values:!0});;){var r=await i.next();if(!r)break;try{var[,a]=h.nn(r.key);t[a]=r.value.toString("ascii")}catch(e){throw await i.end(),e}}return t}async getAccountIndex(e,t){return(e=await this.db.get(h.i(e,t)))?e.readUInt32LE(0,!0):-1}async getAccountName(e,t){return(e=await this.db.get(h.n(e,t)))?e.toString("ascii"):null}saveAccount(e){var t=e.wid,i=e.wallet,r=e.accountIndex,a=e.name,s=this.batch(i);s.put(h.a(t,r),e.toRaw()),s.put(h.i(t,a),T(r)),s.put(h.n(t,r),Buffer.from(a,"ascii")),i.accountCache.push(r,e)}hasAccount(e,t){return"number"==typeof e&&"number"==typeof t&&this.db.has(h.a(e,t))}async getPathMap(e){var t=this.pathMapCache.get(e);return t||((t=await this.db.get(h.p(e)))?(t=ie.fromRaw(e,t),this.pathMapCache.set(e,t),t):null)}saveKey(e,t){return this.savePath(e,t.toPath())}async savePath(e,t){var i=e.wid,r=t.hash,a=this.batch(e);this.addHash(r);let s=await this.getPathMap(r);(s=s||new ie(r)).add(i)&&(this.pathMapCache.set(r,s),e.pathCache.push(r,t),a.put(h.p(r),s.toRaw()),a.put(h.P(i,r),t.toRaw()),a.put(h.r(i,t.account,r),null))}async getPath(e,t){var i=await this.db.get(h.P(e,t));return i?((i=Q.fromRaw(i)).wid=e,i.hash=t,i):null}hasPath(e,t){return this.db.has(h.P(e,t))}getHashes(){return this.db.keys({gte:h.p(P.NULL_HASH),lte:h.p(P.HIGH_HASH),parse:h.pp})}getOutpoints(){return this.db.keys({gte:h.o(P.NULL_HASH,0),lte:h.o(P.HIGH_HASH,4294967295),parse:e=>{var[e,t]=h.oo(e);return new m(e,t)}})}getWalletHashes(e){return this.db.keys({gte:h.P(e,P.NULL_HASH),lte:h.P(e,P.HIGH_HASH),parse:h.Pp})}getAccountHashes(e,t){return this.db.keys({gte:h.r(e,t,P.NULL_HASH),lte:h.r(e,t,P.HIGH_HASH),parse:h.rr})}async getWalletPaths(e){var t=[];for(const a of await this.db.range({gte:h.P(e,P.NULL_HASH),lte:h.P(e,P.HIGH_HASH)})){var i=h.Pp(a.key),r=Q.fromRaw(a.value);r.hash=i,r.wid=e,t.push(r)}return t}async encryptKeys(e,t){var i,r,s=e.wid,n=await e.getPaths(),o=this.batch(e);for(i of n)i.data&&(a(!i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.encipher(i.data,t,r),i.encrypted=!0,e.pathCache.push(i.hash,i),o.put(h.P(s,i.hash),i.toRaw()))}async decryptKeys(e,t){var i,r,s=e.wid,n=await e.getPaths(),o=this.batch(e);for(i of n)i.data&&(a(i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.decipher(i.data,t,r),i.encrypted=!1,e.pathCache.push(i.hash,i),o.put(h.P(s,i.hash),i.toRaw()))}async resend(){var e,t={};for(const e of await this.db.keys({gte:h.w(0),lte:h.w(4294967295)})){var i=h.ww(e),r=await this.resendPending(i);r&&Array.isArray(r)&&(t[i]=r)}for(e of Object.keys(t))if(await this.get(parseInt(e)))for(const i of t[e]){try{await this.send(i)}catch(e){this.logger.warning("wdb resend:",e.message)}await se.timeout(50)}}async resendPending(e){var t=await this.get(e),i=await this.db.keys({gte:u.txdb.prefix(e,u.txdb.p(P.NULL_HASH)),lte:u.txdb.prefix(e,u.txdb.p(P.HIGH_HASH))});if(0!==i.length){this.logger.info("Rebroadcasting %d transactions for %d.",i.length,e);var r=[];for(const o of i){var a=u.txdb.pp(o),s=u.txdb.prefix(e,u.txdb.t(a));if((s=await this.db.get(s))&&!(s=re.fromRaw(s)).tx.isCoinbase())try{var n=await b.FactoryOfContract({tx:s.tx,env:this});await n.isBlockFinal()==w.Expired?t&&(await this.removeTX(s.tx),await t.remove(a),await n.erase()):"notify"!=n.oper&&r.push(s.tx)}catch(e){this.logger.error("TX(%s) Smart Contract Error: %s",s.tx.txid(),e.message)}}return A(r)}}getWallets(){return this.db.keys({gte:h.l("\0"),lte:h.l("ÿ"),parse:h.ll})}async getWalletsByTX(e){var t=new Set;if(!e.isCoinbase())for(const r of e.inputs){var i=r.prevout;if(this.testFilter(i.toRaw())&&(i=await this.getOutpointMap(i.hash,i.index)))for(const e of i.wids)t.add(e)}for(const i of e.getOutputHashes("hex"))if(this.testFilter(i)){var r=await this.getPathMap(i);if(r)for(const e of r.wids)t.add(e)}return 0===t.size?null:t}async getState(){var e=await this.db.get(h.R);return e?Z.fromRaw(e):null}async init(e){var t=this.options.startHeight;let i;if(this.client){if(null!=t){if(!(i=await this.client.getEntry(t)))throw new Error("WDB: Could not find start block.")}else i=await this.client.getTip();i=te.fromEntry(i)}else i=te.fromEntry(this.network.genesis);this.logger.info("Initializing AccountDB chain state (height %d).",i.height),(t=await this.getState())?this.state=t:await this.resetState(i,!1),await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),e&&e.backup&&await this.loadBackup(e.backup)}async resetState(e,t){for(var i=this.state.clone(),r=(i.startHeight=e.height,i.startHash=e.hash,i.height=e.height,i.marked=t,this.db.batch()),a=this.db.iterator({gte:h.h(e.height),lte:h.h(4294967295),values:!1});;){var s=await a.next();if(!s)break;try{r.del(s.key)}catch(e){throw await a.end(),e}}r.put(h.h(e.height),e.toHash()),r.put(h.R,i.toRaw()),await r.write(),this.state=i}async syncState(e){var t=this.state.clone(),i=this.db.batch();if(e.height<t.height){let a=t.height;var r=a-e.height;for(let e=0;e<r;e++)i.del(h.h(a--))}else e.height>t.height&&a(e.height===t.height+1,`Bad chain sync tip ${e.height} while state `+t.height);t.height=e.height,i.put(h.h(e.height),e.toHash()),i.put(h.R,t.toRaw()),await i.write(),this.state=t,V("block/tips",t)}get curHeight(){return this.state.height}get tidCreator(){return u.txdb.tx}get finder(){return this.getTXFromDb.bind(this)}rpcExecute(){return this.rpc.execute.apply(this.rpc,arguments)}async getBlockMap(e){var t=await this.db.get(h.b(e));return t?ee.fromRaw(e,t):null}writeBlockMap(e,t,i){this.batch(e).put(h.b(t),i.toRaw())}unwriteBlockMap(e,t){this.batch(e).del(h.b(t))}async getOutpointMap(e,t){var i=await this.db.get(h.o(e,t));return i?J.fromRaw(e,t,i):null}writeOutpointMap(e,t,i,r){e=this.batch(e),this.addOutpoint(t,i),e.put(h.o(t,i),r.toRaw())}unwriteOutpointMap(e,t,i){this.batch(e).del(h.o(t,i))}async writeBalanceLog(e,t){var i=h.log(e.wid,t.aidx,t.height,t.hash),r=(t=Buffer.from(JSON.stringify(t)),await this.writeLock.lock());try{this.start(e).put(i,t),await this.commit(e)}finally{r()}}async queryBalanceLog(e,t,i=0){return this.db.values({gte:h.log(e,t,i,P.NULL_HASH),lte:h.log(e,t,this.curHeight,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async getBlock(e){var t,i=await this.db.get(h.h(e));return i?((t=new te).hash=i.toString("hex"),t.height=e,t):null}async getTip(){var e=await this.getBlock(this.curHeight);if(e)return e;throw new Error("WDB: Tip not found!")}async rollback(e,t=!0){if(e>this.curHeight)throw new Error("WDB: Cannot rollback to the future.");if(e===this.curHeight)return this.logger.debug("Rolled back to same height (%d).",e),!0;this.logger.info("Rolling back %d AccountDB blocks to height %d.",this.curHeight-e,e);var i=await this.getBlock(e);let r=!1;return i?(await this.revert(i.height),await this.syncState(i),t):(i=new te,e>=this.state.startHeight?(i.height=this.state.startHeight,i.hash=this.state.startHash,r=this.state.marked,this.logger.warning("Rolling back AccountDB to start block (%d).",i.height)):(i.height=0,i.hash=this.network.genesis.hash,r=!1,this.logger.warning("Rolling back AccountDB to genesis block.")),await this.revert(i.height),await this.resetState(i,r),!1)}async revert(e){var t=this.db.iterator({gte:h.b(e+1),lte:h.b(4294967295),reverse:!0,values:!0});let i=0;for(;;){var r=await t.next();if(!r)break;try{var a=h.bb(r.key),s=ee.fromRaw(a,r.value),n=s.toArray();i+=n.length;for(let e=n.length-1;0<=e;e--){var o=await this.getTX(n[e].hash);o&&await this._unconfirm(o,s)}}catch(e){throw await t.end(),e}}this.logger.info("Rolled back %d AccountDB transactions.",i)}async addBlock(e,t){var i=await this.txLock.lock();try{return await this._addBlock(e,t)}finally{i()}}async _addBlock(e,t){var i=te.fromEntry(e);let r=0;if(i.height<this.curHeight)this.logger.warning("AccountDB is connecting low blocks (%d).",i.height);else{if(i.height===this.curHeight)this.logger.warning("Already saw AccountDB block (%d).",i.height);else if(i.height!==this.curHeight+1)throw new Error(`WDB(addBlock): Bad disconnection (height mismatch, tip ${i.height} while state ${this.curHeight})`);if(await this.syncState(i),await this.propList.save(),!(this.options.checkpoints&&i.height<=this.network.lastCheckpoint)){for(const e of t)await this._insert(e,i)&&r++;0<r&&this.logger.info("Connected AccountDB block %s (tx=%d).",j.revHex(i.hash),r)}}return r}async removeBlock(e,t){var i=await this.txLock.lock();try{return await this._removeBlock(e,t)}finally{i()}}async _removeBlock(e,t){if((e=te.fromEntry(e)).height>this.curHeight)return this.logger.warning("AccountDB is disconnecting high blocks (%d).",e.height),0;if(e.height!==this.curHeight)throw new Error(`WDB(removeBlock): Bad disconnection (height mismatch, tip ${e.height} / ${j.revHex(e.hash)} while state ${this.curHeight})`);var i=await this.getBlock(e.height-1);if(!i)throw new Error(`WDB(removeBlock): Bad disconnection (no previous block of ${e.height} / ${j.revHex(e.hash)}).`);var r=await this.getBlockMap(e.height);if(r){for(let e=t.length-1;0<=e;e--)await this._unconfirm(t[e],r);this.logger.warning("Disconnected wallet block %s (tx=%d).",j.revHex(e.hash),r.txs.size)}return await this.syncState(i),await this.propList.save(),r?r.txs.size:0}async rescanBlock(e,t){if(this.rescanning){var i=await this.scanLock.lock();try{await this._addBlock(e,t)}catch(e){throw this.emit("error",e),e}finally{i()}}else this.logger.warning("Unsolicited rescan block: %s.",e.height)}async addTX(e,t,i){var r=await this.txLock.lock();try{return await this._insert(e,t,i)}finally{r()}}listNotify(e){return this.NotifyList.deletes([["h","<",this.curHeight-12]]),this.NotifyList.query(e)}listContact(e,t,i){return this.$contacts.query(e,t,i)}async setCp(e){await this.batchPut(u.txdb.cp(e.cid),e.toRaw())}async delCp(e){await this.batchDel(u.txdb.cp(e))}async delVp(e){var t=this.db.batch();t.del(u.txdb.VP(e.pid)),await t.write()}async setVp(e,t){var i=this.db.batch();i.put(u.txdb.VP(e.pid),e.toRaw()),await i.write()}async getVp(e){return(e=await this.db.get(u.txdb.VP(e)))?W.fromRaw(e):null}async getVpByAddress(e){return{list:[],count:0}}async getVpByOid(e){return{list:[],count:0}}async loadVpList(){return this.db.values({gte:u.txdb.VP(P.ZERO_CID,"hex"),lte:u.txdb.VP(P.MAX_CID,"hex"),parse:e=>W.fromRaw(e)})}async saveContact(e){var t=this.db.batch();t.put(u.txdb.CT(e.getAddress()),e.toRaw()),await t.write()}async loadContact(e){var t;for(t of await this.db.values({gte:u.txdb.CT(P.ZERO_HASH160_HEX),lte:u.txdb.CT(P.MAX_HASH160_HEX),parse:e=>S.fromRaw(e,this)}))t.sender&&(t.sender.wallet=await this.get(t.sender.wid)),this.$contacts.set(t.address,t)}async delHtlc(e){var t;(e=new F(e)).id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(u.txdb.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new F(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.aa)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.ba));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(u.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new F(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.ab)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.bb));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(u.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:u.txdb.VH(P.ZERO_CID,0),lte:u.txdb.VH(P.MAX_CID,4294967295),parse:e=>F.fromRaw(e)})}async delComment(e){var t;(e=new M(e)).id&&(this.commentList.delete(e.id),this.commentList.delAccount(e),(t=this.db.batch()).del(u.txdb.VC(e.shash,e.sidx)),await t.write())}async setComment(e){e=new M(e);var t,[t,i]=(this.commentList.set(e.id,e),await this.getAccountByAddress(e.bob));(t=(t&&(this.commentList.setAccount(e,t,i),this.emit("comm.comment",e)),this.db.batch())).put(u.txdb.VC(e.shash,e.sidx),e.toRaw()),await t.write()}async loadCommentList(){return this.db.values({gte:u.txdb.VC(P.ZERO_CID,0),lte:u.txdb.VC(P.MAX_CID,4294967295),parse:e=>M.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(u.txdb.ER(e.erid)),t.del(u.txdb.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){t&&e.source&&(i=g.fromWitnessPubkeyhash(l.hash160(Buffer.from(e.source.pubkey,"hex")),this.network),[i,t]=await this.getAccountByAddress(i,t),e.wid=i,e.account=t);var i=this.db.batch();t=u.txdb.ERR(e.witness,e.erid,e.txid);i.put(t,e.toRaw()),i.put(u.txdb.ER(e.erid),t),await i.write()}async getEr(e){var t;return(e=await this.db.get(u.txdb.ER(e)))&&([,,t]=u.txdb.ERRR(e),e=await this.db.get(e))?((e=Y.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){var r,a=new _;e=await this.db.values({gte:u.txdb.ERR(e,P.NULL_HASH,P.NULL_HASH),lte:u.txdb.ERR(e,P.HIGH_HASH,P.HIGH_HASH),parse:e=>Y.fromRaw(e)});let s=[],n=new Map;if(i){for(var o of e)(!n.get(o.source.cluster)||o.startHeight>n.get(o.source.cluster).startHeight)&&n.set(o.source.cluster,await this.caVerifyObj(o));s=n.values()}else s=e;for(r of s)a.set(r.erid,r);return a.query(t)}async caVerifyObj(e){var t={verify:!1};if(!e||e.validHeight<=this.curHeight)return t;var i=await this.erAbList.getErAb(e.erid);return i&&i.abolishHeight<this.curHeight?t:(i=ae.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verify(i)?(e.verify=!0,0<(i=this.cpList.query([["pubKey",e.witness]])).list.length&&(e.cpid=i.list[0].cid),e):t)}async delErAbolish(e){var t=this.db.batch();t.del(u.txdb.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(u.txdb.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(u.txdb.ERA(e)))?q.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:u.txdb.ERA(P.ZERO_CID),lte:u.txdb.ERA(P.MAX_CID),parse:e=>q.fromRaw(e)})}async delAudit(e){var t=this.db.batch();t.del(u.txdb.AU(e.erid)),await t.write()}async setAudit(e){var t=this.db.batch();t.put(u.txdb.AU(e.erid),e.toRaw()),await t.write()}async getAudit(e){return(e=await this.db.get(u.txdb.AU(e)))?X.fromRaw(e):null}async loadAuditList(){return this.db.values({gte:u.txdb.AU(P.NULL_HASH),lte:u.txdb.AU(P.HIGH_HASH),parse:e=>X.fromRaw(e)})}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}async _insert(e,t,i){a(!e.mutable,"WDB: Cannot add mutable TX.");let r=await this.getWalletsByTX(e);if(r){this.logger.info("Incoming transaction for %d wallets in AccountDB (%s).",r.size,e.txid()),!t||this.state.marked||(this.logger.info("Marking AccountDB start block at %s (%d).",j.revHex(t.hash),t.height),await this.resetState(t,!0));let n=!1;for(const o of r){var s=await this.get(o);a(s),await s.add(e,t,i)&&(this.logger.info("Added transaction to wallet in AccountDB: %s (%d).",s.id,o),n=!0)}n||(r=null)}try{var n=await b.FactoryOfContract({env:this,block:t,tx:e});t?await n.confirm():await n.insert()}catch(n){t?this.logger.error("TX(%s) Smart Contract Confirm Error: %s",e.txid(),n.message):this.logger.error("TX(%s) Smart Contract Insert Error: %s",e.txid(),n.message)}return r}async _unconfirm(e,t){if(t)try{await(await b.FactoryOfContract({env:this,block:t,tx:e})).unconfirm()}catch(e){this.logger.error("Smart Contract Unconfirm Error: %s",e.message)}var i=e.hash("hex");if(!(e=t.txs.get(i).wids))return null;for(const t of e){var r=await this.get(t);a(r),await r.unconfirm(i)}}async resetChain(e){var t=await this.txLock.lock();try{return await this._resetChain(e)}finally{t()}}async _resetChain(e){if(e.height>this.curHeight)throw new Error(`WDB: Bad reset height ${e.height} while curHeight `+this.curHeight);var t;for(t of(await this.rollback(e.height)||await this._rescan(),await this.getWallets())){var i=await this.get(t);for(const t of await i.getPending())try{await i.abandon(t.hash)}catch(e){}}}async saveMSTrans(e){var t=await this.writeLock.lock();try{return await this._saveMSTrans(e)}finally{t()}}async _saveMSTrans(e){var t=this.db.batch();t.put(h.ms(g.getHash(e.addr,"hex"),e.txid),Buffer.from(JSON.stringify(e))),await t.write()}async listMSTrans(e){return e=g.getHash(e,"hex"),this.db.values({gte:h.ms(e,P.NULL_HASH),lte:h.ms(e,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async delMSTrans(e,t){var i=await this.writeLock.lock();try{return await this._delMSTrans(e,t)}finally{i()}}async _delMSTrans(e,t){e=g.getHash(e,"hex");var i=this.db.batch();i.del(h.ms(e,t)),await i.write()}}he.layout=h,e.exports=he},function(e,t,i){"use strict";
|
|
834
834
|
/*!
|
|
835
835
|
* txdb.js - persistent transaction pool
|
|
836
836
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
package/lib/gamegold.js
CHANGED
|
@@ -206,7 +206,7 @@ var r=i(126),s=r.Buffer;function n(e,t){for(var i in e)t[i]=e[i]}function a(e,t,
|
|
|
206
206
|
* pkg.js - package constants
|
|
207
207
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
208
208
|
* https://github.com/bookmansoft/gamegold
|
|
209
|
-
*/t.protocol="vallnet",t.version="5.4.
|
|
209
|
+
*/t.protocol="vallnet",t.version="5.4.4",t.url="https://github.com/bookmansoft/gamegold"},function(e,t,i){"use strict";
|
|
210
210
|
/*!
|
|
211
211
|
* common.js - p2p constants for vallnet
|
|
212
212
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
@@ -877,7 +877,7 @@ var r=i(776),s=i(778),n=i(779),a=i(780),o=i(781),c=i(782),h=i(783);i=i(784),s=[]
|
|
|
877
877
|
/*!
|
|
878
878
|
* chaindb.js - blockchain data management for vallnet
|
|
879
879
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
880
|
-
*/const r=i(0),s=i(2),n=i(1),a=i(4),o=i(33),c=i(3),h=i(15),u=i(60),l=i(246),p=i(167),d=i(328),f=i(64),m=i(75),g=i(45),y=i(37),v=i(13),b=i(329),w=i(330),k=i(146),x=c.U8,S=c.U32,{getVerifyMsg:_,BlockFinalType:E,ContractEnvType:R,ContractType:A}=i(5);var O=i(72);const C=i(50),I=i(20),j=i(69),P=i(113),T=i(28),B=i(6),N=i(144),M=i(7),L=i(159),F=i(118),z=F.scItem,H=i(339),D=i(312),U=D.cpItem,q=i(132),V=q.vpItem,K=i(340),W=K.vpItem,$=i(729),X=i(153),G=X.ErItem,Y=i(154),J=Y.ErAbolishItem,Z=i(227),Q=Z.EnchancementItem;i(54);const ee=i(341),te=i(117),{opcodes:ie,nestingCodes:re}=i(19),se=i(123),ne=i(26),ae=i(39),oe=i(32).VerifyError;class ce extends O{constructor(e){super(),this.chain=e,this.eid="chaindb",this.fromOptions(e.options),this.db=p(this.options),this.stateCache=new le(this.network),this.state=new ue,this.pending=null,this.current=null,this.coinCache=new f(this.options.coinCache),this.cacheHash=new f(this.options.entryCache),this.cacheHeight=new f(this.options.entryCache),this.autoTaskMgr=new L(this),this.propList=new q(this),this.htlcList=new K(this),this.$voteMgr=new $(this),this.transactionList=new H(this),this.cpList=new D(this),this.scList=new F(this),this.erList=new X(this),this.erAbList=new Y(this),this.enCpList=new Z(this,{type:"cp"}),this.middleHashChain=new Set}get hmacConnection(){return this.node.specialCp.content()}get voteMgr(){return this.$voteMgr}get mode(){return R.Block}fromOptions(e){this.options=e,this.node=e.node,this.network=e.network,this.logger=e.logger.context("chaindb")}get curHeight(){return this.chain.height}get finder(){return this.node.getTXFromAll?this.node.getTXFromAll.bind(this.node):()=>{}}get tidCreator(){return d.tx}rpcExecute(){return this.node.rpc.execute.apply(this.node.rpc,arguments)}createGenesisCoinbase(e,t){var i,r=new I,s=new P,n=((i=((i=(s.script.pushInt(0),s.script.pushData(c.ZERO_HASH160),Buffer.allocUnsafe(4))).writeUInt32LE(0,0,!0),s.script.pushData(i),s.script.pushData(c.ZERO_U64),s.script.compile(),s.witness.push(c.ZERO_HASH),s.witness.compile(),r.inputs.push(s),new T)).script.createScript(c.ZERO_HASH160),i.value=M.ORIGINAL,r.outputs.push(i),c.ZERO_HASH),a=[],[a,,]=(a.push(c.ZERO_HASH),N.createRoot(a));a=B.root256(a,n);return(n=new T).script.fromCommitment(a),r.outputs.push(n),s.script.setData(1,t),s.script.compile(),i.script.fromAddress(e.addresses[0]),r}dummyInput(){return P.fromOutpoint(new g(c.NULL_HASH,0))}createGenesisBlock(e){if(!e.addresses||e.addresses.length<11)throw new Error("addresses length expect 11.");let t=e.flags;t=t||Buffer.from("In the name of Athena: Of the user, By the user, and For the user.","ascii");var i=this.createGenesisCoinbase(e,t),r=this.network.genesisId,n=new j,[n,,]=(n.addInput(this.dummyInput()),n.cpRegister(e.addresses[0],M.COIN,{cid:r,oper:A.cpRegister,name:"ATHENA",ip:"*",pubAddress:"",pubKey:"",signMethod:""}),n.commit()),a=new j;a.addInput(this.dummyInput());for(let t=0;t<10;t++)for(let i=0;i<10;i++){var o={oper:A.propCreate,pid:""+this.network.tokenFix+s.sprintf("%04d",10*t+i+1),oid:this.network.tokenFix+"0000",cid:r,gold:M.COIN};a.propCreate(e.addresses[t+1],o)}var[h,,]=a.commit(),u=new m({version:e.version,prevBlock:c.NULL_HASH,merkleRoot:i.hash("hex"),time:e.time,bits:e.bits,nonce:e.nonce,height:0});return u.txs.push(i),u.txs.push(n),u.txs.push(h),u.refresh(!0),u.merkleRoot=u.createMerkleRoot("hex"),u}async open(e){this.logger.info("Opening ChainDB..."),await this.db.open();var t=await this.db.checkVersion(d,3);if(i=await this.getState()){var i;if(await this.verifyFlags(i),await this.verifyDeployments(),this.stateCache=await this.getStateCache(),this.state=i,!(i=await this.getEntry(0)))throw new Error("genesis block not found.");this.network.genesis.hash=i.hash,this.network.genesis.merkleRoot=i.merkleRoot,this.logger.info("ChainDB successfully loaded.")}else e&&(i=await this.getGenesisParams(e),this.node.miner&&(this.node.miner.addresses=[new v(i.coinbaseAddress)]),this.node.config)&&this.node.config.changeParams(i),await this.saveFlags(),await this.saveDeployments(),await this.saveGenesis(),this.logger.info("ChainDB successfully initialized.");return this.logger.info("Chain State: hash=%s tx=%d coin=%d value=%s.",this.state.rhash(),this.state.tx,this.state.coin,o.btc(this.state.value)),t}async getGenesisParams(e){if(e.isGenesisParams)return e;e=e||{};var t=new ee({name:"wallet-test",db:"memory",resolution:!1,verify:!1}),i=(t=(e.getMnemonicFromMemory=!0,await t.open(e),await t.get("primary")),[]);for(const s of await t.getPaths("default")){var r=s.toAddress();0==s.branch&&i.push(""+r.toString(e.network))}var s,n,a,o,h={};return h[e.network+"Addresses"]=i.reduce((e,t)=>e+(""==e?t:","+t),""),h.coinbaseAddress=i[1],h.notifyAddress=t.notifyAddress,this.node.config.notifyAddress=h.notifyAddress,await se.writeFile(h,e.network+"-genesis.params"),e.isGenesisEncrypt||(s=B.hash256(Buffer.from(t.master.mnemonic.toSeed().toString("hex"))),n=ne.publicKeyCreate(s,!0),a=v.fromWitnessPubkeyhash(B.hash160(n),this.network.type).toString(),o=B.hash256(Buffer.concat([Buffer.from("root"),t.master.key.privateKey])),t={body:{language:t.master.mnemonic.language,phrase:t.master.mnemonic.getPhrase(),passphrase:t.master.mnemonic.passphrase,awardAddress:h.coinbaseAddress,notifyAddress:t.notifyAddress,alliancePrivateKey:o.toString("hex"),allianceName:"root",allianceNodeId:0,allianceNodeToken:{prv:s.toString("hex"),pub:n.toString("hex"),address:a}},password:e.password||c.MNEMONIC_SALT,network:e.network,file:e.network+"-genesis.keystore"},await se.writeEncryptFile(t)),h}close(){return this.db.close()}start(){return r(!this.current),r(!this.pending),this.current=this.db.batch(),this.pending=this.state.clone(),this.coinCache.start(),this.cacheHash.start(),this.cacheHeight.start(),this.current}put(e,t){r(this.current),this.current.put(e,t)}del(e){r(this.current),this.current.del(e)}batch(){return r(this.current),this.current}drop(){var e=this.current;r(this.current),r(this.pending),this.current=null,this.pending=null,this.coinCache.drop(),this.cacheHash.drop(),this.cacheHeight.drop(),this.stateCache.drop(),e.clear()}async commit(){r(this.current),r(this.pending);try{await this.current.write()}catch(e){throw this.current=null,this.pending=null,this.coinCache.drop(),this.cacheHash.drop(),this.cacheHeight.drop(),e}this.pending.committed&&(this.state=this.pending),this.current=null,this.pending=null,this.coinCache.commit(),this.cacheHash.commit(),this.cacheHeight.commit(),this.stateCache.commit()}hasCache(e){return("number"==typeof e?this.cacheHeight:(r("string"==typeof e),this.cacheHash)).has(e)}getCache(e){return("number"==typeof e?this.cacheHeight:(r("string"==typeof e),this.cacheHash)).get(e)}async getHeight(e){var t;return"number"==typeof e?e:(r("string"==typeof e),e===c.NULL_HASH?-1:(t=this.cacheHash.get(e))?t.height:(t=await this.db.get(d.h(e)))?t.readUInt32LE(0,!0):-1)}async getHash(e){var t;return"string"==typeof e?e:(r("number"==typeof e),e<0?null:(t=this.cacheHeight.get(e))?t.hash:(t=await this.db.get(d.H(e)))?t.toString("hex"):null)}async getEntryByHeight(e){var t;return r("number"==typeof e),e<0?null:this.cacheHeight.get(e)||((e=await this.db.get(d.H(e)))&&(e=e.toString("hex"),t=this.state,e=await this.getEntryByHash(e))?(this.state===t&&this.cacheHeight.set(e.height,e),e):null)}async getEntryByHash(e){return r("string"==typeof e),e===c.NULL_HASH?null:this.cacheHash.get(e)||((e=await this.db.get(d.e(e)))?(e=b.fromRaw(e),this.cacheHash.set(e.hash,e),e):null)}getEntry(e){return"number"==typeof e?this.getEntryByHeight(e):this.getEntryByHash(e)}async hasEntry(e){return-1!==await this.getHeight(e)}async getAncestor(e,t){if(t<0)return null;if(r(0<=t),r(t<=e.height),await this.isMainChain(e))return this.getEntryByHeight(t);for(;e.height!==t;){e=this.getPrevCache(e)||await this.getPrevious(e),r(e)}return e}getPrevious(e){return this.getEntryByHash(e.prevBlock)}getPrevCache(e){return this.cacheHash.get(e.prevBlock)||null}async getNext(e){return(e=await this.getNextHash(e.hash))?this.getEntryByHash(e):null}async getNextEntry(e){var t=await this.getEntryByHeight(e.height+1);return t&&t.prevBlock===e.hash?t:null}getTip(){return this.getEntryByHash(this.state.tip)}async getState(){var e=await this.db.get(d.R);return e?ue.fromRaw(e):null}async saveGenesis(){let e=[];e=(this.node.config?this.node.config[this.network.type+"Addresses"]:this.network.genesis.addresses).split(",");var t=this.createGenesisBlock({version:this.network.genesis.version,time:this.network.genesis.time,bits:this.network.genesis.bits,nonce:this.network.genesis.nonce,addresses:e}),i=(this.network.genesis.hash=t.hash("hex"),this.network.genesis.merkleRoot=t.merkleRoot,b.fromBlock(t)),r=(this.logger.info("Writing genesis block to ChainDB."),new u);for(let e=0;e<t.txs.length;e++)r.addTX(t.txs[e],t.height,t.time);await this.save(i,t,r)}async getFlags(){var e=await this.db.get(d.O);return e?he.fromRaw(e):null}async verifyFlags(e){var t=this.options,i=await this.getFlags();let r=!1,s=!1;if(!i)throw new Error("No flags found.");if(t.network!==i.network)throw new Error("Network mismatch for chain.");if(t.spv&&!i.spv)throw new Error("Cannot retroactively enable SPV.");if(!t.spv&&i.spv)throw new Error("Cannot retroactively disable SPV.");if(!i.witness){if(!t.forceFlags)throw new Error("Cannot retroactively enable witness.");r=!0}if(t.prune&&!i.prune){if(!t.forceFlags)throw new Error("Cannot retroactively prune.");s=!0}if(!t.prune&&i.prune)throw new Error("Cannot retroactively unprune.");if(t.indexTX&&!i.indexTX)throw new Error("Cannot retroactively enable TX indexing.");if(!t.indexTX&&i.indexTX)throw new Error("Cannot retroactively disable TX indexing.");if(t.indexAddress&&!i.indexAddress)throw new Error("Cannot retroactively enable address indexing.");if(!t.indexAddress&&i.indexAddress)throw new Error("Cannot retroactively disable address indexing.");r&&(await this.logger.info("Rewriting chain flags."),await this.saveFlags()),s&&(await this.logger.info("Retroactively pruning chain."),await this.prune(e.tip))}async getStateCache(){var e=new le(this.network);for(const s of await this.db.range({gte:d.v(0,c.ZERO_HASH),lte:d.v(255,c.MAX_HASH),values:!0})){var[t,i]=d.vv(s.key),r=s.value[0];e.insert(t,i,r)}return e}saveDeployments(){var e=this.db.batch();return this.writeDeployments(e),e.write()}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}writeDeployments(e){var t=new a(1+17*this.network.deploys.length);t.writeU8(this.network.deploys.length);for(const e of this.network.deploys)t.writeU8(e.bit),t.writeU32(e.startTime),t.writeU32(e.timeout),t.writeI32(e.threshold),t.writeI32(e.window);e.put(d.V,t.render())}async checkDeployments(){var e=await this.db.get(d.V),t=(r(e,"No deployment table found."),new n(e)),i=t.readU8(),s=[];for(let e=0;e<i;e++){var a=t.readU8(),o=t.readU32(),c=t.readU32(),h=t.readI32(),u=t.readI32(),l=this.network.byBit(a);l&&o===l.startTime&&c===l.timeout&&h===l.threshold&&u===l.window||s.push(a)}return s}async verifyDeployments(){let e;try{e=await this.checkDeployments()}catch(t){if("EncodingError"!==t.type)throw t;e=[];for(let t=0;t<32;t++)e.push(t)}if(0===e.length)return!0;var t=this.db.batch();for(const i of e)this.logger.warning("Versionbit deployment params modified."),this.logger.warning("Invalidating cache for bit %d.",i),await this.invalidateCache(i,t);return this.writeDeployments(t),await t.write(),!1}async invalidateCache(e,t){for(const i of await this.db.keys({gte:d.v(e,c.ZERO_HASH),lte:d.v(e,c.MAX_HASH)}))t.del(i)}async prune(){var e=this.options,t=this.network.block.keepBlocks,i=this.network.block.pruneAfterHeight;if((await this.getFlags()).prune)throw new Error("Chain is already pruned.");var s=await this.getHeight(this.state.tip);if(s<=i+t)return!1;i+=1;var n=s-t,a=this.db.batch();for(let e=i;e<=n;e++){var o=await this.getHash(e);if(!o)throw new Error(`Cannot find hash for ${e}.`);a.del(d.b(o)),a.del(d.u(o))}try{e.prune=!0;const t=he.fromOptions(e);r(t.prune),a.put(d.O,t.toRaw()),await a.write()}catch(t){throw e.prune=!1,t}return await this.db.compactRange(),!0}async getNextHash(e){return(e=await this.db.get(d.n(e)))?e.toString("hex"):null}async isMainHash(e){if(r("string"==typeof e),e===c.NULL_HASH)return!1;if(e===this.network.genesis.hash)return!0;if(e===this.state.tip)return!0;var t=this.cacheHash.get(e);return t&&(t=this.cacheHeight.get(t.height))?t.hash===e:!!await this.getNextHash(e)}async isMainChain(e){var t;return!!e.isGenesis()||e.hash===this.state.tip||((t=this.getCache(e.height))?e.hash===t.hash:!!await this.getNextHash(e.hash))}getEntries(){return this.db.values({gte:d.e(c.ZERO_HASH),lte:d.e(c.MAX_HASH),parse:e=>b.fromRaw(e)})}getTimestampHashes(e,t){return this.db.keys({gte:d.th(t,c.ZERO_HASH),lte:d.th(e,c.MAX_HASH),parse:d.thh})}getContracts(){return this.db.values({gte:d.tx(c.NULL_HASH),lte:d.tx(c.HIGH_HASH),parse:e=>s.parseJson(e.toString())})}getCps(){return this.db.values({gte:d.CP(c.ZERO_CID,"hex"),lte:d.CP(c.MAX_CID,"hex"),parse:e=>U.fromRaw(e)})}async setCp(e){var t=this.db.batch();t.put(d.CP(e.cid),e.toRaw()),await t.write()}async delCp(e){var t=this.db.batch();t.del(d.CP(e)),await t.write()}getScs(){return this.db.values({gte:d.SC(c.ZERO_CID,"hex"),lte:d.SC(c.MAX_CID,"hex"),parse:e=>z.fromRaw(e)})}async setSc(e){var t=this.db.batch();t.put(d.SC(e.id),e.toRaw()),await t.write()}async delSc(e){var t=this.db.batch();t.del(d.SC(e)),await t.write()}async getSCList(e){return r(Array.isArray(e)),this.scList.query(e)}async delVp(e){var t=this.db.batch();t.del(d.VP(e.pid)),await t.write()}async setVp(e){var t=this.db.batch();t.put(d.VP(e.pid),e.toRaw()),await t.write()}async getVp(e){return(e=await this.db.get(d.VP(e)))?V.fromRaw(e):null}loadVpList(){return this.db.values({gte:d.VP(c.ZERO_CID,"hex"),lte:d.VP(c.MAX_CID,"hex"),parse:e=>V.fromRaw(e)})}async delHtlc(e){var t;e.id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(d.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new W(e);var t=(this.htlcList.set(e.id,e),this.db.batch());t.put(d.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new W(e);var t=(this.htlcList.set(e.id,e),this.db.batch());t.put(d.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:d.VH(c.ZERO_CID,0),lte:d.VH(c.MAX_CID,4294967295),parse:e=>W.fromRaw(e)})}async delErAbolish(e){var t=this.db.batch();t.del(d.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(d.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(d.ERA(e)))?J.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:d.ERA(c.ZERO_CID),lte:d.ERA(c.MAX_CID),parse:e=>J.fromRaw(e)})}async delCpEn(e){var t=this.db.batch();t.del(d.EN2(e.to,e.from)),await t.write()}async setCpEn(e){var t=this.db.batch();t.put(d.EN2(e.to,e.from),e.toRaw()),await t.write()}loadCpEnList(){return this.db.values({gte:d.EN2(c.ZERO_CID,c.ZERO_CID,"ascii"),lte:d.EN2(c.MAX_CID,c.MAX_CID,"ascii"),parse:e=>Q.fromRaw(e)})}queryCpEnListByCid(e){return this.db.values({gte:d.EN2(e,c.ZERO_CID,"ascii"),lte:d.EN2(e,c.MAX_CID,"ascii"),parse:e=>Q.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(d.ER(e.erid)),t.del(d.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){var i=this.db.batch(),r=d.ERR(e.witness,e.erid,e.txid);i.put(r,e.toRaw()),i.put(d.ER(e.erid),r),await i.write()}async getEr(e){var t;return(e=await this.db.get(d.ER(e)))&&([,,t]=d.ERRR(e),e=await this.db.get(e))?((e=G.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){if(!(e=await this.db.values({gte:d.ERR(e,c.NULL_HASH,c.NULL_HASH),lte:d.ERR(e,c.HIGH_HASH,c.HIGH_HASH),parse:e=>G.fromRaw(e)}))||0==e.length)return[];let r=null;if(i){var s,n=new Map;for(s of e){var a,o=await this.caVerifyObj(s);o&&((a=n.get(o.source.cluster))?o.startHeight>a.startHeight&&n.set(s.source.cluster,o):n.set(o.source.cluster,o))}r=n.values()}else r=e;if(!r||0==r.length)return[];var h,u=new y;for(h of r)u.set(h.erid,h);return u.query(t)}async caVerify(e){return this.caVerifyObj(await this.erList.getEr(e))}async caVerifyObj(e){var t;return e?(e.verify=!1,e.validHeight<=this.chain.height||(t=await this.erAbList.getErAb(e.erid))&&t.abolishHeight<this.chain.height||(t=ae.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verifying(t)&&(e.verify=!0,0<(t=this.cpList.query([["pubKey",e.witness]])).list.length)&&(e.cpid=t.list[0].cid)),e):null}async saveVote(e,t){var i=this.db.batch();i.put(d.VM(e),Buffer.from(JSON.stringify(t))),await i.write()}async saveOracle(e,t){var i=this.db.batch();i.put(d.VO(e),Buffer.from(JSON.stringify(t))),await i.write()}getTips(){return this.db.keys({gte:d.p(c.ZERO_HASH),lte:d.p(c.MAX_HASH),parse:d.pp})}async readCoin(e){var t,i,r,s;return this.options.spv?null:(({hash:t,index:i}=e),e=e.toKey(),r=this.state,(s=this.coinCache.get(e))?k.fromRaw(s):(s=await this.db.get(d.c(t,i)))?(r===this.state&&this.coinCache.set(e,s),k.fromRaw(s)):null)}async getCoin(e,t){return e=new g(e,t),(t=await this.readCoin(e))?t.toCoin(e):null}async hasCoins(e){for(let i=0;i<e.outputs.length;i++){var t=d.c(e.hash(),i);if(await this.db.has(t))return!0}return!1}async getCoinView(e){var t,i=new u;for({prevout:t}of e.inputs){var r=await this.readCoin(t);r&&i.addEntry(t,r)}return i}async getSpentView(e){var t,i=await this.getCoinView(e);for({prevout:t}of e.inputs)if(!i.hasEntry(t)){var r,{hash:r,index:s}=t;if(r=await this.getMeta(r)){const{tx:e,height:t,time:n}=r;s<e.outputs.length&&i.addIndex(e,s,t,n)}}return i}async getUndoCoins(e){return(e=await this.db.get(d.u(e)))?l.fromRaw(e):new l}async getBlock(e){return(e=await this.getRawBlock(e))?m.fromRaw(e):null}async getRawBlock(e){return!this.options.spv&&(e=await this.getHash(e))?this.db.get(d.b(e)):null}async getBlockView(e){var t=new u,i=await this.getUndoCoins(e.hash());if(!i.isEmpty()){for(let r=e.txs.length-1;0<r;r--){var s=e.txs[r];for(let e=s.inputs.length-1;0<=e;e--){var n=s.inputs[e];i.apply(t,n.prevout)}}r(i.isEmpty(),"Undo coins data inconsistency.")}return t}async getMeta(e){return this.options.indexTX&&(e=await this.db.get(d.t(e)))?w.fromRaw(e):null}async getTX(e){return(e=await this.getMeta(e))?e.tx:null}async getExtendTX(e){return(e=await this.getMeta(e))||null}async hasTX(e){return!!this.options.indexTX&&this.db.has(d.t(e))}async getCoinsByAddress(e){if(!this.options.indexAddress)return[];var t=[];for(const o of e=Array.isArray(e)?e:[e]){var i,s,n=v.getHash(o);for([i,s]of await this.db.keys({gte:d.C(n,c.ZERO_HASH,0),lte:d.C(n,c.MAX_HASH,4294967295),parse:d.Cc})){var a=await this.getCoin(i,s);r(a),t.push(a)}}return t}async getHashesByAddress(e,t="both"){if(Array.isArray(e)||(e=[e]),!this.options.indexTX||!this.options.indexAddress)return[];const i=Object.create(null);for(const s of e){var r=v.getHash(s);let e,n;n="input"==t?(e=d.TI(r,c.ZERO_HASH),d.TI(r,c.MAX_HASH)):"output"==t?(e=d.TO(r,c.ZERO_HASH),d.TO(r,c.MAX_HASH)):(e=d.T(r,c.ZERO_HASH),d.T(r,c.MAX_HASH)),await this.db.keys({gte:e,lte:n,parse:e=>{e=d.Tt(e),i[e]=!0}})}return Object.keys(i)}async getTXByAddress(e){var t=[];for(const i of await this.getMetaByAddress(e))t.push(i.tx);return t}async getVpByOid(e){return{list:[],count:0}}async getVpByAddress(e,t="both"){t=await this.getMetaByAddress(e,t);var i=new Map;for(const e of t)for(let t=0;t<e.tx.outputs.length;t++){var r=e.tx.outputs[t],s=r.getReturnData([ie.OP_PROPCREATE,ie.OP_PROPEXCHANGE]);s&&(s.current={height:e.height,hash:e.tx.rhash("hex"),index:t,address:r.getAddress().toString()},!(r=i.get(s.pid))||r.current.height<s.current.height)&&i.set(s.pid,s)}let n=[];return i.forEach(t=>{t.current.address==e&&n.push(t)}),{list:n,count:n.length}}async getMetaByAddress(e,t="both"){if(!this.options.indexTX||!this.options.indexAddress)return[];Array.isArray(e)||(e=[e]);var i=[];for(const n of await this.getHashesByAddress(e,t)){var s=await this.getMeta(n);r(s),i.push(s)}return i}async scan(e,t,i){"number"==typeof(e=null==e?this.network.genesis.hash:e)?this.logger.info("Scanning from height %d.",e):this.logger.info("Scanning from block %s.",s.revHex(e));let r=await this.getEntry(e);if(r){if(!await this.isMainChain(r))throw new Error("Cannot rescan an alternate chain.");let e=0;for(;r;){var n=await this.getBlock(r.hash),a=[];if(e++,n){this.logger.info("Scanning block %s (%d).",r.rhash(),r.height);for(let e=0;e<n.txs.length;e++){var o=n.txs[e];let i=!1;for(let e=0;e<o.outputs.length;e++){var c=o.outputs[e].getHash();c&&(0==r.height||t&&t.test(c))&&(c=g.fromTX(o,e),t&&t.add(c.toRaw()),i=!0)}if(!t||i)a.push(o);else if(0!==e)for(var{prevout:h}of o.inputs)if(!t||t.test(h.toRaw())){a.push(o);break}}}else if(!this.options.spv&&!this.options.prune)throw new Error("Block not found.");await i(r,a),r=await this.getNext(r)}this.logger.info("Finished scanning %d blocks.",e)}}async save(e,t,i){this.start();try{await this._save(e,t,i)}catch(e){throw this.drop(),e}await this.commit()}async _save(e,t,i){var r=t.hash();this.put(d.h(r),S(e.height)),this.put(d.th(t.time,r),null),this.put(d.e(r),e.toRaw()),this.cacheHash.push(e.hash,e),this.del(d.p(e.prevBlock)),this.put(d.p(r),null),this.saveUpdates(),i?(e.isGenesis()||this.put(d.n(e.prevBlock),r),this.put(d.H(e.height),r),this.cacheHeight.push(e.height,e),await this.saveBlock(e,t,i),this.put(d.R,this.pending.commit(r))):await this.saveBlock(e,t)}async reconnect(e,t,i){this.start();try{await this._reconnect(e,t,i)}catch(e){throw this.drop(),e}await this.commit()}async _reconnect(e,t,i){var s=t.hash();r(!e.isGenesis()),this.put(d.n(e.prevBlock),s),this.put(d.H(e.height),s),this.cacheHeight.push(e.height,e),this.cacheHash.push(e.hash,e),this.saveUpdates(),await this.connectBlock(e,t,i),this.put(d.R,this.pending.commit(s))}async disconnect(e,t){let i;this.start();try{i=await this._disconnect(e,t)}catch(e){throw this.drop(),e}return await this.commit(),i}async _disconnect(e,t){return this.del(d.n(e.prevBlock)),this.del(d.H(e.height)),this.cacheHeight.unpush(e.height),this.saveUpdates(),t=await this.disconnectBlock(e,t),this.put(d.R,this.pending.commit(e.prevBlock)),t}saveUpdates(){var e=this.stateCache.updates;if(0!==e.length){this.logger.info("Saving %d state cache updates.",e.length);for(const r of e){var{bit:t,hash:i}=r;this.put(d.v(t,i),r.toRaw())}}}async reset(e){var t=await this.getEntry(e);if(!t)throw new Error("Block not found.");if(!await this.isMainChain(t))throw new Error("Cannot reset on alternate chain.");if(this.options.prune)throw new Error("Cannot reset when pruned.");await this.removeChains();let i=await this.getTip();for(r(i),this.logger.debug("Resetting main chain to: %s",t.rhash());;){if(this.start(),i.hash===t.hash){this.put(d.R,this.pending.commit(i.hash)),await this.commit();break}r(!i.isGenesis()),this.del(d.p(i.hash)),this.put(d.p(i.prevBlock),null),this.del(d.H(i.height)),this.del(d.h(i.hash)),this.del(d.th(i.time,i.hash)),this.del(d.e(i.hash)),this.del(d.n(i.prevBlock));try{await this.removeBlock(i)}catch(e){throw this.drop(),e}this.cacheHeight.remove(i.height),this.cacheHash.remove(i.hash),i=await this.getPrevious(i),r(i)}return i}async removeChains(){var e=await this.getTips();this.start();try{for(const t of e)await this._removeChain(t)}catch(e){throw this.drop(),e}await this.commit()}async _removeChain(e){let t=await this.getEntryByHash(e);if(!t)throw new Error("Alternate chain tip not found.");for(this.logger.debug("Removing alternate chain: %s.",t.rhash());!await this.isMainChain(t);)r(!t.isGenesis()),this.del(d.p(t.hash)),this.del(d.h(t.hash)),this.del(d.th(t.time,t.hash)),this.del(d.e(t.hash)),this.del(d.b(t.hash)),this.cacheHash.unpush(t.hash),t=await this.getPrevious(t),r(t)}async saveBlock(e,t,i){var r=t.hash();this.options.spv||(this.put(d.b(r),t.toRaw()),i&&await this.connectBlock(e,t,i))}async removeBlock(e){if(this.options.spv)return new u;var t=await this.getBlock(e.hash);if(!t)throw new Error("Block not found.");this.del(d.b(t.hash()));var i=await this.disconnectBlock(e,t);return this.put(d.R,this.pending.commit(e.prevBlock)),await this.commit(),await this.chain.fire("block.disconnect",e,t,i),i}saveView(e){for(var[t,i]of e.map)for(var[r,s]of i.outputs){var n;s.spent?(this.del(d.c(t,r)),this.node.transmit("utxo.remove",{oper:"utxo.remove",hash:t,index:r,address:s.output.getAddress().toString(),color:s.output.isColored,value:s.output.value,height:s.height}),this.coinCache.unpush(t+r)):(this.del(d.s(t,r)),n=s.toRaw(),this.put(d.c(t,r),n),this.node.transmit("utxo.add",{oper:"utxo.add",hash:t,index:r,color:s.output.isColored,address:s.output.getAddress().toString(),value:s.output.value,height:s.height}),this.coinCache.push(t+r,n))}}async getSpender(e,t){return(e=await this.db.get(d.s(e,t)))?I.DecodeSpenderValue(e):null}async connectBlock(e,t,i){if(!this.options.spv){var r=t.hash("hex");this.pending.connect(t);for(let u=0;u<t.txs.length;u++){var s=t.txs[u],n=s.hash("hex");if(!e.isGenesis()&&0<u)for(let e=0;e<s.inputs.length;e++){var a=s.inputs[e].prevout,o=i.getOutput(a);this.pending.spend(o);try{await this.emitCoinSpent(s.inputs[e],o,s,t)}catch(e){this.logger.error("connect block:",e.message)}this.put(d.s(a.hash,a.index),I.EncodeSpenderValue(n,e,t.height,r))}for(const e of s.outputs)e.script.isUnspendable()||this.pending.add(e);try{var c=await C.FactoryOfContract({env:this,block:t,tx:s,coins:i});if(!e.isGenesis()){var h=await c.verify();if(1!=h)throw new oe(s,_(h),"bad-contract-verify",100)}await c.isBlockFinal()==E.Final&&await c.confirm()}catch(e){this.logger.error("TX(%s) Smart Contract Execute Error: %s",s.txid(),e.message)}this.indexTX(s,i,e,u)}this.saveView(i),i.undo.isEmpty()||this.put(d.u(r),i.undo.commit()),await this.voteMgr.saveVote(),await this.propList.save(),this.scList.deletes([["indate","<",this.chain.height]]),await this.pruneBlock(e)}}async disconnectBlock(e,t){var i=new u;if(!this.options.spv){var s=t.hash(),n=await this.getUndoCoins(s);this.pending.disconnect(t);for(let r=t.txs.length-1;0<=r;r--){var a=t.txs[r];if(0<r)for(let e=a.inputs.length-1;0<=e;e--){var o=a.inputs[e].prevout;n.apply(i,o),this.pending.add(i.getOutput(o))}i.removeTX(a,e.height,e.time);for(let e=a.outputs.length-1;0<=e;e--){var c=a.outputs[e];c.script.isUnspendable()||this.pending.spend(c)}try{await(await C.FactoryOfContract({env:this,block:t,tx:a})).unconfirm()}catch(s){this.logger.error("TX(%s) Smart Contract Unconfirm Error: %s",a.txid(),s.message)}await this.unindexTX(a,i)}r(n.isEmpty(),"Undo coins data inconsistency."),this.saveView(i),this.del(d.u(s)),await this.voteMgr.saveVote(),await this.propList.save()}return i}async pruneBlock(e){this.options.spv||!this.options.prune||(e=e.height-this.network.block.keepBlocks)<=this.network.block.pruneAfterHeight||(e=await this.getHash(e))&&(this.del(d.b(e)),this.del(d.u(e)))}saveFlags(){var e=he.fromOptions(this.options),t=this.db.batch();return t.put(d.O,e.toRaw()),t.write()}indexTX(e,t,i,r){var s=e.hash();if(this.options.indexTX&&(r=w.fromTX(e,i,r),this.put(d.t(s),r.toRaw()),this.options.indexAddress)){for(const t of e.getHashes())this.put(d.T(t,s),null);for(const t of e.getOutputHashes())this.put(d.TO(t,s),null);for(const i of e.getInputHashes(t))this.put(d.TI(i,s),null)}if(this.options.indexAddress){if(!i.isGenesis()&&!e.isCoinbase())for(var{prevout:n}of e.inputs){var a=t.getOutput(n).getHash();a&&this.del(d.C(a,n.hash,n.index))}for(let t=0;t<e.outputs.length;t++){var o=e.outputs[t].getHash();o&&this.put(d.C(o,s,t),null)}}}async unindexTX(e,t){var i,r=e.hash();if(this.options.indexTX&&(this.del(d.t(r)),this.options.indexAddress))for(i of e.getHashes(t))this.del(d.T(i,r)),this.del(d.TI(i,r)),this.del(d.TO(i,r));if(this.options.indexAddress){if(!e.isCoinbase())for(var{prevout:s}of e.inputs){var n=t.getOutput(s).getHash();n&&this.put(d.C(n,s.hash,s.index),null)}for(let t=0;t<e.outputs.length;t++){var a=e.outputs[t].getHash();a&&this.del(d.C(a,r,t))}}}async readHostList(){return this.db.get(d.HL)}async writeHostList(e){var t=this.db.batch();return t.put(d.HL,e),t.write()}async emitCoinSpent(e,t,i,r){(i={env:this,block:r,tx:i,hash:e.prevout.hash,i:e.prevout.index,height:r.height,output:t,type:t.getReturnType(),data:t.getReturnData(re)}).data&&await te(i).spent(e)}}function he(e){if(!(this instanceof he))return new he(e);this.network=h.primary,this.spv=!1,this.witness=!0,this.prune=!1,this.indexTX=!1,this.indexAddress=!1,e&&this.fromOptions(e)}ce.layout=d,he.prototype.fromOptions=function(e){return this.network=h.get(e.network),null!=e.spv&&(r("boolean"==typeof e.spv),this.spv=e.spv),null!=e.prune&&(r("boolean"==typeof e.prune),this.prune=e.prune),null!=e.indexTX&&(r("boolean"==typeof e.indexTX),this.indexTX=e.indexTX),null!=e.indexAddress&&(r("boolean"==typeof e.indexAddress),this.indexAddress=e.indexAddress),this},he.fromOptions=function(e){return(new he).fromOptions(e)},he.prototype.toRaw=function(){var e=new a(12);let t=0;return this.spv&&(t|=1),this.witness&&(t|=2),this.prune&&(t|=4),this.indexTX&&(t|=8),this.indexAddress&&(t|=16),e.writeU32(this.network.magic),e.writeU32(t),e.writeU32(0),e.render()},he.prototype.fromRaw=function(e){return e=new n(e),this.network=h.fromMagic(e.readU32()),e=e.readU32(),this.spv=0!=(1&e),this.witness=0!=(2&e),this.prune=0!=(4&e),this.indexTX=0!=(8&e),this.indexAddress=0!=(16&e),this},he.fromRaw=function(e){return(new he).fromRaw(e)};class ue{constructor(){this.tip=c.NULL_HASH,this.tx=0,this.coin=0,this.value=0,this.committed=!1}rhash(){return s.revHex(this.tip)}clone(){var e=new ue;return e.tip=this.tip,e.tx=this.tx,e.coin=this.coin,e.value=this.value,e}connect(e){this.tx+=e.txs.length}disconnect(e){this.tx-=e.txs.length}add(e){this.coin++,this.value+=e.value}spend(e){this.coin--,this.value-=e.value}commit(e){return"string"!=typeof e&&(e=e.toString("hex")),this.tip=e,this.committed=!0,this.toRaw()}toRaw(){var e=new a(56);return e.writeHash(this.tip),e.writeU64(this.tx),e.writeU64(this.coin),e.writeU64(this.value),e.render()}static fromRaw(e){var t=new ue;e=new n(e);return t.tip=e.readHash("hex"),t.tx=e.readU64(),t.coin=e.readU64(),t.value=e.readU64(),t}}function le(e){this.network=e,this.bits=[],this.updates=[],this._init()}function pe(e,t,i){this.bit=e,this.hash=t,this.state=i}le.prototype._init=function(){for(let e=0;e<32;e++)this.bits.push(null);for(var{bit:e}of this.network.deploys)r(!this.bits[e]),this.bits[e]=new Map},le.prototype.set=function(e,t,i){var s=this.bits[e];r(s),s.get(t.hash)!==i&&(s.set(t.hash,i),this.updates.push(new pe(e,t.hash,i)))},le.prototype.get=function(e,t){return e=this.bits[e],r(e),null==(e=e.get(t.hash))?-1:e},le.prototype.commit=function(){this.updates.length=0},le.prototype.drop=function(){for(var{bit:e,hash:t}of this.updates)e=this.bits[e],r(e),e.delete(t);this.updates.length=0},le.prototype.insert=function(e,t,i){e=this.bits[e],r(e),e.set(t,i)},pe.prototype.toRaw=function(){return x(this.state)},e.exports=ce},function(e,t,i){"use strict";
|
|
880
|
+
*/const r=i(0),s=i(2),n=i(1),a=i(4),o=i(33),c=i(3),h=i(15),u=i(60),l=i(246),p=i(167),d=i(328),f=i(64),m=i(75),g=i(45),y=i(37),v=i(13),b=i(329),w=i(330),k=i(146),x=c.U8,S=c.U32,{getVerifyMsg:_,BlockFinalType:E,ContractEnvType:R,ContractType:A}=i(5);var O=i(72);const C=i(50),I=i(20),j=i(69),P=i(113),T=i(28),B=i(6),N=i(144),M=i(7),L=i(159),F=i(118),z=F.scItem,H=i(339),D=i(312),U=D.cpItem,q=i(132),V=q.vpItem,K=i(340),W=K.vpItem,$=i(729),X=i(153),G=X.ErItem,Y=i(154),J=Y.ErAbolishItem,Z=i(227),Q=Z.EnchancementItem;i(54);const ee=i(341),te=i(117),{opcodes:ie,nestingCodes:re}=i(19),se=i(123),ne=i(26),ae=i(39),oe=i(32).VerifyError;class ce extends O{constructor(e){super(),this.chain=e,this.eid="chaindb",this.fromOptions(e.options),this.db=p(this.options),this.stateCache=new le(this.network),this.state=new ue,this.pending=null,this.current=null,this.coinCache=new f(this.options.coinCache),this.cacheHash=new f(this.options.entryCache),this.cacheHeight=new f(this.options.entryCache),this.autoTaskMgr=new L(this),this.propList=new q(this),this.htlcList=new K(this),this.$voteMgr=new $(this),this.transactionList=new H(this),this.cpList=new D(this),this.scList=new F(this),this.erList=new X(this),this.erAbList=new Y(this),this.enCpList=new Z(this,{type:"cp"}),this.middleHashChain=new Set}get hmacConnection(){return this.node.specialCp.content()}get voteMgr(){return this.$voteMgr}get mode(){return R.Block}fromOptions(e){this.options=e,this.node=e.node,this.network=e.network,this.logger=e.logger.context("chaindb")}get curHeight(){return this.chain.height}get finder(){return this.node.getTXFromAll?this.node.getTXFromAll.bind(this.node):()=>{}}get tidCreator(){return d.tx}rpcExecute(){return this.node.rpc.execute.apply(this.node.rpc,arguments)}createGenesisCoinbase(e,t){var i,r=new I,s=new P,n=((i=((i=(s.script.pushInt(0),s.script.pushData(c.ZERO_HASH160),Buffer.allocUnsafe(4))).writeUInt32LE(0,0,!0),s.script.pushData(i),s.script.pushData(c.ZERO_U64),s.script.compile(),s.witness.push(c.ZERO_HASH),s.witness.compile(),r.inputs.push(s),new T)).script.createScript(c.ZERO_HASH160),i.value=M.ORIGINAL,r.outputs.push(i),c.ZERO_HASH),a=[],[a,,]=(a.push(c.ZERO_HASH),N.createRoot(a));a=B.root256(a,n);return(n=new T).script.fromCommitment(a),r.outputs.push(n),s.script.setData(1,t),s.script.compile(),i.script.fromAddress(e.addresses[0]),r}dummyInput(){return P.fromOutpoint(new g(c.NULL_HASH,0))}createGenesisBlock(e){if(!e.addresses||e.addresses.length<11)throw new Error("addresses length expect 11.");let t=e.flags;t=t||Buffer.from("In the name of Athena: Of the user, By the user, and For the user.","ascii");var i=this.createGenesisCoinbase(e,t),r=this.network.genesisId,n=new j,[n,,]=(n.addInput(this.dummyInput()),n.cpRegister(e.addresses[0],M.COIN,{cid:r,oper:A.cpRegister,name:"ATHENA",ip:"*",pubAddress:"",pubKey:"",signMethod:""}),n.commit()),a=new j;a.addInput(this.dummyInput());for(let t=0;t<10;t++)for(let i=0;i<10;i++){var o={oper:A.propCreate,pid:""+this.network.tokenFix+s.sprintf("%04d",10*t+i+1),oid:this.network.tokenFix+"0000",cid:r,gold:M.COIN};a.propCreate(e.addresses[t+1],o)}var[h,,]=a.commit(),u=new m({version:e.version,prevBlock:c.NULL_HASH,merkleRoot:i.hash("hex"),time:e.time,bits:e.bits,nonce:e.nonce,height:0});return u.txs.push(i),u.txs.push(n),u.txs.push(h),u.refresh(!0),u.merkleRoot=u.createMerkleRoot("hex"),u}async open(e){this.logger.info("Opening ChainDB..."),await this.db.open();var t=await this.db.checkVersion(d,3);if(i=await this.getState()){var i;if(await this.verifyFlags(i),await this.verifyDeployments(),this.stateCache=await this.getStateCache(),this.state=i,!(i=await this.getEntry(0)))throw new Error("genesis block not found.");this.network.genesis.hash=i.hash,this.network.genesis.merkleRoot=i.merkleRoot,this.logger.info("ChainDB successfully loaded.")}else e&&(i=await this.getGenesisParams(e),this.node.miner&&(this.node.miner.addresses=[new v(i.coinbaseAddress)]),this.node.config)&&this.node.config.changeParams(i),await this.saveFlags(),await this.saveDeployments(),await this.saveGenesis(),this.logger.info("ChainDB successfully initialized.");return this.logger.info("Chain State: hash=%s tx=%d coin=%d value=%s.",this.state.rhash(),this.state.tx,this.state.coin,o.btc(this.state.value)),t}async getGenesisParams(e){if(e.isGenesisParams)return e;e=e||{};var t=new ee({name:"wallet-test",db:"memory",resolution:!1,verify:!1}),i=(t=(e.getMnemonicFromMemory=!0,await t.open(e),await t.get("primary")),[]);for(const s of await t.getPaths("default")){var r=s.toAddress();0==s.branch&&i.push(""+r.toString(e.network))}var s,n,a,o,h={};return h[e.network+"Addresses"]=i.reduce((e,t)=>e+(""==e?t:","+t),""),h.coinbaseAddress=i[1],h.notifyAddress=t.notifyAddress,this.node.config.notifyAddress=h.notifyAddress,await se.writeFile(h,e.network+"-genesis.params"),e.isGenesisEncrypt||(s=B.hash256(Buffer.from(t.master.mnemonic.toSeed().toString("hex"))),n=ne.publicKeyCreate(s,!0),a=v.fromWitnessPubkeyhash(B.hash160(n),this.network.type).toString(),o=B.hash256(Buffer.concat([Buffer.from("root"),t.master.key.privateKey])),t={body:{language:t.master.mnemonic.language,phrase:t.master.mnemonic.getPhrase(),passphrase:t.master.mnemonic.passphrase,awardAddress:h.coinbaseAddress,notifyAddress:t.notifyAddress,alliancePrivateKey:o.toString("hex"),allianceName:"root",allianceNodeId:0,allianceNodeToken:{prv:s.toString("hex"),pub:n.toString("hex"),address:a}},password:e.password||c.MNEMONIC_SALT,network:e.network,file:e.network+"-genesis.keystore"},await se.writeEncryptFile(t)),h}close(){return this.db.close()}start(){return r(!this.current),r(!this.pending),this.current=this.db.batch(),this.pending=this.state.clone(),this.coinCache.start(),this.cacheHash.start(),this.cacheHeight.start(),this.current}put(e,t){r(this.current),this.current.put(e,t)}del(e){r(this.current),this.current.del(e)}batch(){return r(this.current),this.current}drop(){var e=this.current;r(this.current),r(this.pending),this.current=null,this.pending=null,this.coinCache.drop(),this.cacheHash.drop(),this.cacheHeight.drop(),this.stateCache.drop(),e.clear()}async commit(){r(this.current),r(this.pending);try{await this.current.write()}catch(e){throw this.current=null,this.pending=null,this.coinCache.drop(),this.cacheHash.drop(),this.cacheHeight.drop(),e}this.pending.committed&&(this.state=this.pending),this.current=null,this.pending=null,this.coinCache.commit(),this.cacheHash.commit(),this.cacheHeight.commit(),this.stateCache.commit()}hasCache(e){return("number"==typeof e?this.cacheHeight:(r("string"==typeof e),this.cacheHash)).has(e)}getCache(e){return("number"==typeof e?this.cacheHeight:(r("string"==typeof e),this.cacheHash)).get(e)}async getHeight(e){var t;return"number"==typeof e?e:(r("string"==typeof e),e===c.NULL_HASH?-1:(t=this.cacheHash.get(e))?t.height:(t=await this.db.get(d.h(e)))?t.readUInt32LE(0,!0):-1)}async getHash(e){var t;return"string"==typeof e?e:(r("number"==typeof e),e<0?null:(t=this.cacheHeight.get(e))?t.hash:(t=await this.db.get(d.H(e)))?t.toString("hex"):null)}async getEntryByHeight(e){var t;return r("number"==typeof e),e<0?null:this.cacheHeight.get(e)||((e=await this.db.get(d.H(e)))&&(e=e.toString("hex"),t=this.state,e=await this.getEntryByHash(e))?(this.state===t&&this.cacheHeight.set(e.height,e),e):null)}async getEntryByHash(e){return r("string"==typeof e),e===c.NULL_HASH?null:this.cacheHash.get(e)||((e=await this.db.get(d.e(e)))?(e=b.fromRaw(e),this.cacheHash.set(e.hash,e),e):null)}getEntry(e){return"number"==typeof e?this.getEntryByHeight(e):this.getEntryByHash(e)}async hasEntry(e){return-1!==await this.getHeight(e)}async getAncestor(e,t){if(t<0)return null;if(r(0<=t),r(t<=e.height),await this.isMainChain(e))return this.getEntryByHeight(t);for(;e.height!==t;){e=this.getPrevCache(e)||await this.getPrevious(e),r(e)}return e}getPrevious(e){return this.getEntryByHash(e.prevBlock)}getPrevCache(e){return this.cacheHash.get(e.prevBlock)||null}async getNext(e){return(e=await this.getNextHash(e.hash))?this.getEntryByHash(e):null}async getNextEntry(e){var t=await this.getEntryByHeight(e.height+1);return t&&t.prevBlock===e.hash?t:null}getTip(){return this.getEntryByHash(this.state.tip)}async getState(){var e=await this.db.get(d.R);return e?ue.fromRaw(e):null}async saveGenesis(){let e=[];e=(this.node.config?this.node.config[this.network.type+"Addresses"]:this.network.genesis.addresses).split(",");var t=this.createGenesisBlock({version:this.network.genesis.version,time:this.network.genesis.time,bits:this.network.genesis.bits,nonce:this.network.genesis.nonce,addresses:e}),i=(this.network.genesis.hash=t.hash("hex"),this.network.genesis.merkleRoot=t.merkleRoot,b.fromBlock(t)),r=(this.logger.info("Writing genesis block to ChainDB."),new u);for(let e=0;e<t.txs.length;e++)r.addTX(t.txs[e],t.height,t.time);await this.save(i,t,r)}async getFlags(){var e=await this.db.get(d.O);return e?he.fromRaw(e):null}async verifyFlags(e){var t=this.options,i=await this.getFlags();let r=!1,s=!1;if(!i)throw new Error("No flags found.");if(t.network!==i.network)throw new Error("Network mismatch for chain.");if(t.spv&&!i.spv)throw new Error("Cannot retroactively enable SPV.");if(!t.spv&&i.spv)throw new Error("Cannot retroactively disable SPV.");if(!i.witness){if(!t.forceFlags)throw new Error("Cannot retroactively enable witness.");r=!0}if(t.prune&&!i.prune){if(!t.forceFlags)throw new Error("Cannot retroactively prune.");s=!0}if(!t.prune&&i.prune)throw new Error("Cannot retroactively unprune.");if(t.indexTX&&!i.indexTX)throw new Error("Cannot retroactively enable TX indexing.");if(!t.indexTX&&i.indexTX)throw new Error("Cannot retroactively disable TX indexing.");if(t.indexAddress&&!i.indexAddress)throw new Error("Cannot retroactively enable address indexing.");if(!t.indexAddress&&i.indexAddress)throw new Error("Cannot retroactively disable address indexing.");r&&(await this.logger.info("Rewriting chain flags."),await this.saveFlags()),s&&(await this.logger.info("Retroactively pruning chain."),await this.prune(e.tip))}async getStateCache(){var e=new le(this.network);for(const s of await this.db.range({gte:d.v(0,c.ZERO_HASH),lte:d.v(255,c.MAX_HASH),values:!0})){var[t,i]=d.vv(s.key),r=s.value[0];e.insert(t,i,r)}return e}saveDeployments(){var e=this.db.batch();return this.writeDeployments(e),e.write()}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}writeDeployments(e){var t=new a(1+17*this.network.deploys.length);t.writeU8(this.network.deploys.length);for(const e of this.network.deploys)t.writeU8(e.bit),t.writeU32(e.startTime),t.writeU32(e.timeout),t.writeI32(e.threshold),t.writeI32(e.window);e.put(d.V,t.render())}async checkDeployments(){var e=await this.db.get(d.V),t=(r(e,"No deployment table found."),new n(e)),i=t.readU8(),s=[];for(let e=0;e<i;e++){var a=t.readU8(),o=t.readU32(),c=t.readU32(),h=t.readI32(),u=t.readI32(),l=this.network.byBit(a);l&&o===l.startTime&&c===l.timeout&&h===l.threshold&&u===l.window||s.push(a)}return s}async verifyDeployments(){let e;try{e=await this.checkDeployments()}catch(t){if("EncodingError"!==t.type)throw t;e=[];for(let t=0;t<32;t++)e.push(t)}if(0===e.length)return!0;var t=this.db.batch();for(const i of e)this.logger.warning("Versionbit deployment params modified."),this.logger.warning("Invalidating cache for bit %d.",i),await this.invalidateCache(i,t);return this.writeDeployments(t),await t.write(),!1}async invalidateCache(e,t){for(const i of await this.db.keys({gte:d.v(e,c.ZERO_HASH),lte:d.v(e,c.MAX_HASH)}))t.del(i)}async prune(){var e=this.options,t=this.network.block.keepBlocks,i=this.network.block.pruneAfterHeight;if((await this.getFlags()).prune)throw new Error("Chain is already pruned.");var s=await this.getHeight(this.state.tip);if(s<=i+t)return!1;i+=1;var n=s-t,a=this.db.batch();for(let e=i;e<=n;e++){var o=await this.getHash(e);if(!o)throw new Error(`Cannot find hash for ${e}.`);a.del(d.b(o)),a.del(d.u(o))}try{e.prune=!0;const t=he.fromOptions(e);r(t.prune),a.put(d.O,t.toRaw()),await a.write()}catch(t){throw e.prune=!1,t}return await this.db.compactRange(),!0}async getNextHash(e){return(e=await this.db.get(d.n(e)))?e.toString("hex"):null}async isMainHash(e){if(r("string"==typeof e),e===c.NULL_HASH)return!1;if(e===this.network.genesis.hash)return!0;if(e===this.state.tip)return!0;var t=this.cacheHash.get(e);return t&&(t=this.cacheHeight.get(t.height))?t.hash===e:!!await this.getNextHash(e)}async isMainChain(e){var t;return!!e.isGenesis()||e.hash===this.state.tip||((t=this.getCache(e.height))?e.hash===t.hash:!!await this.getNextHash(e.hash))}getEntries(){return this.db.values({gte:d.e(c.ZERO_HASH),lte:d.e(c.MAX_HASH),parse:e=>b.fromRaw(e)})}getTimestampHashes(e,t){return this.db.keys({gte:d.th(t,c.ZERO_HASH),lte:d.th(e,c.MAX_HASH),parse:d.thh})}getContracts(){return this.db.values({gte:d.tx(c.NULL_HASH),lte:d.tx(c.HIGH_HASH),parse:e=>s.parseJson(e.toString())})}getCps(){return this.db.values({gte:d.CP(c.ZERO_CID,"hex"),lte:d.CP(c.MAX_CID,"hex"),parse:e=>U.fromRaw(e)})}async setCp(e){var t=this.db.batch();t.put(d.CP(e.cid),e.toRaw()),await t.write()}async delCp(e){var t=this.db.batch();t.del(d.CP(e)),await t.write()}getScs(){return this.db.values({gte:d.SC(c.ZERO_CID,"hex"),lte:d.SC(c.MAX_CID,"hex"),parse:e=>z.fromRaw(e)})}async setSc(e){var t=this.db.batch();t.put(d.SC(e.id),e.toRaw()),await t.write()}async delSc(e){var t=this.db.batch();t.del(d.SC(e)),await t.write()}async getSCList(e){return r(Array.isArray(e)),this.scList.query(e)}async delVp(e){var t=this.db.batch();t.del(d.VP(e.pid)),await t.write()}async setVp(e){var t=this.db.batch();t.put(d.VP(e.pid),e.toRaw()),await t.write()}async getVp(e){return(e=await this.db.get(d.VP(e)))?V.fromRaw(e):null}loadVpList(){return this.db.values({gte:d.VP(c.ZERO_CID,"hex"),lte:d.VP(c.MAX_CID,"hex"),parse:e=>V.fromRaw(e)})}async delHtlc(e){var t;e.id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(d.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new W(e);var t=(this.htlcList.set(e.id,e),this.db.batch());t.put(d.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new W(e);var t=(this.htlcList.set(e.id,e),this.db.batch());t.put(d.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:d.VH(c.ZERO_CID,0),lte:d.VH(c.MAX_CID,4294967295),parse:e=>W.fromRaw(e)})}async delErAbolish(e){var t=this.db.batch();t.del(d.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(d.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(d.ERA(e)))?J.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:d.ERA(c.ZERO_CID),lte:d.ERA(c.MAX_CID),parse:e=>J.fromRaw(e)})}async delCpEn(e){var t=this.db.batch();t.del(d.EN2(e.to,e.from)),await t.write()}async setCpEn(e){var t=this.db.batch();t.put(d.EN2(e.to,e.from),e.toRaw()),await t.write()}loadCpEnList(){return this.db.values({gte:d.EN2(c.ZERO_CID,c.ZERO_CID,"ascii"),lte:d.EN2(c.MAX_CID,c.MAX_CID,"ascii"),parse:e=>Q.fromRaw(e)})}queryCpEnListByCid(e){return this.db.values({gte:d.EN2(e,c.ZERO_CID,"ascii"),lte:d.EN2(e,c.MAX_CID,"ascii"),parse:e=>Q.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(d.ER(e.erid)),t.del(d.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){var i=this.db.batch(),r=d.ERR(e.witness,e.erid,e.txid);i.put(r,e.toRaw()),i.put(d.ER(e.erid),r),await i.write()}async getEr(e){var t;return(e=await this.db.get(d.ER(e)))&&([,,t]=d.ERRR(e),e=await this.db.get(e))?((e=G.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){if(!(e=await this.db.values({gte:d.ERR(e,c.NULL_HASH,c.NULL_HASH),lte:d.ERR(e,c.HIGH_HASH,c.HIGH_HASH),parse:e=>G.fromRaw(e)}))||0==e.length)return[];let r=null;if(i){var s,n=new Map;for(s of e){var a,o=await this.caVerifyObj(s);o&&((a=n.get(o.source.cluster))?o.startHeight>a.startHeight&&n.set(s.source.cluster,o):n.set(o.source.cluster,o))}r=n.values()}else r=e;if(!r||0==r.length)return[];var h,u=new y;for(h of r)u.set(h.erid,h);return u.query(t)}async caVerify(e){return this.caVerifyObj(await this.erList.getEr(e))}async caVerifyObj(e){var t;return e?(e.verify=!1,e.validHeight<=this.chain.height||(t=await this.erAbList.getErAb(e.erid))&&t.abolishHeight<this.chain.height||(t=ae.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verifying(t)&&(e.verify=!0,0<(t=this.cpList.query([["pubKey",e.witness]])).list.length)&&(e.cpid=t.list[0].cid)),e):null}async saveVote(e,t){var i=this.db.batch();i.put(d.VM(e),Buffer.from(JSON.stringify(t))),await i.write()}async saveOracle(e,t){var i=this.db.batch();i.put(d.VO(e),Buffer.from(JSON.stringify(t))),await i.write()}getTips(){return this.db.keys({gte:d.p(c.ZERO_HASH),lte:d.p(c.MAX_HASH),parse:d.pp})}async readCoin(e){var t,i,r,s;return this.options.spv?null:(({hash:t,index:i}=e),e=e.toKey(),r=this.state,(s=this.coinCache.get(e))?k.fromRaw(s):(s=await this.db.get(d.c(t,i)))?(r===this.state&&this.coinCache.set(e,s),k.fromRaw(s)):null)}async getCoin(e,t){return e=new g(e,t),(t=await this.readCoin(e))?t.toCoin(e):null}async hasCoins(e){for(let i=0;i<e.outputs.length;i++){var t=d.c(e.hash(),i);if(await this.db.has(t))return!0}return!1}async getCoinView(e){var t,i=new u;for({prevout:t}of e.inputs){var r=await this.readCoin(t);r&&i.addEntry(t,r)}return i}async getSpentView(e){var t,i=await this.getCoinView(e);for({prevout:t}of e.inputs)if(!i.hasEntry(t)){var r,{hash:r,index:s}=t;if(r=await this.getMeta(r)){const{tx:e,height:t,time:n}=r;s<e.outputs.length&&i.addIndex(e,s,t,n)}}return i}async getUndoCoins(e){return(e=await this.db.get(d.u(e)))?l.fromRaw(e):new l}async getBlock(e){return(e=await this.getRawBlock(e))?m.fromRaw(e):null}async getRawBlock(e){return!this.options.spv&&(e=await this.getHash(e))?this.db.get(d.b(e)):null}async getBlockView(e){var t=new u,i=await this.getUndoCoins(e.hash());if(!i.isEmpty()){for(let r=e.txs.length-1;0<r;r--){var s=e.txs[r];for(let e=s.inputs.length-1;0<=e;e--){var n=s.inputs[e];i.apply(t,n.prevout)}}r(i.isEmpty(),"Undo coins data inconsistency.")}return t}async getMeta(e){return this.options.indexTX&&(e=await this.db.get(d.t(e)))?w.fromRaw(e):null}async getTX(e){return(e=await this.getMeta(e))?e.tx:null}async getExtendTX(e){return(e=await this.getMeta(e))||null}async hasTX(e){return!!this.options.indexTX&&this.db.has(d.t(e))}async getCoinsByAddress(e){if(!this.options.indexAddress)return[];var t=[];for(const o of e=Array.isArray(e)?e:[e]){var i,s,n=v.getHash(o);for([i,s]of await this.db.keys({gte:d.C(n,c.ZERO_HASH,0),lte:d.C(n,c.MAX_HASH,4294967295),parse:d.Cc})){var a=await this.getCoin(i,s);r(a),t.push(a)}}return t}async getHashesByAddress(e,t="both"){if(Array.isArray(e)||(e=[e]),!this.options.indexTX||!this.options.indexAddress)return[];const i=Object.create(null);for(const s of e){var r=v.getHash(s);let e,n;n="input"==t?(e=d.TI(r,c.ZERO_HASH),d.TI(r,c.MAX_HASH)):"output"==t?(e=d.TO(r,c.ZERO_HASH),d.TO(r,c.MAX_HASH)):(e=d.T(r,c.ZERO_HASH),d.T(r,c.MAX_HASH)),await this.db.keys({gte:e,lte:n,parse:e=>{e=d.Tt(e),i[e]=!0}})}return Object.keys(i)}async getTXByAddress(e){var t=[];for(const i of await this.getMetaByAddress(e))t.push(i.tx);return t}async getVpByOid(e){return{list:[],count:0}}async getVpByAddress(e,t="both"){t=await this.getMetaByAddress(e,t);var i=new Map;for(const e of t)for(let t=0;t<e.tx.outputs.length;t++){var r=e.tx.outputs[t],s=r.getReturnData([ie.OP_PROPCREATE,ie.OP_PROPEXCHANGE]);s&&(s.current={height:e.height,hash:e.tx.rhash("hex"),index:t,address:r.getAddress().toString()},!(r=i.get(s.pid))||r.current.height<s.current.height)&&i.set(s.pid,s)}let n=[];return i.forEach(t=>{t.current.address==e&&n.push(t)}),{list:n,count:n.length}}async getMetaByAddress(e,t="both"){if(!this.options.indexTX||!this.options.indexAddress)return[];Array.isArray(e)||(e=[e]);var i=[];for(const n of await this.getHashesByAddress(e,t)){var s=await this.getMeta(n);r(s),i.push(s)}return i}async scan(e,t,i){"number"==typeof(e=null==e?this.network.genesis.hash:e)?this.logger.info("Scanning from height %d.",e):this.logger.info("Scanning from block %s.",s.revHex(e));let r=await this.getEntry(e);if(r){if(!await this.isMainChain(r))throw new Error("Cannot rescan an alternate chain.");let e=0;for(;r;){var n=await this.getBlock(r.hash),a=[];if(e++,n){this.logger.info("Scanning block %s (%d).",r.rhash(),r.height);for(let e=0;e<n.txs.length;e++){var o=n.txs[e];let i=!1;for(let e=0;e<o.outputs.length;e++){var c=o.outputs[e].getHash();c&&(0==r.height||t&&t.test(c))&&(c=g.fromTX(o,e),t&&t.add(c.toRaw()),i=!0)}if(!t||i)a.push(o);else if(0!==e)for(var{prevout:h}of o.inputs)if(!t||t.test(h.toRaw())){a.push(o);break}}}else if(!this.options.spv&&!this.options.prune)throw new Error("Block not found.");await i(r,a),r=await this.getNext(r)}this.logger.info("Finished scanning %d blocks.",e)}}async save(e,t,i){this.start();try{await this._save(e,t,i)}catch(e){throw this.drop(),e}await this.commit()}async _save(e,t,i){var r=t.hash();this.put(d.h(r),S(e.height)),this.put(d.th(t.time,r),null),this.put(d.e(r),e.toRaw()),this.cacheHash.push(e.hash,e),this.del(d.p(e.prevBlock)),this.put(d.p(r),null),this.saveUpdates(),i?(e.isGenesis()||this.put(d.n(e.prevBlock),r),this.put(d.H(e.height),r),this.cacheHeight.push(e.height,e),await this.saveBlock(e,t,i),this.put(d.R,this.pending.commit(r))):await this.saveBlock(e,t)}async reconnect(e,t,i){this.start();try{await this._reconnect(e,t,i)}catch(e){throw this.drop(),e}await this.commit()}async _reconnect(e,t,i){var s=t.hash();r(!e.isGenesis()),this.put(d.n(e.prevBlock),s),this.put(d.H(e.height),s),this.cacheHeight.push(e.height,e),this.cacheHash.push(e.hash,e),this.saveUpdates(),await this.connectBlock(e,t,i),this.put(d.R,this.pending.commit(s))}async disconnect(e,t){let i;this.start();try{i=await this._disconnect(e,t)}catch(e){throw this.drop(),e}return await this.commit(),i}async _disconnect(e,t){return this.del(d.n(e.prevBlock)),this.del(d.H(e.height)),this.cacheHeight.unpush(e.height),this.saveUpdates(),t=await this.disconnectBlock(e,t),this.put(d.R,this.pending.commit(e.prevBlock)),t}saveUpdates(){var e=this.stateCache.updates;if(0!==e.length){this.logger.info("Saving %d state cache updates.",e.length);for(const r of e){var{bit:t,hash:i}=r;this.put(d.v(t,i),r.toRaw())}}}async reset(e){var t=await this.getEntry(e);if(!t)throw new Error("Block not found.");if(!await this.isMainChain(t))throw new Error("Cannot reset on alternate chain.");if(this.options.prune)throw new Error("Cannot reset when pruned.");await this.removeChains();let i=await this.getTip();for(r(i),this.logger.debug("Resetting main chain to: %s",t.rhash());;){if(this.start(),i.hash===t.hash){this.put(d.R,this.pending.commit(i.hash)),await this.commit();break}r(!i.isGenesis()),this.del(d.p(i.hash)),this.put(d.p(i.prevBlock),null),this.del(d.H(i.height)),this.del(d.h(i.hash)),this.del(d.th(i.time,i.hash)),this.del(d.e(i.hash)),this.del(d.n(i.prevBlock));try{await this.removeBlock(i)}catch(e){throw this.drop(),e}this.cacheHeight.remove(i.height),this.cacheHash.remove(i.hash),i=await this.getPrevious(i),r(i)}return i}async removeChains(){var e=await this.getTips();this.start();try{for(const t of e)await this._removeChain(t)}catch(e){throw this.drop(),e}await this.commit()}async _removeChain(e){let t=await this.getEntryByHash(e);if(!t)throw new Error("Alternate chain tip not found.");for(this.logger.debug("Removing alternate chain: %s.",t.rhash());!await this.isMainChain(t);)r(!t.isGenesis()),this.del(d.p(t.hash)),this.del(d.h(t.hash)),this.del(d.th(t.time,t.hash)),this.del(d.e(t.hash)),this.del(d.b(t.hash)),this.cacheHash.unpush(t.hash),t=await this.getPrevious(t),r(t)}async saveBlock(e,t,i){var r=t.hash();this.options.spv||(this.put(d.b(r),t.toRaw()),i&&await this.connectBlock(e,t,i))}async removeBlock(e){if(this.options.spv)return new u;var t=await this.getBlock(e.hash);if(!t)throw new Error("Block not found.");this.del(d.b(t.hash()));var i=await this.disconnectBlock(e,t);return this.put(d.R,this.pending.commit(e.prevBlock)),await this.commit(),await this.chain.fire("block.disconnect",e,t,i),i}saveView(e){for(var[t,i]of e.map)for(var[r,s]of i.outputs){var n;s.spent?(this.del(d.c(t,r)),this.node.transmit("utxo.remove",{oper:"utxo.remove",hash:t,index:r,address:s.output.getAddress()?s.output.getAddress().toString():null,color:s.output.isColored,value:s.output.value,height:s.height}),this.coinCache.unpush(t+r)):(this.del(d.s(t,r)),n=s.toRaw(),this.put(d.c(t,r),n),this.node.transmit("utxo.add",{oper:"utxo.add",hash:t,index:r,color:s.output.isColored,address:s.output.getAddress()?s.output.getAddress().toString():null,value:s.output.value,height:s.height}),this.coinCache.push(t+r,n))}}async getSpender(e,t){return(e=await this.db.get(d.s(e,t)))?I.DecodeSpenderValue(e):null}async connectBlock(e,t,i){if(!this.options.spv){var r=t.hash("hex");this.pending.connect(t);for(let u=0;u<t.txs.length;u++){var s=t.txs[u],n=s.hash("hex");if(!e.isGenesis()&&0<u)for(let e=0;e<s.inputs.length;e++){var a=s.inputs[e].prevout,o=i.getOutput(a);this.pending.spend(o);try{await this.emitCoinSpent(s.inputs[e],o,s,t)}catch(e){this.logger.error("connect block:",e.message)}this.put(d.s(a.hash,a.index),I.EncodeSpenderValue(n,e,t.height,r))}for(const e of s.outputs)e.script.isUnspendable()||this.pending.add(e);try{var c=await C.FactoryOfContract({env:this,block:t,tx:s,coins:i});if(!e.isGenesis()){var h=await c.verify();if(1!=h)throw new oe(s,_(h),"bad-contract-verify",100)}await c.isBlockFinal()==E.Final&&await c.confirm()}catch(e){this.logger.error("TX(%s) Smart Contract Execute Error: %s",s.txid(),e.message)}this.indexTX(s,i,e,u)}this.saveView(i),i.undo.isEmpty()||this.put(d.u(r),i.undo.commit()),await this.voteMgr.saveVote(),await this.propList.save(),this.scList.deletes([["indate","<",this.chain.height]]),await this.pruneBlock(e)}}async disconnectBlock(e,t){var i=new u;if(!this.options.spv){var s=t.hash(),n=await this.getUndoCoins(s);this.pending.disconnect(t);for(let r=t.txs.length-1;0<=r;r--){var a=t.txs[r];if(0<r)for(let e=a.inputs.length-1;0<=e;e--){var o=a.inputs[e].prevout;n.apply(i,o),this.pending.add(i.getOutput(o))}i.removeTX(a,e.height,e.time);for(let e=a.outputs.length-1;0<=e;e--){var c=a.outputs[e];c.script.isUnspendable()||this.pending.spend(c)}try{await(await C.FactoryOfContract({env:this,block:t,tx:a})).unconfirm()}catch(s){this.logger.error("TX(%s) Smart Contract Unconfirm Error: %s",a.txid(),s.message)}await this.unindexTX(a,i)}r(n.isEmpty(),"Undo coins data inconsistency."),this.saveView(i),this.del(d.u(s)),await this.voteMgr.saveVote(),await this.propList.save()}return i}async pruneBlock(e){this.options.spv||!this.options.prune||(e=e.height-this.network.block.keepBlocks)<=this.network.block.pruneAfterHeight||(e=await this.getHash(e))&&(this.del(d.b(e)),this.del(d.u(e)))}saveFlags(){var e=he.fromOptions(this.options),t=this.db.batch();return t.put(d.O,e.toRaw()),t.write()}indexTX(e,t,i,r){var s=e.hash();if(this.options.indexTX&&(r=w.fromTX(e,i,r),this.put(d.t(s),r.toRaw()),this.options.indexAddress)){for(const t of e.getHashes())this.put(d.T(t,s),null);for(const t of e.getOutputHashes())this.put(d.TO(t,s),null);for(const i of e.getInputHashes(t))this.put(d.TI(i,s),null)}if(this.options.indexAddress){if(!i.isGenesis()&&!e.isCoinbase())for(var{prevout:n}of e.inputs){var a=t.getOutput(n).getHash();a&&this.del(d.C(a,n.hash,n.index))}for(let t=0;t<e.outputs.length;t++){var o=e.outputs[t].getHash();o&&this.put(d.C(o,s,t),null)}}}async unindexTX(e,t){var i,r=e.hash();if(this.options.indexTX&&(this.del(d.t(r)),this.options.indexAddress))for(i of e.getHashes(t))this.del(d.T(i,r)),this.del(d.TI(i,r)),this.del(d.TO(i,r));if(this.options.indexAddress){if(!e.isCoinbase())for(var{prevout:s}of e.inputs){var n=t.getOutput(s).getHash();n&&this.put(d.C(n,s.hash,s.index),null)}for(let t=0;t<e.outputs.length;t++){var a=e.outputs[t].getHash();a&&this.del(d.C(a,r,t))}}}async readHostList(){return this.db.get(d.HL)}async writeHostList(e){var t=this.db.batch();return t.put(d.HL,e),t.write()}async emitCoinSpent(e,t,i,r){(i={env:this,block:r,tx:i,hash:e.prevout.hash,i:e.prevout.index,height:r.height,output:t,type:t.getReturnType(),data:t.getReturnData(re)}).data&&await te(i).spent(e)}}function he(e){if(!(this instanceof he))return new he(e);this.network=h.primary,this.spv=!1,this.witness=!0,this.prune=!1,this.indexTX=!1,this.indexAddress=!1,e&&this.fromOptions(e)}ce.layout=d,he.prototype.fromOptions=function(e){return this.network=h.get(e.network),null!=e.spv&&(r("boolean"==typeof e.spv),this.spv=e.spv),null!=e.prune&&(r("boolean"==typeof e.prune),this.prune=e.prune),null!=e.indexTX&&(r("boolean"==typeof e.indexTX),this.indexTX=e.indexTX),null!=e.indexAddress&&(r("boolean"==typeof e.indexAddress),this.indexAddress=e.indexAddress),this},he.fromOptions=function(e){return(new he).fromOptions(e)},he.prototype.toRaw=function(){var e=new a(12);let t=0;return this.spv&&(t|=1),this.witness&&(t|=2),this.prune&&(t|=4),this.indexTX&&(t|=8),this.indexAddress&&(t|=16),e.writeU32(this.network.magic),e.writeU32(t),e.writeU32(0),e.render()},he.prototype.fromRaw=function(e){return e=new n(e),this.network=h.fromMagic(e.readU32()),e=e.readU32(),this.spv=0!=(1&e),this.witness=0!=(2&e),this.prune=0!=(4&e),this.indexTX=0!=(8&e),this.indexAddress=0!=(16&e),this},he.fromRaw=function(e){return(new he).fromRaw(e)};class ue{constructor(){this.tip=c.NULL_HASH,this.tx=0,this.coin=0,this.value=0,this.committed=!1}rhash(){return s.revHex(this.tip)}clone(){var e=new ue;return e.tip=this.tip,e.tx=this.tx,e.coin=this.coin,e.value=this.value,e}connect(e){this.tx+=e.txs.length}disconnect(e){this.tx-=e.txs.length}add(e){this.coin++,this.value+=e.value}spend(e){this.coin--,this.value-=e.value}commit(e){return"string"!=typeof e&&(e=e.toString("hex")),this.tip=e,this.committed=!0,this.toRaw()}toRaw(){var e=new a(56);return e.writeHash(this.tip),e.writeU64(this.tx),e.writeU64(this.coin),e.writeU64(this.value),e.render()}static fromRaw(e){var t=new ue;e=new n(e);return t.tip=e.readHash("hex"),t.tx=e.readU64(),t.coin=e.readU64(),t.value=e.readU64(),t}}function le(e){this.network=e,this.bits=[],this.updates=[],this._init()}function pe(e,t,i){this.bit=e,this.hash=t,this.state=i}le.prototype._init=function(){for(let e=0;e<32;e++)this.bits.push(null);for(var{bit:e}of this.network.deploys)r(!this.bits[e]),this.bits[e]=new Map},le.prototype.set=function(e,t,i){var s=this.bits[e];r(s),s.get(t.hash)!==i&&(s.set(t.hash,i),this.updates.push(new pe(e,t.hash,i)))},le.prototype.get=function(e,t){return e=this.bits[e],r(e),null==(e=e.get(t.hash))?-1:e},le.prototype.commit=function(){this.updates.length=0},le.prototype.drop=function(){for(var{bit:e,hash:t}of this.updates)e=this.bits[e],r(e),e.delete(t);this.updates.length=0},le.prototype.insert=function(e,t,i){e=this.bits[e],r(e),e.set(t,i)},pe.prototype.toRaw=function(){return x(this.state)},e.exports=ce},function(e,t,i){"use strict";
|
|
881
881
|
/*!
|
|
882
882
|
* lowlevelup.js - LevelUP module for vallnet
|
|
883
883
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
@@ -904,7 +904,7 @@ var r=i(776),s=i(778),n=i(779),a=i(780),o=i(781),c=i(782),h=i(783);i=i(784),s=[]
|
|
|
904
904
|
/*!
|
|
905
905
|
* accountdb.js - storage for account management
|
|
906
906
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|
|
907
|
-
*/const r=i(8),s=i(0),n=i(73),a=i(119),o=i(157),c=i(610),h=i(85),u=h.walletdb,l=i(6),p=i(158),d=i(125),f=i(167);var{}=i(32);const m=i(45),g=i(13);i(20),i(69);const y=i(197),v=i(68),b=i(50),{BlockFinalType:w,ContractEnvType:k}=i(5),x=i(159),S=i(612),_=i(37);var E=i(72);const R=i(2),A=i(141).sortWithSeq,O=i(35),C=i(198),I=i(64),j=i(100),P=i(3),T=P.U32,B=i(338),N=i(339),M=i(340),L=M.vpItem,F=i(617),z=F.vpItem,H=i(312);i(618);const D=H.cpItem,U=i(154),q=U.ErAbolishItem,V=i(38).broadcast,K=i(132),W=K.vpItem,$=i(153),X=$.ErItem,G=i(619),Y=G.AuditItem,J=i(305),Z=i(109),Q=i(620),ee=i(306),te=i(120),ie=i(621),re=i(217),se=i(39),ne=i(36),ae=i(59),oe=i(78),ce=oe.errors,he=i(77);class ue extends E{constructor(e){super(),this.readyLoad=!1,this.options=new c(e),this.network=this.options.network,this.logger=this.options.logger.context("wallet"),this.workers=this.options.workers,this.keys={hmacSalt:P.DefaultChainCode},e.keys&&e.keys.hmacSalt&&(s(Buffer.isBuffer(e.keys.hmacSalt)),this.keys.hmacSalt=e.keys.hmacSalt),this.client=this.options.client,this.client&&(this.client.wdb=this),this.jsonp=this.options.jsonp,this.jsonp&&(this.jsonp.wdb=this),this.spv=this.options.spv,this.feeRate=this.options.feeRate,this.db=f(this.options),this.rpc=new B(this),this.primary=null,this.state=new Q,this.wallets=new Map,this.depth=0,this.rescanning=!1,this.bound=!1,this.newRecord=!0,this.readLock=new C,this.writeLock=new O,this.txLock=new O,this.scanLock=new O,this.widCache=new I(1e4),this.pathMapCache=new I(1e5),this.filter=new j,this.middleHashMem=new Set,this.middleHashChain=new Set,this.autoTaskMgr=new x(this),this.transactionList=new N(this),this.htlcList=new M(this),this.commentList=new F(this),this.NotifyList=new _,this.propList=new K(this),this.$contacts=new _,this.cpList=new H(this),this.cpMemList=new H(this),this.auditList=new G(this),this.erList=new $(this),this.erAbList=new U(this),this.hmacConnection=[],this._init()}async logAudit(e){e.height=this.curHeight,e.time=R.now(),e.erid=l.sha256(R.stringify(e)).toString("hex"),e=new Y(e),await this.auditList.setAudit(e)}async getAccountByAddress(e,t){if(e){let s=null;if(s=t?await this.getWalletsByTX(t):await this.getWallets())for(const t of s){var i=await this.get(t);if(i){var r=await i.getPath(e);if(r)return[i.wid,r.name,i.id]}}}return[0,"",""]}_init(){let e=1e6,t=-1;this.spv&&(e=2e4,t=j.flags.ALL),this.filter=j.fromRate(e,.001,t)}get mode(){return k.Wallet}async getTXFromAll(e){return this.getTXFromDb(e)}async checkNewRecord(){var e={createIfMissing:this.db.options.createIfMissing,errorIfExists:this.db.options.errorIfExists};this.db.options.createIfMissing=!1,this.db.options.errorIfExists=!0;try{await this.db.open();var t=await this.db.checkVersion(u,6);this.newRecord="new"==t}catch(e){if(-1!=e.message.indexOf("does not exist (create_if_missing is false)"))this.newRecord=!0;else{if(-1==e.message.indexOf("exists (error_if_exists is true)"))throw e;this.newRecord=!1}}try{await this.db.close()}catch(e){}this.db.options.createIfMissing=e.createIfMissing,this.db.options.errorIfExists=e.errorIfExists}async isNewRecord(){return await this.checkNewRecord(),this.newRecord}setmnemonic(e){if(this.options.mnemonic=this.options.mnemonic||{},e.bits)this.options.mnemonic={bits:e.bits};else if(e.entropy)this.options.mnemonic={entropy:Buffer.from(e.entropy,"hex")};else if(e.phrase){var t=this.testmnemonic(e.phrase);if(0!=t.code)throw t.msg;this.options.mnemonic={phrase:e.phrase}}e.passphrase&&(this.options.mnemonic.passphrase=e.passphrase),e.language&&(this.options.mnemonic.language=e.language)}testmnemonic(e){try{return new y(e),{code:0}}catch(e){return{code:-1,msg:e.message}}}async getContracts(e){var t=await this.db.values({gte:h.txdb.tx(P.NULL_HASH),lte:h.txdb.tx(P.HIGH_HASH),parse:e=>R.parseJson(e.toString())});return e?t.filter(t=>t.srcact==e||t.dstact==e):t}isFull(){return this.spv||this.synced||!1}async _open(e){}async handleNotify(e,t=!1){if(!t){let i=e.body.content;if("string"==typeof i)try{i=JSON.parse(e.body.content)}catch(e){return}"object"==typeof i&&"secret"===i.type&&(t={contact:e.body.src,messenger:e.body.dst},i.init&&(t.init=Buffer.from(i.init,"hex")),i.packet&&(t.packet=Buffer.from(i.packet)),await this.handleSecret(t))}}async handleSecret(e){if(e.contact&&e.messenger&&e.contact!=e.messenger){try{g.fromString(e.contact,this.network.type),g.fromString(e.messenger,this.network.type)}catch(e){return}var t=await this.ensureContact(e);t&&await t.ensureMessenger(e).answer(e)}}async scanContact(e,t=-1){var i=async e=>{var t;e.witness&&"witnesspubkeyhash"==e.getType()&&(t=e.witness.getPubkeyhashInput()[1],e=g.fromWitness(e.witness).toString(),t)&&e&&await this.ensureContact({contact:e,publicKey:t})};if(0<=t&&t<e.inputs.length)await i(e.inputs[t]);else for(var r of e.inputs)await i(r)}async ensureContact(e){if(!e.contact||e.contact==e.messenger)return null;try{g.fromString(e.contact,this.network.type),e.messenger&&g.fromString(e.messenger,this.network.type)}catch(e){return null}e.network=this.network.type,this.$contacts.get(e.contact)||this.$contacts.set(e.contact,new S(e));var t=this.$contacts.get(e.contact);if(e.messenger&&!(e=t.ensureMessenger(e)).wallet){var i,[i,r]=await this.getAccountByAddress(e.address);if(!(i=await this.get(i)))return;e.wallet=i,e.account=r}return t}getCps(){return this.db.values({gte:h.txdb.cp(P.ZERO_CID,"hex"),lte:h.txdb.cp(P.MAX_CID,"hex"),parse:e=>D.fromRaw(e)})}async _close(){await this.disconnect(),this.http&&this.options.listen&&await this.http.close();for(const e of this.wallets.values())await e.destroy();await this.db.close(),this.options.listen&&await this.logger.close()}async destroy(){await this.db.destroy(),this.widCache.reset(),this.pathMapCache.reset()}async load(e){if(this.readyLoad){var t=await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),i=await this.txLock.lock();try{await this.init(e),await this.watch(),await t.createReceive(0,1,t.master,this.network.type),await t.ensureNotifyKey(),await this.sync()}finally{i()}setTimeout(()=>{this.resend()},5e3)}}async disconnect(){this.client&&await this.client._close(),this.jsonp&&await this.jsonp._close()}async flushCP(e,t=!1){this.client&&(e=e||[],t||(e=this.cpList.excludeCids(e),t=t||0<e.length),t)&&await this.client.execute("cp.remoteQuery",[[["cid","include",e]]])}async watch(){let e=this.db.iterator({gte:u.p(P.NULL_HASH),lte:u.p(P.HIGH_HASH)}),t=0,i=0;for(;;){var r=await e.next();if(!r)break;try{var s=u.pp(r.key);this.addHash(s,!1)}catch(t){throw await e.end(),t}t++}for(e=this.db.iterator({gte:u.o(P.NULL_HASH,0),lte:u.o(P.HIGH_HASH,4294967295)});;){var n=await e.next();if(!n)break;try{var[a,o]=u.oo(n.key);this.addOutpoint(a,o)}catch(t){throw await e.end(),t}i++}this.logger.info("Filter: Added %d hashes to AccountDB filter.",t),this.logger.info("Filter: Added %d outpoints to AccountDB filter.",i),await this.setFilter()}async sync(){if(this.client){let t,i=this.curHeight;for(;0<=i;){var e=await this.getBlock(i);if(!e)break;if(t=await this.client.getEntry(e.hash))break;i--}t||(i=this.state.startHeight,t=await this.client.getEntry(this.state.startHash))||(i=0),await this.cpList.loadHistory(),await this.cpMemList.loadHistory(),await this.propList.loadHistory(),await this.htlcList.loadHistory(),await this.commentList.loadHistory(),await this.transactionList.loadHistory(),await this.loadContact(),await this.erList.loadHistory(),await this.auditList.loadHistory(),await this.erAbList.loadHistory(),await this._rescan(i,!1)}}async _rescan(e,t=!0){if(this.client){null==e&&(e=this.state.startHeight),s(e>>>0===e,"WDB: Must pass in a height.");var i=this.curHeight;t=(await this.rollback(e,t),this.logger.info("AccountDB is scanning %d blocks.",i-e+1),await this.getTip());try{this.rescanning=!0,await this.client.rescan(t.hash,this.eid)}finally{this.rescanning=!1}}}async rescan(e){var t=await this.txLock.lock();try{return await this._rescan(e,!1)}finally{t()}}async send(e){return this.client?this.client.send(e):(this.emit("send",e),Promise.resolve())}async getTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getTXFromDb(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getExtendTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t}return null}async removeTX(e){this.client?await this.client.removeTX(e):this.emit("remove",e)}async estimateFee(e){return 0<this.feeRate?this.feeRate:!this.client||(e=await this.client.estimateFee(e))<this.network.feeRate?this.network.feeRate:e>this.network.maxFeeRate?this.network.maxFeeRate:e}setFilter(){return this.client?this.client.setFilter(this.filter):(this.emit("filter.set",this.filter),Promise.resolve())}resetFilter(){return this.client?this.client.resetFilter():(this.emit("filter.reset"),Promise.resolve())}backup(e){return this.db.backup(e)}async wipe(){this.logger.warning("Wiping AccountDB TXDB..."),this.logger.warning("I hope you know what you're doing.");var e=this.db.iterator({gte:Buffer.from([0]),lte:Buffer.from([255])}),t=this.db.batch();let i=0;for(;;){var r=await e.next();if(!r)break;try{switch(r.key[0]){case 98:case 99:case 101:case 116:case 111:case 104:case 82:t.del(r.key),i++}}catch(t){throw await e.end(),t}}this.logger.warning("Wiped %d txdb records.",i),await t.write()}async getDepth(){var e=this.db.iterator({gte:u.w(0),lte:u.w(4294967295),reverse:!0,limit:1}),t=await e.next();return t?(await e.end(),u.ww(t.key)+1):1}start(e){return s(!e.current,"WDB: Batch already started."),e.current=this.db.batch(),e.accountCache.start(),e.pathCache.start(),e.current}drop(e){var t=this.batch(e);e.current=null,e.accountCache.drop(),e.pathCache.drop(),t.clear()}clear(e){var t=this.batch(e);e.accountCache.clear(),e.pathCache.clear(),t.clear()}batch(e){return s(e.current,"WDB: Batch does not exist."),e.current}async commit(e){var t=this.batch(e);try{await t.write()}catch(e){throw this.drop(),e}e.current=null,e.accountCache.commit(),e.pathCache.commit()}testFilter(e){return this.filter.test(e,"hex")}addHash(e,t=!0){this.filter.add(e,"hex"),t&&(t=Buffer.from(e,"hex"),this.client?this.client.addFilter(t):this.emit("filter.add",t))}addOutpoint(e,t){e=new m(e,t),this.filter.add(e.toRaw())}dump(){return this.db.dump()}register(e){s(!this.wallets.has(e.wid)),this.wallets.set(e.wid,e)}unregister(e){s(this.wallets.has(e.wid)),this.wallets.delete(e.wid)}async getWalletID(e){var t;return e?"number"==typeof e?e:this.widCache.get(e)||((t=await this.db.get(u.l(e)))?(t=t.readUInt32LE(0,!0),this.widCache.set(e,t),t):null):null}async get(e){if(!(e=await this.getWalletID(e)))return null;var t=await this.readLock.lock(e);try{return await this._get(e)}finally{t()}}async _get(e){var t=this.wallets.get(e);return t||((t=await this.db.get(u.w(e)))?(await(e=a.fromRaw(this,t)).open(),this.register(e),e):null)}async loadBackup(e){if(ae.unsupported)throw new he(ce.INTERNAL_ERROR,"FS not available.");let t=null;var i;for(i of(await ae.readFile(e,"utf8")).split(/\n+/))if(0!==(i=i.trim()).length&&!/^\s*#/.test(i)){var r=i.split(/\s+/);if(r.length<4)throw new he(ce.DESERIALIZATION_ERROR,"Malformed wallet Data File.");switch(r[0]){case"W":var n=Buffer.from(r[1],"base64");n=a.fromRaw(this,n);await this.replace(n),t=await this.get(n.id),this.logger.info("Import Wallet %s(%s)",t.id,t.wid);break;case"C":n=Buffer.from(r[1],"base64");(c=((h=o.fromRaw(this,n)).wallet=t,h.wid=t.wid,h.id=t.id,h.initialized=!0,h.watchOnly=t.watchOnly,h.receive=h.deriveReceive(h.receiveDepth-1),h.change=h.deriveChange(h.changeDepth-1),h.witness&&(h.nested=h.deriveNested(h.nestedDepth-1)),t.master.key.deriveAccount(44,h.accountIndex))).publicKey.toString("hex")!==h.accountKey.publicKey.toString("hex")&&s(c.publicKey.toString("hex")==h.accountKey.publicKey.toString("hex")),await t.saveAccount(h),this.logger.info("Import Account %s(%s)",h.name,h.accountIndex);break;case"A":var c=oe.parseSecret(r[1],this.network),h=parseInt(r[5]),u=parseInt(r[7]),l=parseInt(r[9]),p=r[11].trim();if(u<0||l<0)try{await t.importKey(h,c)}catch(e){this.logger.error(`loadBackup: ${e.message} account/secret: ${h}/`+p)}else{var d=await t.deriveKey(h,u,l),f=await t.deriveKey(h,u,l,t.master);d.getAddress("string")!==f.getAddress("string")&&this.logger.error(`loadBackup: not-equal-1: ${d.getAddress("string")} != `+f.getAddress("string")),d.getAddress("string")!==p&&this.logger.error(`loadBackup: not-equal-2: ${d.getAddress("string")} != `+p)}this.logger.info("Import Address %s %s %s %s",h,u,l,p)}}return t.accountCache.reset(),t}save(e){var t=e.wid,i=e.id,r=this.batch(e);this.widCache.set(i,t),r.put(u.w(t),e.toRaw()),r.put(u.l(i),T(t))}async rename(e,t){var i=await this.writeLock.lock();try{return await this._rename(e,t)}finally{i()}}async _rename(e,t){var i=e.id;if(!n.isName(t))throw new Error("WDB: Bad wallet ID.");if(await this.has(t))throw new Error("WDB: ID not available.");this.start(e).del(u.l(i)),e.id=t,this.save(e),await this.commit(e),this.widCache.remove(i),i=e.pathCache.values();for(const e of i)e.id=t}async replace(e){var t=await this.writeLock.lock();try{return await this._replace(e)}finally{t()}}async _replace(e){var t=this.start(e);t.del(u.l(e.id)),t.del(u.w(e.wid)),this.save(e),await this.commit(e),this.widCache.remove(e.id),this.wallets.delete(e.wid)}renameAccount(e,t){var i=e.wallet;this.batch(i).del(u.i(e.wid,e.name)),e.name=t,this.saveAccount(e)}async auth(e,t){if("string"==typeof t){if(!R.isHex256(t))throw new Error("WDB Authentication: Invalid Token.");t=Buffer.from(t,"hex")}e=v.getHmac(e.toString(),this.keys.hmacSalt);var i=r.createHmac("sha256",e.random);i=Buffer.from(i.update(e.token).digest("hex"),"hex");if(!p(t,i))throw new Error("WDB Authentication: CRC Error.")}async create(e){var t=await this.writeLock.lock();e=e||{};try{return await this._create(e)}finally{t()}}async _create(e){if(await this.has(e.id))throw new Error("WDB: Wallet already exists.");"string"==typeof e.mnemonic&&(e.mnemonic={phrase:e.mnemonic}),e.mnemonic=e.mnemonic||{},!e.mnemonic.language&&this.options.mnemonic&&this.options.mnemonic.language&&(e.mnemonic.language=this.options.mnemonic.language);var t=a.fromOptions(this,e);return t.wid=this.depth++,await t.init(e),this.register(t),this.logger.info("Created wallet %s in AccountDB.",t.id),t}async has(e){return null!=await this.getWalletID(e)}async ensure(e){return await this.get(e.id)||this.create(e)}async getAccount(e,t){return(e=await this.db.get(u.a(e,t)))?o.fromRaw(this,e):null}getAccounts(e){return this.db.values({gte:u.n(e,0),lte:u.n(e,4294967295),parse:e=>e.toString("ascii")})}async getAccountMap(e){for(var t={},i=this.db.iterator({gte:u.n(e,0),lte:u.n(e,4294967295),values:!0});;){var r=await i.next();if(!r)break;try{var[,s]=u.nn(r.key);t[s]=r.value.toString("ascii")}catch(e){throw await i.end(),e}}return t}async getAccountIndex(e,t){return(e=await this.db.get(u.i(e,t)))?e.readUInt32LE(0,!0):-1}async getAccountName(e,t){return(e=await this.db.get(u.n(e,t)))?e.toString("ascii"):null}saveAccount(e){var t=e.wid,i=e.wallet,r=e.accountIndex,s=e.name,n=this.batch(i);n.put(u.a(t,r),e.toRaw()),n.put(u.i(t,s),T(r)),n.put(u.n(t,r),Buffer.from(s,"ascii")),i.accountCache.push(r,e)}hasAccount(e,t){return"number"==typeof e&&"number"==typeof t&&this.db.has(u.a(e,t))}async getPathMap(e){var t=this.pathMapCache.get(e);return t||((t=await this.db.get(u.p(e)))?(t=ie.fromRaw(e,t),this.pathMapCache.set(e,t),t):null)}saveKey(e,t){return this.savePath(e,t.toPath())}async savePath(e,t){var i=e.wid,r=t.hash,s=this.batch(e);this.addHash(r);let n=await this.getPathMap(r);(n=n||new ie(r)).add(i)&&(this.pathMapCache.set(r,n),e.pathCache.push(r,t),s.put(u.p(r),n.toRaw()),s.put(u.P(i,r),t.toRaw()),s.put(u.r(i,t.account,r),null))}async getPath(e,t){var i=await this.db.get(u.P(e,t));return i?((i=Z.fromRaw(i)).wid=e,i.hash=t,i):null}hasPath(e,t){return this.db.has(u.P(e,t))}getHashes(){return this.db.keys({gte:u.p(P.NULL_HASH),lte:u.p(P.HIGH_HASH),parse:u.pp})}getOutpoints(){return this.db.keys({gte:u.o(P.NULL_HASH,0),lte:u.o(P.HIGH_HASH,4294967295),parse:e=>{var[e,t]=u.oo(e);return new m(e,t)}})}getWalletHashes(e){return this.db.keys({gte:u.P(e,P.NULL_HASH),lte:u.P(e,P.HIGH_HASH),parse:u.Pp})}getAccountHashes(e,t){return this.db.keys({gte:u.r(e,t,P.NULL_HASH),lte:u.r(e,t,P.HIGH_HASH),parse:u.rr})}async getWalletPaths(e){var t=[];for(const s of await this.db.range({gte:u.P(e,P.NULL_HASH),lte:u.P(e,P.HIGH_HASH)})){var i=u.Pp(s.key),r=Z.fromRaw(s.value);r.hash=i,r.wid=e,t.push(r)}return t}async encryptKeys(e,t){var i,r,n=e.wid,a=await e.getPaths(),o=this.batch(e);for(i of a)i.data&&(s(!i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.encipher(i.data,t,r),i.encrypted=!0,e.pathCache.push(i.hash,i),o.put(u.P(n,i.hash),i.toRaw()))}async decryptKeys(e,t){var i,r,n=e.wid,a=await e.getPaths(),o=this.batch(e);for(i of a)i.data&&(s(i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.decipher(i.data,t,r),i.encrypted=!1,e.pathCache.push(i.hash,i),o.put(u.P(n,i.hash),i.toRaw()))}async resend(){var e,t={};for(const e of await this.db.keys({gte:u.w(0),lte:u.w(4294967295)})){var i=u.ww(e),r=await this.resendPending(i);r&&Array.isArray(r)&&(t[i]=r)}for(e of Object.keys(t))if(await this.get(parseInt(e)))for(const i of t[e]){try{await this.send(i)}catch(e){this.logger.warning("wdb resend:",e.message)}await ne.timeout(50)}}async resendPending(e){var t=await this.get(e),i=await this.db.keys({gte:h.txdb.prefix(e,h.txdb.p(P.NULL_HASH)),lte:h.txdb.prefix(e,h.txdb.p(P.HIGH_HASH))});if(0!==i.length){this.logger.info("Rebroadcasting %d transactions for %d.",i.length,e);var r=[];for(const o of i){var s=h.txdb.pp(o),n=h.txdb.prefix(e,h.txdb.t(s));if((n=await this.db.get(n))&&!(n=re.fromRaw(n)).tx.isCoinbase())try{var a=await b.FactoryOfContract({tx:n.tx,env:this});await a.isBlockFinal()==w.Expired?t&&(await this.removeTX(n.tx),await t.remove(s),await a.erase()):"notify"!=a.oper&&r.push(n.tx)}catch(e){this.logger.error("TX(%s) Smart Contract Error: %s",n.tx.txid(),e.message)}}return A(r)}}getWallets(){return this.db.keys({gte:u.l("\0"),lte:u.l("ÿ"),parse:u.ll})}async getWalletsByTX(e){var t=new Set;if(!e.isCoinbase())for(const r of e.inputs){var i=r.prevout;if(this.testFilter(i.toRaw())&&(i=await this.getOutpointMap(i.hash,i.index)))for(const e of i.wids)t.add(e)}for(const i of e.getOutputHashes("hex"))if(this.testFilter(i)){var r=await this.getPathMap(i);if(r)for(const e of r.wids)t.add(e)}return 0===t.size?null:t}async getState(){var e=await this.db.get(u.R);return e?Q.fromRaw(e):null}async init(e){var t=this.options.startHeight;let i;if(this.client){if(null!=t){if(!(i=await this.client.getEntry(t)))throw new Error("WDB: Could not find start block.")}else i=await this.client.getTip();i=te.fromEntry(i)}else i=te.fromEntry(this.network.genesis);this.logger.info("Initializing AccountDB chain state (height %d).",i.height),(t=await this.getState())?this.state=t:await this.resetState(i,!1),await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),e&&e.backup&&await this.loadBackup(e.backup)}async resetState(e,t){for(var i=this.state.clone(),r=(i.startHeight=e.height,i.startHash=e.hash,i.height=e.height,i.marked=t,this.db.batch()),s=this.db.iterator({gte:u.h(e.height),lte:u.h(4294967295),values:!1});;){var n=await s.next();if(!n)break;try{r.del(n.key)}catch(e){throw await s.end(),e}}r.put(u.h(e.height),e.toHash()),r.put(u.R,i.toRaw()),await r.write(),this.state=i}async syncState(e){var t=this.state.clone(),i=this.db.batch();if(e.height<t.height){let s=t.height;var r=s-e.height;for(let e=0;e<r;e++)i.del(u.h(s--))}else e.height>t.height&&s(e.height===t.height+1,`Bad chain sync tip ${e.height} while state `+t.height);t.height=e.height,i.put(u.h(e.height),e.toHash()),i.put(u.R,t.toRaw()),await i.write(),this.state=t,V("block/tips",t)}get curHeight(){return this.state.height}get tidCreator(){return h.txdb.tx}get finder(){return this.getTXFromDb.bind(this)}rpcExecute(){return this.rpc.execute.apply(this.rpc,arguments)}async getBlockMap(e){var t=await this.db.get(u.b(e));return t?ee.fromRaw(e,t):null}writeBlockMap(e,t,i){this.batch(e).put(u.b(t),i.toRaw())}unwriteBlockMap(e,t){this.batch(e).del(u.b(t))}async getOutpointMap(e,t){var i=await this.db.get(u.o(e,t));return i?J.fromRaw(e,t,i):null}writeOutpointMap(e,t,i,r){e=this.batch(e),this.addOutpoint(t,i),e.put(u.o(t,i),r.toRaw())}unwriteOutpointMap(e,t,i){this.batch(e).del(u.o(t,i))}async writeBalanceLog(e,t){var i=u.log(e.wid,t.aidx,t.height,t.hash),r=(t=Buffer.from(JSON.stringify(t)),await this.writeLock.lock());try{this.start(e).put(i,t),await this.commit(e)}finally{r()}}async queryBalanceLog(e,t,i=0){return this.db.values({gte:u.log(e,t,i,P.NULL_HASH),lte:u.log(e,t,this.curHeight,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async getBlock(e){var t,i=await this.db.get(u.h(e));return i?((t=new te).hash=i.toString("hex"),t.height=e,t):null}async getTip(){var e=await this.getBlock(this.curHeight);if(e)return e;throw new Error("WDB: Tip not found!")}async rollback(e,t=!0){if(e>this.curHeight)throw new Error("WDB: Cannot rollback to the future.");if(e===this.curHeight)return this.logger.debug("Rolled back to same height (%d).",e),!0;this.logger.info("Rolling back %d AccountDB blocks to height %d.",this.curHeight-e,e);var i=await this.getBlock(e);let r=!1;return i?(await this.revert(i.height),await this.syncState(i),t):(i=new te,e>=this.state.startHeight?(i.height=this.state.startHeight,i.hash=this.state.startHash,r=this.state.marked,this.logger.warning("Rolling back AccountDB to start block (%d).",i.height)):(i.height=0,i.hash=this.network.genesis.hash,r=!1,this.logger.warning("Rolling back AccountDB to genesis block.")),await this.revert(i.height),await this.resetState(i,r),!1)}async revert(e){var t=this.db.iterator({gte:u.b(e+1),lte:u.b(4294967295),reverse:!0,values:!0});let i=0;for(;;){var r=await t.next();if(!r)break;try{var s=u.bb(r.key),n=ee.fromRaw(s,r.value).toArray();i+=n.length;for(let e=n.length-1;0<=e;e--)await this._unconfirm(n[e])}catch(e){throw await t.end(),e}}this.logger.info("Rolled back %d AccountDB transactions.",i)}async addBlock(e,t){var i=await this.txLock.lock();try{return await this._addBlock(e,t)}finally{i()}}async _addBlock(e,t){var i=te.fromEntry(e);let r=0;if(i.height<this.curHeight)this.logger.warning("AccountDB is connecting low blocks (%d).",i.height);else{if(i.height===this.curHeight)this.logger.warning("Already saw AccountDB block (%d).",i.height);else if(i.height!==this.curHeight+1)throw new Error(`WDB(addBlock): Bad disconnection (height mismatch, tip ${i.height} while state ${this.curHeight})`);if(await this.syncState(i),await this.propList.save(),!(this.options.checkpoints&&i.height<=this.network.lastCheckpoint)){for(const e of t)await this._insert(e,i)&&r++;0<r&&this.logger.info("Connected AccountDB block %s (tx=%d).",R.revHex(i.hash),r)}}return r}async removeBlock(e,t){var i=await this.txLock.lock();try{return await this._removeBlock(e,t)}finally{i()}}async _removeBlock(e,t){if((e=te.fromEntry(e)).height>this.curHeight)return this.logger.warning("AccountDB is disconnecting high blocks (%d).",e.height),0;if(e.height!==this.curHeight)throw new Error(`WDB(removeBlock): Bad disconnection (height mismatch, tip ${e.height} / ${R.revHex(e.hash)} while state ${this.curHeight})`);var i=await this.getBlock(e.height-1);if(!i)throw new Error(`WDB(removeBlock): Bad disconnection (no previous block of ${e.height} / ${R.revHex(e.hash)}).`);var r=await this.getBlockMap(e.height);if(r){for(let e=t.length-1;0<=e;e--){var s=t[e];await this._unconfirm(s,r)}this.logger.warning("Disconnected wallet block %s (tx=%d).",R.revHex(e.hash),r.txs.size)}return await this.syncState(i),await this.propList.save(),r?r.txs.size:0}async rescanBlock(e,t){if(this.rescanning){var i=await this.scanLock.lock();try{await this._addBlock(e,t)}catch(e){throw this.emit("error",e),e}finally{i()}}else this.logger.warning("Unsolicited rescan block: %s.",e.height)}async addTX(e,t,i){var r=await this.txLock.lock();try{return await this._insert(e,t,i)}finally{r()}}listNotify(e){return this.NotifyList.deletes([["h","<",this.curHeight-12]]),this.NotifyList.query(e)}listContact(e,t,i){return this.$contacts.query(e,t,i)}async setCp(e){await this.batchPut(h.txdb.cp(e.cid),e.toRaw())}async delCp(e){await this.batchDel(h.txdb.cp(e))}async delVp(e){var t=this.db.batch();t.del(h.txdb.VP(e.pid)),await t.write()}async setVp(e,t){var i=this.db.batch();i.put(h.txdb.VP(e.pid),e.toRaw()),await i.write()}async getVp(e){return(e=await this.db.get(h.txdb.VP(e)))?W.fromRaw(e):null}async getVpByAddress(e){return{list:[],count:0}}async getVpByOid(e){return{list:[],count:0}}async loadVpList(){return this.db.values({gte:h.txdb.VP(P.ZERO_CID,"hex"),lte:h.txdb.VP(P.MAX_CID,"hex"),parse:e=>W.fromRaw(e)})}async saveContact(e){var t=this.db.batch();t.put(h.txdb.CT(e.getAddress()),e.toRaw()),await t.write()}async loadContact(e){var t;for(t of await this.db.values({gte:h.txdb.CT(P.ZERO_HASH160_HEX),lte:h.txdb.CT(P.MAX_HASH160_HEX),parse:e=>S.fromRaw(e,this)}))t.sender&&(t.sender.wallet=await this.get(t.sender.wid)),this.$contacts.set(t.address,t)}async delHtlc(e){var t;(e=new L(e)).id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(h.txdb.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new L(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.aa)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.ba));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(h.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new L(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.ab)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.bb));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(h.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:h.txdb.VH(P.ZERO_CID,0),lte:h.txdb.VH(P.MAX_CID,4294967295),parse:e=>L.fromRaw(e)})}async delComment(e){var t;(e=new z(e)).id&&(this.commentList.delete(e.id),this.commentList.delAccount(e),(t=this.db.batch()).del(h.txdb.VC(e.shash,e.sidx)),await t.write())}async setComment(e){e=new z(e);var t,[t,i]=(this.commentList.set(e.id,e),await this.getAccountByAddress(e.bob));(t=(t&&(this.commentList.setAccount(e,t,i),this.emit("comm.comment",e)),this.db.batch())).put(h.txdb.VC(e.shash,e.sidx),e.toRaw()),await t.write()}async loadCommentList(){return this.db.values({gte:h.txdb.VC(P.ZERO_CID,0),lte:h.txdb.VC(P.MAX_CID,4294967295),parse:e=>z.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(h.txdb.ER(e.erid)),t.del(h.txdb.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){t&&e.source&&(i=g.fromWitnessPubkeyhash(l.hash160(Buffer.from(e.source.pubkey,"hex")),this.network),[i,t]=await this.getAccountByAddress(i,t),e.wid=i,e.account=t);var i=this.db.batch();t=h.txdb.ERR(e.witness,e.erid,e.txid);i.put(t,e.toRaw()),i.put(h.txdb.ER(e.erid),t),await i.write()}async getEr(e){var t;return(e=await this.db.get(h.txdb.ER(e)))&&([,,t]=h.txdb.ERRR(e),e=await this.db.get(e))?((e=X.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){var r,s=new _;e=await this.db.values({gte:h.txdb.ERR(e,P.NULL_HASH,P.NULL_HASH),lte:h.txdb.ERR(e,P.HIGH_HASH,P.HIGH_HASH),parse:e=>X.fromRaw(e)});let n=[],a=new Map;if(i){for(var o of e)(!a.get(o.source.cluster)||o.startHeight>a.get(o.source.cluster).startHeight)&&a.set(o.source.cluster,await this.caVerifyObj(o));n=a.values()}else n=e;for(r of n)s.set(r.erid,r);return s.query(t)}async caVerifyObj(e){var t={verify:!1};if(!e||e.validHeight<=this.curHeight)return t;var i=await this.erAbList.getErAb(e.erid);return i&&i.abolishHeight<this.curHeight?t:(i=se.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verify(i)?(e.verify=!0,0<(i=this.cpList.query([["pubKey",e.witness]])).list.length&&(e.cpid=i.list[0].cid),e):t)}async delErAbolish(e){var t=this.db.batch();t.del(h.txdb.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(h.txdb.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(h.txdb.ERA(e)))?q.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:h.txdb.ERA(P.ZERO_CID),lte:h.txdb.ERA(P.MAX_CID),parse:e=>q.fromRaw(e)})}async delAudit(e){var t=this.db.batch();t.del(h.txdb.AU(e.erid)),await t.write()}async setAudit(e){var t=this.db.batch();t.put(h.txdb.AU(e.erid),e.toRaw()),await t.write()}async getAudit(e){return(e=await this.db.get(h.txdb.AU(e)))?Y.fromRaw(e):null}async loadAuditList(){return this.db.values({gte:h.txdb.AU(P.NULL_HASH),lte:h.txdb.AU(P.HIGH_HASH),parse:e=>Y.fromRaw(e)})}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}async _insert(e,t,i){s(!e.mutable,"WDB: Cannot add mutable TX.");let r=await this.getWalletsByTX(e);if(r){this.logger.info("Incoming transaction for %d wallets in AccountDB (%s).",r.size,e.txid()),!t||this.state.marked||(this.logger.info("Marking AccountDB start block at %s (%d).",R.revHex(t.hash),t.height),await this.resetState(t,!0));let a=!1;for(const o of r){var n=await this.get(o);s(n),await n.add(e,t,i)&&(this.logger.info("Added transaction to wallet in AccountDB: %s (%d).",n.id,o),a=!0)}a||(r=null)}try{var a=await b.FactoryOfContract({env:this,block:t,tx:e});t?await a.confirm():await a.insert()}catch(a){t?this.logger.error("TX(%s) Smart Contract Confirm Error: %s",e.txid(),a.message):this.logger.error("TX(%s) Smart Contract Insert Error: %s",e.txid(),a.message)}return r}async _unconfirm(e,t){if(t)try{await(await b.FactoryOfContract({env:this,block:t,tx:e})).unconfirm()}catch(t){this.logger.error("TX(%s) Smart Contract Unconfirm Error: %s",e.txid(),t.message)}let i,r=null;if(i=e.wids?(r=e.wids,e.hash):(r=await this.getWalletsByTX(e),e.hash("hex")),!r)return null;for(const e of r){var n=await this.get(e);s(n),await n.unconfirm(i)}}async resetChain(e){var t=await this.txLock.lock();try{return await this._resetChain(e)}finally{t()}}async _resetChain(e){if(e.height>this.curHeight)throw new Error(`WDB: Bad reset height ${e.height} while curHeight `+this.curHeight);var t;for(t of(await this.rollback(e.height)||await this._rescan(),await this.getWallets())){var i=await this.get(t);for(const t of await i.getPending())try{await i.abandon(t.hash)}catch(e){}}}async saveMSTrans(e){var t=await this.writeLock.lock();try{return await this._saveMSTrans(e)}finally{t()}}async _saveMSTrans(e){var t=this.db.batch();t.put(u.ms(g.getHash(e.addr,"hex"),e.txid),Buffer.from(JSON.stringify(e))),await t.write()}async listMSTrans(e){return e=g.getHash(e,"hex"),this.db.values({gte:u.ms(e,P.NULL_HASH),lte:u.ms(e,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async delMSTrans(e,t){var i=await this.writeLock.lock();try{return await this._delMSTrans(e,t)}finally{i()}}async _delMSTrans(e,t){e=g.getHash(e,"hex");var i=this.db.batch();i.del(u.ms(e,t)),await i.write()}}ue.layout=u,e.exports=ue},function(e,t,i){"use strict";
|
|
907
|
+
*/const r=i(8),s=i(0),n=i(73),a=i(119),o=i(157),c=i(610),h=i(85),u=h.walletdb,l=i(6),p=i(158),d=i(125),f=i(167);var{}=i(32);const m=i(45),g=i(13);i(20),i(69);const y=i(197),v=i(68),b=i(50),{BlockFinalType:w,ContractEnvType:k}=i(5),x=i(159),S=i(612),_=i(37);var E=i(72);const R=i(2),A=i(141).sortWithSeq,O=i(35),C=i(198),I=i(64),j=i(100),P=i(3),T=P.U32,B=i(338),N=i(339),M=i(340),L=M.vpItem,F=i(617),z=F.vpItem,H=i(312);i(618);const D=H.cpItem,U=i(154),q=U.ErAbolishItem,V=i(38).broadcast,K=i(132),W=K.vpItem,$=i(153),X=$.ErItem,G=i(619),Y=G.AuditItem,J=i(305),Z=i(109),Q=i(620),ee=i(306),te=i(120),ie=i(621),re=i(217),se=i(39),ne=i(36),ae=i(59),oe=i(78),ce=oe.errors,he=i(77);class ue extends E{constructor(e){super(),this.readyLoad=!1,this.options=new c(e),this.network=this.options.network,this.logger=this.options.logger.context("wallet"),this.workers=this.options.workers,this.keys={hmacSalt:P.DefaultChainCode},e.keys&&e.keys.hmacSalt&&(s(Buffer.isBuffer(e.keys.hmacSalt)),this.keys.hmacSalt=e.keys.hmacSalt),this.client=this.options.client,this.client&&(this.client.wdb=this),this.jsonp=this.options.jsonp,this.jsonp&&(this.jsonp.wdb=this),this.spv=this.options.spv,this.feeRate=this.options.feeRate,this.db=f(this.options),this.rpc=new B(this),this.primary=null,this.state=new Q,this.wallets=new Map,this.depth=0,this.rescanning=!1,this.bound=!1,this.newRecord=!0,this.readLock=new C,this.writeLock=new O,this.txLock=new O,this.scanLock=new O,this.widCache=new I(1e4),this.pathMapCache=new I(1e5),this.filter=new j,this.middleHashMem=new Set,this.middleHashChain=new Set,this.autoTaskMgr=new x(this),this.transactionList=new N(this),this.htlcList=new M(this),this.commentList=new F(this),this.NotifyList=new _,this.propList=new K(this),this.$contacts=new _,this.cpList=new H(this),this.cpMemList=new H(this),this.auditList=new G(this),this.erList=new $(this),this.erAbList=new U(this),this.hmacConnection=[],this._init()}async logAudit(e){e.height=this.curHeight,e.time=R.now(),e.erid=l.sha256(R.stringify(e)).toString("hex"),e=new Y(e),await this.auditList.setAudit(e)}async getAccountByAddress(e,t){if(e){let s=null;if(s=t?await this.getWalletsByTX(t):await this.getWallets())for(const t of s){var i=await this.get(t);if(i){var r=await i.getPath(e);if(r)return[i.wid,r.name,i.id]}}}return[0,"",""]}_init(){let e=1e6,t=-1;this.spv&&(e=2e4,t=j.flags.ALL),this.filter=j.fromRate(e,.001,t)}get mode(){return k.Wallet}async getTXFromAll(e){return this.getTXFromDb(e)}async checkNewRecord(){var e={createIfMissing:this.db.options.createIfMissing,errorIfExists:this.db.options.errorIfExists};this.db.options.createIfMissing=!1,this.db.options.errorIfExists=!0;try{await this.db.open();var t=await this.db.checkVersion(u,6);this.newRecord="new"==t}catch(e){if(-1!=e.message.indexOf("does not exist (create_if_missing is false)"))this.newRecord=!0;else{if(-1==e.message.indexOf("exists (error_if_exists is true)"))throw e;this.newRecord=!1}}try{await this.db.close()}catch(e){}this.db.options.createIfMissing=e.createIfMissing,this.db.options.errorIfExists=e.errorIfExists}async isNewRecord(){return await this.checkNewRecord(),this.newRecord}setmnemonic(e){if(this.options.mnemonic=this.options.mnemonic||{},e.bits)this.options.mnemonic={bits:e.bits};else if(e.entropy)this.options.mnemonic={entropy:Buffer.from(e.entropy,"hex")};else if(e.phrase){var t=this.testmnemonic(e.phrase);if(0!=t.code)throw t.msg;this.options.mnemonic={phrase:e.phrase}}e.passphrase&&(this.options.mnemonic.passphrase=e.passphrase),e.language&&(this.options.mnemonic.language=e.language)}testmnemonic(e){try{return new y(e),{code:0}}catch(e){return{code:-1,msg:e.message}}}async getContracts(e){var t=await this.db.values({gte:h.txdb.tx(P.NULL_HASH),lte:h.txdb.tx(P.HIGH_HASH),parse:e=>R.parseJson(e.toString())});return e?t.filter(t=>t.srcact==e||t.dstact==e):t}isFull(){return this.spv||this.synced||!1}async _open(e){}async handleNotify(e,t=!1){if(!t){let i=e.body.content;if("string"==typeof i)try{i=JSON.parse(e.body.content)}catch(e){return}"object"==typeof i&&"secret"===i.type&&(t={contact:e.body.src,messenger:e.body.dst},i.init&&(t.init=Buffer.from(i.init,"hex")),i.packet&&(t.packet=Buffer.from(i.packet)),await this.handleSecret(t))}}async handleSecret(e){if(e.contact&&e.messenger&&e.contact!=e.messenger){try{g.fromString(e.contact,this.network.type),g.fromString(e.messenger,this.network.type)}catch(e){return}var t=await this.ensureContact(e);t&&await t.ensureMessenger(e).answer(e)}}async scanContact(e,t=-1){var i=async e=>{var t;e.witness&&"witnesspubkeyhash"==e.getType()&&(t=e.witness.getPubkeyhashInput()[1],e=g.fromWitness(e.witness).toString(),t)&&e&&await this.ensureContact({contact:e,publicKey:t})};if(0<=t&&t<e.inputs.length)await i(e.inputs[t]);else for(var r of e.inputs)await i(r)}async ensureContact(e){if(!e.contact||e.contact==e.messenger)return null;try{g.fromString(e.contact,this.network.type),e.messenger&&g.fromString(e.messenger,this.network.type)}catch(e){return null}e.network=this.network.type,this.$contacts.get(e.contact)||this.$contacts.set(e.contact,new S(e));var t=this.$contacts.get(e.contact);if(e.messenger&&!(e=t.ensureMessenger(e)).wallet){var i,[i,r]=await this.getAccountByAddress(e.address);if(!(i=await this.get(i)))return;e.wallet=i,e.account=r}return t}getCps(){return this.db.values({gte:h.txdb.cp(P.ZERO_CID,"hex"),lte:h.txdb.cp(P.MAX_CID,"hex"),parse:e=>D.fromRaw(e)})}async _close(){await this.disconnect(),this.http&&this.options.listen&&await this.http.close();for(const e of this.wallets.values())await e.destroy();await this.db.close(),this.options.listen&&await this.logger.close()}async destroy(){await this.db.destroy(),this.widCache.reset(),this.pathMapCache.reset()}async load(e){if(this.readyLoad){var t=await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),i=await this.txLock.lock();try{await this.init(e),await this.watch(),await t.createReceive(0,1,t.master,this.network.type),await t.ensureNotifyKey(),await this.sync()}finally{i()}setTimeout(()=>{this.resend()},5e3)}}async disconnect(){this.client&&await this.client._close(),this.jsonp&&await this.jsonp._close()}async flushCP(e,t=!1){this.client&&(e=e||[],t||(e=this.cpList.excludeCids(e),t=t||0<e.length),t)&&await this.client.execute("cp.remoteQuery",[[["cid","include",e]]])}async watch(){let e=this.db.iterator({gte:u.p(P.NULL_HASH),lte:u.p(P.HIGH_HASH)}),t=0,i=0;for(;;){var r=await e.next();if(!r)break;try{var s=u.pp(r.key);this.addHash(s,!1)}catch(t){throw await e.end(),t}t++}for(e=this.db.iterator({gte:u.o(P.NULL_HASH,0),lte:u.o(P.HIGH_HASH,4294967295)});;){var n=await e.next();if(!n)break;try{var[a,o]=u.oo(n.key);this.addOutpoint(a,o)}catch(t){throw await e.end(),t}i++}this.logger.info("Filter: Added %d hashes to AccountDB filter.",t),this.logger.info("Filter: Added %d outpoints to AccountDB filter.",i),await this.setFilter()}async sync(){if(this.client){let t,i=this.curHeight;for(;0<=i;){var e=await this.getBlock(i);if(!e)break;if(t=await this.client.getEntry(e.hash))break;i--}t||(i=this.state.startHeight,t=await this.client.getEntry(this.state.startHash))||(i=0),await this.cpList.loadHistory(),await this.cpMemList.loadHistory(),await this.propList.loadHistory(),await this.htlcList.loadHistory(),await this.commentList.loadHistory(),await this.transactionList.loadHistory(),await this.loadContact(),await this.erList.loadHistory(),await this.auditList.loadHistory(),await this.erAbList.loadHistory(),await this._rescan(i,!1)}}async _rescan(e,t=!0){if(this.client){null==e&&(e=this.state.startHeight),s(e>>>0===e,"WDB: Must pass in a height.");var i=this.curHeight;t=(await this.rollback(e,t),this.logger.info("AccountDB is scanning %d blocks.",i-e+1),await this.getTip());try{this.rescanning=!0,await this.client.rescan(t.hash,this.eid)}finally{this.rescanning=!1}}}async rescan(e){var t=await this.txLock.lock();try{return await this._rescan(e,!1)}finally{t()}}async send(e){return this.client?this.client.send(e):(this.emit("send",e),Promise.resolve())}async getTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getTXFromDb(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t.tx}return null}async getExtendTX(e){for(const i of this.wallets.values()){var t=await i.getTX(e);if(t)return t}return null}async removeTX(e){this.client?await this.client.removeTX(e):this.emit("remove",e)}async estimateFee(e){return 0<this.feeRate?this.feeRate:!this.client||(e=await this.client.estimateFee(e))<this.network.feeRate?this.network.feeRate:e>this.network.maxFeeRate?this.network.maxFeeRate:e}setFilter(){return this.client?this.client.setFilter(this.filter):(this.emit("filter.set",this.filter),Promise.resolve())}resetFilter(){return this.client?this.client.resetFilter():(this.emit("filter.reset"),Promise.resolve())}backup(e){return this.db.backup(e)}async wipe(){this.logger.warning("Wiping AccountDB TXDB..."),this.logger.warning("I hope you know what you're doing.");var e=this.db.iterator({gte:Buffer.from([0]),lte:Buffer.from([255])}),t=this.db.batch();let i=0;for(;;){var r=await e.next();if(!r)break;try{switch(r.key[0]){case 98:case 99:case 101:case 116:case 111:case 104:case 82:t.del(r.key),i++}}catch(t){throw await e.end(),t}}this.logger.warning("Wiped %d txdb records.",i),await t.write()}async getDepth(){var e=this.db.iterator({gte:u.w(0),lte:u.w(4294967295),reverse:!0,limit:1}),t=await e.next();return t?(await e.end(),u.ww(t.key)+1):1}start(e){return s(!e.current,"WDB: Batch already started."),e.current=this.db.batch(),e.accountCache.start(),e.pathCache.start(),e.current}drop(e){var t=this.batch(e);e.current=null,e.accountCache.drop(),e.pathCache.drop(),t.clear()}clear(e){var t=this.batch(e);e.accountCache.clear(),e.pathCache.clear(),t.clear()}batch(e){return s(e.current,"WDB: Batch does not exist."),e.current}async commit(e){var t=this.batch(e);try{await t.write()}catch(e){throw this.drop(),e}e.current=null,e.accountCache.commit(),e.pathCache.commit()}testFilter(e){return this.filter.test(e,"hex")}addHash(e,t=!0){this.filter.add(e,"hex"),t&&(t=Buffer.from(e,"hex"),this.client?this.client.addFilter(t):this.emit("filter.add",t))}addOutpoint(e,t){e=new m(e,t),this.filter.add(e.toRaw())}dump(){return this.db.dump()}register(e){s(!this.wallets.has(e.wid)),this.wallets.set(e.wid,e)}unregister(e){s(this.wallets.has(e.wid)),this.wallets.delete(e.wid)}async getWalletID(e){var t;return e?"number"==typeof e?e:this.widCache.get(e)||((t=await this.db.get(u.l(e)))?(t=t.readUInt32LE(0,!0),this.widCache.set(e,t),t):null):null}async get(e){if(!(e=await this.getWalletID(e)))return null;var t=await this.readLock.lock(e);try{return await this._get(e)}finally{t()}}async _get(e){var t=this.wallets.get(e);return t||((t=await this.db.get(u.w(e)))?(await(e=a.fromRaw(this,t)).open(),this.register(e),e):null)}async loadBackup(e){if(ae.unsupported)throw new he(ce.INTERNAL_ERROR,"FS not available.");let t=null;var i;for(i of(await ae.readFile(e,"utf8")).split(/\n+/))if(0!==(i=i.trim()).length&&!/^\s*#/.test(i)){var r=i.split(/\s+/);if(r.length<4)throw new he(ce.DESERIALIZATION_ERROR,"Malformed wallet Data File.");switch(r[0]){case"W":var n=Buffer.from(r[1],"base64");n=a.fromRaw(this,n);await this.replace(n),t=await this.get(n.id),this.logger.info("Import Wallet %s(%s)",t.id,t.wid);break;case"C":n=Buffer.from(r[1],"base64");(c=((h=o.fromRaw(this,n)).wallet=t,h.wid=t.wid,h.id=t.id,h.initialized=!0,h.watchOnly=t.watchOnly,h.receive=h.deriveReceive(h.receiveDepth-1),h.change=h.deriveChange(h.changeDepth-1),h.witness&&(h.nested=h.deriveNested(h.nestedDepth-1)),t.master.key.deriveAccount(44,h.accountIndex))).publicKey.toString("hex")!==h.accountKey.publicKey.toString("hex")&&s(c.publicKey.toString("hex")==h.accountKey.publicKey.toString("hex")),await t.saveAccount(h),this.logger.info("Import Account %s(%s)",h.name,h.accountIndex);break;case"A":var c=oe.parseSecret(r[1],this.network),h=parseInt(r[5]),u=parseInt(r[7]),l=parseInt(r[9]),p=r[11].trim();if(u<0||l<0)try{await t.importKey(h,c)}catch(e){this.logger.error(`loadBackup: ${e.message} account/secret: ${h}/`+p)}else{var d=await t.deriveKey(h,u,l),f=await t.deriveKey(h,u,l,t.master);d.getAddress("string")!==f.getAddress("string")&&this.logger.error(`loadBackup: not-equal-1: ${d.getAddress("string")} != `+f.getAddress("string")),d.getAddress("string")!==p&&this.logger.error(`loadBackup: not-equal-2: ${d.getAddress("string")} != `+p)}this.logger.info("Import Address %s %s %s %s",h,u,l,p)}}return t.accountCache.reset(),t}save(e){var t=e.wid,i=e.id,r=this.batch(e);this.widCache.set(i,t),r.put(u.w(t),e.toRaw()),r.put(u.l(i),T(t))}async rename(e,t){var i=await this.writeLock.lock();try{return await this._rename(e,t)}finally{i()}}async _rename(e,t){var i=e.id;if(!n.isName(t))throw new Error("WDB: Bad wallet ID.");if(await this.has(t))throw new Error("WDB: ID not available.");this.start(e).del(u.l(i)),e.id=t,this.save(e),await this.commit(e),this.widCache.remove(i),i=e.pathCache.values();for(const e of i)e.id=t}async replace(e){var t=await this.writeLock.lock();try{return await this._replace(e)}finally{t()}}async _replace(e){var t=this.start(e);t.del(u.l(e.id)),t.del(u.w(e.wid)),this.save(e),await this.commit(e),this.widCache.remove(e.id),this.wallets.delete(e.wid)}renameAccount(e,t){var i=e.wallet;this.batch(i).del(u.i(e.wid,e.name)),e.name=t,this.saveAccount(e)}async auth(e,t){if("string"==typeof t){if(!R.isHex256(t))throw new Error("WDB Authentication: Invalid Token.");t=Buffer.from(t,"hex")}e=v.getHmac(e.toString(),this.keys.hmacSalt);var i=r.createHmac("sha256",e.random);i=Buffer.from(i.update(e.token).digest("hex"),"hex");if(!p(t,i))throw new Error("WDB Authentication: CRC Error.")}async create(e){var t=await this.writeLock.lock();e=e||{};try{return await this._create(e)}finally{t()}}async _create(e){if(await this.has(e.id))throw new Error("WDB: Wallet already exists.");"string"==typeof e.mnemonic&&(e.mnemonic={phrase:e.mnemonic}),e.mnemonic=e.mnemonic||{},!e.mnemonic.language&&this.options.mnemonic&&this.options.mnemonic.language&&(e.mnemonic.language=this.options.mnemonic.language);var t=a.fromOptions(this,e);return t.wid=this.depth++,await t.init(e),this.register(t),this.logger.info("Created wallet %s in AccountDB.",t.id),t}async has(e){return null!=await this.getWalletID(e)}async ensure(e){return await this.get(e.id)||this.create(e)}async getAccount(e,t){return(e=await this.db.get(u.a(e,t)))?o.fromRaw(this,e):null}getAccounts(e){return this.db.values({gte:u.n(e,0),lte:u.n(e,4294967295),parse:e=>e.toString("ascii")})}async getAccountMap(e){for(var t={},i=this.db.iterator({gte:u.n(e,0),lte:u.n(e,4294967295),values:!0});;){var r=await i.next();if(!r)break;try{var[,s]=u.nn(r.key);t[s]=r.value.toString("ascii")}catch(e){throw await i.end(),e}}return t}async getAccountIndex(e,t){return(e=await this.db.get(u.i(e,t)))?e.readUInt32LE(0,!0):-1}async getAccountName(e,t){return(e=await this.db.get(u.n(e,t)))?e.toString("ascii"):null}saveAccount(e){var t=e.wid,i=e.wallet,r=e.accountIndex,s=e.name,n=this.batch(i);n.put(u.a(t,r),e.toRaw()),n.put(u.i(t,s),T(r)),n.put(u.n(t,r),Buffer.from(s,"ascii")),i.accountCache.push(r,e)}hasAccount(e,t){return"number"==typeof e&&"number"==typeof t&&this.db.has(u.a(e,t))}async getPathMap(e){var t=this.pathMapCache.get(e);return t||((t=await this.db.get(u.p(e)))?(t=ie.fromRaw(e,t),this.pathMapCache.set(e,t),t):null)}saveKey(e,t){return this.savePath(e,t.toPath())}async savePath(e,t){var i=e.wid,r=t.hash,s=this.batch(e);this.addHash(r);let n=await this.getPathMap(r);(n=n||new ie(r)).add(i)&&(this.pathMapCache.set(r,n),e.pathCache.push(r,t),s.put(u.p(r),n.toRaw()),s.put(u.P(i,r),t.toRaw()),s.put(u.r(i,t.account,r),null))}async getPath(e,t){var i=await this.db.get(u.P(e,t));return i?((i=Z.fromRaw(i)).wid=e,i.hash=t,i):null}hasPath(e,t){return this.db.has(u.P(e,t))}getHashes(){return this.db.keys({gte:u.p(P.NULL_HASH),lte:u.p(P.HIGH_HASH),parse:u.pp})}getOutpoints(){return this.db.keys({gte:u.o(P.NULL_HASH,0),lte:u.o(P.HIGH_HASH,4294967295),parse:e=>{var[e,t]=u.oo(e);return new m(e,t)}})}getWalletHashes(e){return this.db.keys({gte:u.P(e,P.NULL_HASH),lte:u.P(e,P.HIGH_HASH),parse:u.Pp})}getAccountHashes(e,t){return this.db.keys({gte:u.r(e,t,P.NULL_HASH),lte:u.r(e,t,P.HIGH_HASH),parse:u.rr})}async getWalletPaths(e){var t=[];for(const s of await this.db.range({gte:u.P(e,P.NULL_HASH),lte:u.P(e,P.HIGH_HASH)})){var i=u.Pp(s.key),r=Z.fromRaw(s.value);r.hash=i,r.wid=e,t.push(r)}return t}async encryptKeys(e,t){var i,r,n=e.wid,a=await e.getPaths(),o=this.batch(e);for(i of a)i.data&&(s(!i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.encipher(i.data,t,r),i.encrypted=!0,e.pathCache.push(i.hash,i),o.put(u.P(n,i.hash),i.toRaw()))}async decryptKeys(e,t){var i,r,n=e.wid,a=await e.getPaths(),o=this.batch(e);for(i of a)i.data&&(s(i.encrypted),r=Buffer.from(i.hash,"hex").slice(0,16),(i=i.clone()).data=d.decipher(i.data,t,r),i.encrypted=!1,e.pathCache.push(i.hash,i),o.put(u.P(n,i.hash),i.toRaw()))}async resend(){var e,t={};for(const e of await this.db.keys({gte:u.w(0),lte:u.w(4294967295)})){var i=u.ww(e),r=await this.resendPending(i);r&&Array.isArray(r)&&(t[i]=r)}for(e of Object.keys(t))if(await this.get(parseInt(e)))for(const i of t[e]){try{await this.send(i)}catch(e){this.logger.warning("wdb resend:",e.message)}await ne.timeout(50)}}async resendPending(e){var t=await this.get(e),i=await this.db.keys({gte:h.txdb.prefix(e,h.txdb.p(P.NULL_HASH)),lte:h.txdb.prefix(e,h.txdb.p(P.HIGH_HASH))});if(0!==i.length){this.logger.info("Rebroadcasting %d transactions for %d.",i.length,e);var r=[];for(const o of i){var s=h.txdb.pp(o),n=h.txdb.prefix(e,h.txdb.t(s));if((n=await this.db.get(n))&&!(n=re.fromRaw(n)).tx.isCoinbase())try{var a=await b.FactoryOfContract({tx:n.tx,env:this});await a.isBlockFinal()==w.Expired?t&&(await this.removeTX(n.tx),await t.remove(s),await a.erase()):"notify"!=a.oper&&r.push(n.tx)}catch(e){this.logger.error("TX(%s) Smart Contract Error: %s",n.tx.txid(),e.message)}}return A(r)}}getWallets(){return this.db.keys({gte:u.l("\0"),lte:u.l("ÿ"),parse:u.ll})}async getWalletsByTX(e){var t=new Set;if(!e.isCoinbase())for(const r of e.inputs){var i=r.prevout;if(this.testFilter(i.toRaw())&&(i=await this.getOutpointMap(i.hash,i.index)))for(const e of i.wids)t.add(e)}for(const i of e.getOutputHashes("hex"))if(this.testFilter(i)){var r=await this.getPathMap(i);if(r)for(const e of r.wids)t.add(e)}return 0===t.size?null:t}async getState(){var e=await this.db.get(u.R);return e?Q.fromRaw(e):null}async init(e){var t=this.options.startHeight;let i;if(this.client){if(null!=t){if(!(i=await this.client.getEntry(t)))throw new Error("WDB: Could not find start block.")}else i=await this.client.getTip();i=te.fromEntry(i)}else i=te.fromEntry(this.network.genesis);this.logger.info("Initializing AccountDB chain state (height %d).",i.height),(t=await this.getState())?this.state=t:await this.resetState(i,!1),await this.ensure({id:"primary",witness:!0,mnemonic:this.options.mnemonic}),e&&e.backup&&await this.loadBackup(e.backup)}async resetState(e,t){for(var i=this.state.clone(),r=(i.startHeight=e.height,i.startHash=e.hash,i.height=e.height,i.marked=t,this.db.batch()),s=this.db.iterator({gte:u.h(e.height),lte:u.h(4294967295),values:!1});;){var n=await s.next();if(!n)break;try{r.del(n.key)}catch(e){throw await s.end(),e}}r.put(u.h(e.height),e.toHash()),r.put(u.R,i.toRaw()),await r.write(),this.state=i}async syncState(e){var t=this.state.clone(),i=this.db.batch();if(e.height<t.height){let s=t.height;var r=s-e.height;for(let e=0;e<r;e++)i.del(u.h(s--))}else e.height>t.height&&s(e.height===t.height+1,`Bad chain sync tip ${e.height} while state `+t.height);t.height=e.height,i.put(u.h(e.height),e.toHash()),i.put(u.R,t.toRaw()),await i.write(),this.state=t,V("block/tips",t)}get curHeight(){return this.state.height}get tidCreator(){return h.txdb.tx}get finder(){return this.getTXFromDb.bind(this)}rpcExecute(){return this.rpc.execute.apply(this.rpc,arguments)}async getBlockMap(e){var t=await this.db.get(u.b(e));return t?ee.fromRaw(e,t):null}writeBlockMap(e,t,i){this.batch(e).put(u.b(t),i.toRaw())}unwriteBlockMap(e,t){this.batch(e).del(u.b(t))}async getOutpointMap(e,t){var i=await this.db.get(u.o(e,t));return i?J.fromRaw(e,t,i):null}writeOutpointMap(e,t,i,r){e=this.batch(e),this.addOutpoint(t,i),e.put(u.o(t,i),r.toRaw())}unwriteOutpointMap(e,t,i){this.batch(e).del(u.o(t,i))}async writeBalanceLog(e,t){var i=u.log(e.wid,t.aidx,t.height,t.hash),r=(t=Buffer.from(JSON.stringify(t)),await this.writeLock.lock());try{this.start(e).put(i,t),await this.commit(e)}finally{r()}}async queryBalanceLog(e,t,i=0){return this.db.values({gte:u.log(e,t,i,P.NULL_HASH),lte:u.log(e,t,this.curHeight,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async getBlock(e){var t,i=await this.db.get(u.h(e));return i?((t=new te).hash=i.toString("hex"),t.height=e,t):null}async getTip(){var e=await this.getBlock(this.curHeight);if(e)return e;throw new Error("WDB: Tip not found!")}async rollback(e,t=!0){if(e>this.curHeight)throw new Error("WDB: Cannot rollback to the future.");if(e===this.curHeight)return this.logger.debug("Rolled back to same height (%d).",e),!0;this.logger.info("Rolling back %d AccountDB blocks to height %d.",this.curHeight-e,e);var i=await this.getBlock(e);let r=!1;return i?(await this.revert(i.height),await this.syncState(i),t):(i=new te,e>=this.state.startHeight?(i.height=this.state.startHeight,i.hash=this.state.startHash,r=this.state.marked,this.logger.warning("Rolling back AccountDB to start block (%d).",i.height)):(i.height=0,i.hash=this.network.genesis.hash,r=!1,this.logger.warning("Rolling back AccountDB to genesis block.")),await this.revert(i.height),await this.resetState(i,r),!1)}async revert(e){var t=this.db.iterator({gte:u.b(e+1),lte:u.b(4294967295),reverse:!0,values:!0});let i=0;for(;;){var r=await t.next();if(!r)break;try{var s=u.bb(r.key),n=ee.fromRaw(s,r.value),a=n.toArray();i+=a.length;for(let e=a.length-1;0<=e;e--){var o=await this.getTX(a[e].hash);o&&await this._unconfirm(o,n)}}catch(e){throw await t.end(),e}}this.logger.info("Rolled back %d AccountDB transactions.",i)}async addBlock(e,t){var i=await this.txLock.lock();try{return await this._addBlock(e,t)}finally{i()}}async _addBlock(e,t){var i=te.fromEntry(e);let r=0;if(i.height<this.curHeight)this.logger.warning("AccountDB is connecting low blocks (%d).",i.height);else{if(i.height===this.curHeight)this.logger.warning("Already saw AccountDB block (%d).",i.height);else if(i.height!==this.curHeight+1)throw new Error(`WDB(addBlock): Bad disconnection (height mismatch, tip ${i.height} while state ${this.curHeight})`);if(await this.syncState(i),await this.propList.save(),!(this.options.checkpoints&&i.height<=this.network.lastCheckpoint)){for(const e of t)await this._insert(e,i)&&r++;0<r&&this.logger.info("Connected AccountDB block %s (tx=%d).",R.revHex(i.hash),r)}}return r}async removeBlock(e,t){var i=await this.txLock.lock();try{return await this._removeBlock(e,t)}finally{i()}}async _removeBlock(e,t){if((e=te.fromEntry(e)).height>this.curHeight)return this.logger.warning("AccountDB is disconnecting high blocks (%d).",e.height),0;if(e.height!==this.curHeight)throw new Error(`WDB(removeBlock): Bad disconnection (height mismatch, tip ${e.height} / ${R.revHex(e.hash)} while state ${this.curHeight})`);var i=await this.getBlock(e.height-1);if(!i)throw new Error(`WDB(removeBlock): Bad disconnection (no previous block of ${e.height} / ${R.revHex(e.hash)}).`);var r=await this.getBlockMap(e.height);if(r){for(let e=t.length-1;0<=e;e--)await this._unconfirm(t[e],r);this.logger.warning("Disconnected wallet block %s (tx=%d).",R.revHex(e.hash),r.txs.size)}return await this.syncState(i),await this.propList.save(),r?r.txs.size:0}async rescanBlock(e,t){if(this.rescanning){var i=await this.scanLock.lock();try{await this._addBlock(e,t)}catch(e){throw this.emit("error",e),e}finally{i()}}else this.logger.warning("Unsolicited rescan block: %s.",e.height)}async addTX(e,t,i){var r=await this.txLock.lock();try{return await this._insert(e,t,i)}finally{r()}}listNotify(e){return this.NotifyList.deletes([["h","<",this.curHeight-12]]),this.NotifyList.query(e)}listContact(e,t,i){return this.$contacts.query(e,t,i)}async setCp(e){await this.batchPut(h.txdb.cp(e.cid),e.toRaw())}async delCp(e){await this.batchDel(h.txdb.cp(e))}async delVp(e){var t=this.db.batch();t.del(h.txdb.VP(e.pid)),await t.write()}async setVp(e,t){var i=this.db.batch();i.put(h.txdb.VP(e.pid),e.toRaw()),await i.write()}async getVp(e){return(e=await this.db.get(h.txdb.VP(e)))?W.fromRaw(e):null}async getVpByAddress(e){return{list:[],count:0}}async getVpByOid(e){return{list:[],count:0}}async loadVpList(){return this.db.values({gte:h.txdb.VP(P.ZERO_CID,"hex"),lte:h.txdb.VP(P.MAX_CID,"hex"),parse:e=>W.fromRaw(e)})}async saveContact(e){var t=this.db.batch();t.put(h.txdb.CT(e.getAddress()),e.toRaw()),await t.write()}async loadContact(e){var t;for(t of await this.db.values({gte:h.txdb.CT(P.ZERO_HASH160_HEX),lte:h.txdb.CT(P.MAX_HASH160_HEX),parse:e=>S.fromRaw(e,this)}))t.sender&&(t.sender.wallet=await this.get(t.sender.wid)),this.$contacts.set(t.address,t)}async delHtlc(e){var t;(e=new L(e)).id&&(this.htlcList.delete(e.id),this.htlcList.delAccount(e),(t=this.db.batch()).del(h.txdb.VH(e.shash,e.sidx)),await t.write())}async setSuggest(e){e=new L(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.aa)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.ba));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(h.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async setAssent(e){e=new L(e);var t,[t,i]=(this.htlcList.set(e.id,e),await this.getAccountByAddress(e.ab)),[t,i]=(t&&this.htlcList.setAccount(e,t,i),await this.getAccountByAddress(e.bb));(t=(t&&this.htlcList.setAccount(e,t,i),this.db.batch())).put(h.txdb.VH(e.shash,e.sidx),e.toRaw()),await t.write()}async loadHtlcList(){return this.db.values({gte:h.txdb.VH(P.ZERO_CID,0),lte:h.txdb.VH(P.MAX_CID,4294967295),parse:e=>L.fromRaw(e)})}async delComment(e){var t;(e=new z(e)).id&&(this.commentList.delete(e.id),this.commentList.delAccount(e),(t=this.db.batch()).del(h.txdb.VC(e.shash,e.sidx)),await t.write())}async setComment(e){e=new z(e);var t,[t,i]=(this.commentList.set(e.id,e),await this.getAccountByAddress(e.bob));(t=(t&&(this.commentList.setAccount(e,t,i),this.emit("comm.comment",e)),this.db.batch())).put(h.txdb.VC(e.shash,e.sidx),e.toRaw()),await t.write()}async loadCommentList(){return this.db.values({gte:h.txdb.VC(P.ZERO_CID,0),lte:h.txdb.VC(P.MAX_CID,4294967295),parse:e=>z.fromRaw(e)})}async delEr(e){var t=this.db.batch();t.del(h.txdb.ER(e.erid)),t.del(h.txdb.ERR(e.witness,e.erid,e.txid)),await t.write()}async setEr(e,t){t&&e.source&&(i=g.fromWitnessPubkeyhash(l.hash160(Buffer.from(e.source.pubkey,"hex")),this.network),[i,t]=await this.getAccountByAddress(i,t),e.wid=i,e.account=t);var i=this.db.batch();t=h.txdb.ERR(e.witness,e.erid,e.txid);i.put(t,e.toRaw()),i.put(h.txdb.ER(e.erid),t),await i.write()}async getEr(e){var t;return(e=await this.db.get(h.txdb.ER(e)))&&([,,t]=h.txdb.ERRR(e),e=await this.db.get(e))?((e=X.fromRaw(e)).txid=t,e):null}async byPubkey(e,t,i=!1){var r,s=new _;e=await this.db.values({gte:h.txdb.ERR(e,P.NULL_HASH,P.NULL_HASH),lte:h.txdb.ERR(e,P.HIGH_HASH,P.HIGH_HASH),parse:e=>X.fromRaw(e)});let n=[],a=new Map;if(i){for(var o of e)(!a.get(o.source.cluster)||o.startHeight>a.get(o.source.cluster).startHeight)&&a.set(o.source.cluster,await this.caVerifyObj(o));n=a.values()}else n=e;for(r of n)s.set(r.erid,r);return s.query(t)}async caVerifyObj(e){var t={verify:!1};if(!e||e.validHeight<=this.curHeight)return t;var i=await this.erAbList.getErAb(e.erid);return i&&i.abolishHeight<this.curHeight?t:(i=se.fromPublic(Buffer.from(e.witness,"hex"),this.network.type),e.verify(i)?(e.verify=!0,0<(i=this.cpList.query([["pubKey",e.witness]])).list.length&&(e.cpid=i.list[0].cid),e):t)}async delErAbolish(e){var t=this.db.batch();t.del(h.txdb.ERA(e.erid)),await t.write()}async setErAbolish(e){var t=this.db.batch();t.put(h.txdb.ERA(e.erid),e.toRaw()),await t.write()}async getErAbolish(e){return(e=await this.db.get(h.txdb.ERA(e)))?q.fromRaw(e):null}loadErAbolishList(){return this.db.values({gte:h.txdb.ERA(P.ZERO_CID),lte:h.txdb.ERA(P.MAX_CID),parse:e=>q.fromRaw(e)})}async delAudit(e){var t=this.db.batch();t.del(h.txdb.AU(e.erid)),await t.write()}async setAudit(e){var t=this.db.batch();t.put(h.txdb.AU(e.erid),e.toRaw()),await t.write()}async getAudit(e){return(e=await this.db.get(h.txdb.AU(e)))?Y.fromRaw(e):null}async loadAuditList(){return this.db.values({gte:h.txdb.AU(P.NULL_HASH),lte:h.txdb.AU(P.HIGH_HASH),parse:e=>Y.fromRaw(e)})}async batchPut(e,t){var i=this.db.batch();i.put(e,t),await i.write()}async batchDel(e){var t=this.db.batch();t.del(e),await t.write()}async _insert(e,t,i){s(!e.mutable,"WDB: Cannot add mutable TX.");let r=await this.getWalletsByTX(e);if(r){this.logger.info("Incoming transaction for %d wallets in AccountDB (%s).",r.size,e.txid()),!t||this.state.marked||(this.logger.info("Marking AccountDB start block at %s (%d).",R.revHex(t.hash),t.height),await this.resetState(t,!0));let a=!1;for(const o of r){var n=await this.get(o);s(n),await n.add(e,t,i)&&(this.logger.info("Added transaction to wallet in AccountDB: %s (%d).",n.id,o),a=!0)}a||(r=null)}try{var a=await b.FactoryOfContract({env:this,block:t,tx:e});t?await a.confirm():await a.insert()}catch(a){t?this.logger.error("TX(%s) Smart Contract Confirm Error: %s",e.txid(),a.message):this.logger.error("TX(%s) Smart Contract Insert Error: %s",e.txid(),a.message)}return r}async _unconfirm(e,t){if(t)try{await(await b.FactoryOfContract({env:this,block:t,tx:e})).unconfirm()}catch(e){this.logger.error("Smart Contract Unconfirm Error: %s",e.message)}var i=e.hash("hex");if(!(e=t.txs.get(i).wids))return null;for(const t of e){var r=await this.get(t);s(r),await r.unconfirm(i)}}async resetChain(e){var t=await this.txLock.lock();try{return await this._resetChain(e)}finally{t()}}async _resetChain(e){if(e.height>this.curHeight)throw new Error(`WDB: Bad reset height ${e.height} while curHeight `+this.curHeight);var t;for(t of(await this.rollback(e.height)||await this._rescan(),await this.getWallets())){var i=await this.get(t);for(const t of await i.getPending())try{await i.abandon(t.hash)}catch(e){}}}async saveMSTrans(e){var t=await this.writeLock.lock();try{return await this._saveMSTrans(e)}finally{t()}}async _saveMSTrans(e){var t=this.db.batch();t.put(u.ms(g.getHash(e.addr,"hex"),e.txid),Buffer.from(JSON.stringify(e))),await t.write()}async listMSTrans(e){return e=g.getHash(e,"hex"),this.db.values({gte:u.ms(e,P.NULL_HASH),lte:u.ms(e,P.HIGH_HASH),parse:e=>JSON.parse(e.toString())})}async delMSTrans(e,t){var i=await this.writeLock.lock();try{return await this._delMSTrans(e,t)}finally{i()}}async _delMSTrans(e,t){e=g.getHash(e,"hex");var i=this.db.batch();i.del(u.ms(e,t)),await i.write()}}ue.layout=u,e.exports=ue},function(e,t,i){"use strict";
|
|
908
908
|
/*!
|
|
909
909
|
* txdb.js - persistent transaction pool
|
|
910
910
|
* Copyright (c) 2019-2022, Bookman Software (MIT License).
|