import { u8aConcat , u8aToBuffer , isString } from '@polkadot/util' ; import { getTypeByScalarName } from '@subql/common' ; import { GraphQLModelsType } from '@subql/common/graphql/types' ; import { Entity } from '@subql/types' ; import MerkleTools from 'merkle-tools' ; import { OperationEntity , OperationType } from './types' ; export class StoreOperations { private merkleTools ; constructor ( private models ) { this . merkleTools = new MerkleTools ( { hashType : 'sha256' , } ) ; } private operationEntityToUint8Array ( operation ) { const dataBufferArray = [ ] ; if ( operation . operation === OperationType . Remove ) { if ( isString ( operation . data ) ) { dataBufferArray . push ( Buffer . from ( operation . data ) ) ; } else { throw new Error ( `Remove operation only accept data in string type` ) ; } } else { const operationModel = this . models . find ( ( { name } ) => name === operation . entityType ) ; for ( const field of operationModel . fields ) { const fieldValue = operation . data [ field . name ] ; dataBufferArray . push ( Buffer . from ( field . name ) ) ; if ( fieldValue !== undefined && fieldValue !== null ) { if ( field . isEnum ) { getTypeByScalarName ( 'String' ) . hashCode ( fieldValue ) ; } else { dataBufferArray . push ( getTypeByScalarName ( field . type ) . hashCode ( fieldValue ) ) ; } } } } return u8aConcat ( Buffer . from ( operation . operation ) , Buffer . from ( operation . entityType ) , ... dataBufferArray ) ; } put ( operation , entity , data ) { const operationEntity = { operation : operation , entityType : entity , data : data , } ; this . merkleTools . addLeaf ( u8aToBuffer ( this . operationEntityToUint8Array ( operationEntity ) ) ) ; } reset ( ) { this . merkleTools . resetTree ( ) ; } makeOperationMerkleTree ( ) { this . merkleTools . makeTree ( ) ; } getOperationMerkleRoot ( ) { if ( this . merkleTools . getTreeReadyState ( ) ) { return this . merkleTools . getMerkleRoot ( ) ; } else { throw new Error ( `Failed to get Merkle root from operations, tree is not built yet` ) ; } } getOperationLeafCount ( ) { return this . merkleTools . getLeafCount ( ) ; } }