import { common } from '@neo-one/client-common' ; import { ApplicationLog , BlockData , deserializeActionWire , DeserializeWireContext , FailedTransaction , Nep17Balance , Nep17BalanceKey , Nep17Transfer , Nep17TransferKey , Storage , StorageItem , StorageKey , TransactionData , } from '@neo-one/node-core' ; import { keys } from '@neo-one/node-storage-common' ; import { BN } from 'bn.js' ; import { LevelUp } from 'levelup' ; import { convertChange } from './convertChange' ; import * as read from './read' ; interface LevelUpStorageOptions { readonly db : LevelUp ; readonly context : DeserializeWireContext ; } export const levelUpStorage = ( { db , context } ) : Storage => { return { nep17Balances : read . createReadAllFindStorage ( { prefixSize : 4 , db , searchRange : keys . getAllNep17BalanceSearchRange , getSearchRange : keys . getNep17BalanceSearchRange , serializeKey : keys . createNep17BalanceKey , deserializeValue : ( buffer ) => Nep17Balance . deserializeWire ( { context , buffer } ) , deserializeKey : ( buffer ) => Nep17BalanceKey . deserializeWire ( { context , buffer } ) } ) , nep17TransfersReceived : read . createReadFindStorage ( { prefixSize : 4 , db , getSearchRange : keys . getNep17TransferReceivedSearchRange , serializeKey : keys . createNep17TransferReceivedKey , deserializeValue : ( buffer ) => Nep17Transfer . deserializeWire ( { context , buffer } ) , deserializeKey : ( buffer ) => Nep17TransferKey . deserializeWire ( { context , buffer } ) } ) , nep17TransfersSent : read . createReadFindStorage ( { prefixSize : 4 , db , getSearchRange : keys . getNep17TransferSentSearchRange , serializeKey : keys . createNep17TransferSentKey , deserializeValue : ( buffer ) => Nep17Transfer . deserializeWire ( { context , buffer } ) , deserializeKey : ( buffer ) => Nep17TransferKey . deserializeWire ( { context , buffer } ) } ) , applicationLogs : read . createReadStorage ( { db , serializeKey : keys . createApplicationLogKey , deserializeValue : ( buffer ) => ApplicationLog . deserializeWire ( { context , buffer } ) } ) , storages : read . createReadFindStorage ( { prefixSize : 0 , db , getSearchRange : keys . getStorageSearchRange , serializeKey : keys . createStorageKey , deserializeKey : ( buffer ) => StorageKey . deserializeWire ( { context , buffer } ) , deserializeValue : ( buffer ) => StorageItem . deserializeWire ( { context , buffer } ) } ) , blockData : read . createReadStorage ( { db , serializeKey : keys . createBlockDataKey , deserializeValue : ( buffer ) => BlockData . deserializeWire ( { context , buffer } ) } ) , transactionData : read . createReadStorage ( { db , serializeKey : keys . createTransactionDataKey , deserializeValue : ( buffer ) => TransactionData . deserializeWire ( { context , buffer } ) } ) , action : read . createReadAllFindStorage ( { prefixSize : 4 , db , searchRange : keys . getAllActionSearchRange , getSearchRange : keys . getActionSearchRange , serializeKey : keys . createActionKey , deserializeValue : ( buffer ) => deserializeActionWire ( { context , buffer } ) , deserializeKey : ( key ) => ( { index : new BN ( key ) } ) } ) , failedTransactions : read . createReadAllFindStorage ( { prefixSize : 4 , db , searchRange : keys . getAllFailedTransactionSearchRange , getSearchRange : keys . getFailedTransactionSearchRange , serializeKey : keys . createFailedTransactionKey , deserializeValue : ( buffer ) => FailedTransaction . deserializeWire ( { context , buffer } ) , deserializeKey : ( key ) => ( { hash : common . bufferToUInt256 ( key ) } ) } ) , async close ( ) { await db . close ( ) ; } , async commit ( changeSet ) { const changesList = changeSet . map ( convertChange ) ; const changes = changesList . reduce < any [ ] > ( ( acc , converted ) => { acc . push ( ... converted ) ; return acc ; } , [ ] ) ; await db . batch ( changes ) ; } , async commitBatch ( batch ) { await db . batch ( batch ) ; } , async reset ( ) { const batch = [ ] ; await new Promise < void > ( ( resolve , reject ) => { db . createKeyStream ( ) . on ( 'data' , ( key ) => { batch . push ( { type : 'del' , key } ) ; } ) . on ( 'error' , ( error ) => { reject ( error ) ; } ) . on ( 'end' , ( ) => { resolve ( ) ; } ) ; } ) ; await db . batch ( batch ) ; } } ; } ;