diff --git a/lib/core/versions/latest/Delta.ts b/lib/core/versions/latest/Delta.ts index 726ef0451..7808c32c7 100644 --- a/lib/core/versions/latest/Delta.ts +++ b/lib/core/versions/latest/Delta.ts @@ -1,4 +1,5 @@ import ErrorCode from './ErrorCode'; +import JsonCanonicalizer from './util/JsonCanonicalizer'; import ProtocolParameters from './ProtocolParameters'; import SidetreeError from '../../../common/SidetreeError'; @@ -9,6 +10,7 @@ export default class Delta { /** * Validates size of the encoded delta string. + * TODO: SIP 2 #781 delete this and use validateDeltaSize only in chunk file * @throws `SidetreeError` if fails validation. */ public static validateEncodedDeltaSize (encodedDelta: string) { @@ -19,4 +21,16 @@ export default class Delta { throw new SidetreeError(ErrorCode.DeltaExceedsMaximumSize, errorMessage); } } + + /** + * Validates size of the delta object + */ + public static validateDeltaSize (delta: object) { + const size = Buffer.byteLength(JsonCanonicalizer.canonicalizeAsBuffer(delta)); + if (size > ProtocolParameters.maxDeltaSizeInBytes) { + const errorMessage = `${size} bytes of 'delta' exceeded limit of ${ProtocolParameters.maxDeltaSizeInBytes} bytes.`; + console.info(errorMessage); + throw new SidetreeError(ErrorCode.DeltaExceedsMaximumSize, errorMessage); + } + } } diff --git a/lib/core/versions/latest/Did.ts b/lib/core/versions/latest/Did.ts index 30aa31736..f3f3ad8b1 100644 --- a/lib/core/versions/latest/Did.ts +++ b/lib/core/versions/latest/Did.ts @@ -178,6 +178,7 @@ export default class Did { } Did.validateInitialState(initialStateEncodedJcs, initialStateObject); + Delta.validateDeltaSize(initialStateObject.delta); const createOperationRequest = { type: OperationType.Create, diff --git a/lib/core/versions/latest/protocol-parameters.json b/lib/core/versions/latest/protocol-parameters.json index 23259b019..789066d3b 100644 --- a/lib/core/versions/latest/protocol-parameters.json +++ b/lib/core/versions/latest/protocol-parameters.json @@ -2,7 +2,7 @@ "hashAlgorithmInMultihashCode": 18, "maxAnchorFileSizeInBytes": 1000000, "maxMapFileSizeInBytes": 1000000, - "maxChunkFileSizeInBytes": 20000000, + "maxChunkFileSizeInBytes": 10000000, "maxNumberOfOperationsPerTransactionTime": 600000, "maxNumberOfTransactionsPerTransactionTime": 300, "maxOperationsPerBatch": 10000, diff --git a/tests/core/Did.spec.ts b/tests/core/Did.spec.ts index c36b7f2d7..0368b2c89 100644 --- a/tests/core/Did.spec.ts +++ b/tests/core/Did.spec.ts @@ -3,6 +3,7 @@ import Did from '../../lib/core/versions/latest/Did'; import Encoder from '../../lib/core/versions/latest/Encoder'; import ErrorCode from '../../lib/core/versions/latest/ErrorCode'; import JasmineSidetreeErrorValidator from '../JasmineSidetreeErrorValidator'; +import JsonCanonicalizer from '../../lib/core/versions/latest/util/JsonCanonicalizer'; import OperationGenerator from '../generators/OperationGenerator'; import SidetreeError from '../../lib/common/SidetreeError'; @@ -27,6 +28,14 @@ describe('DID', async () => { expect(e).toEqual(new SidetreeError(ErrorCode.DidInitialStateJcsIsNotJcs, 'Initial state object and JCS string mismatch.')); } }); + + it('should throw sidetree error if delta exceeds size limit', () => { + const largeData = crypto.randomBytes(2000).toString('hex');// Intentionally exceeding max size. + const largeDelta = { data: largeData }; + const testInitialState = Encoder.encode(JsonCanonicalizer.canonicalizeAsBuffer({ suffix_data: 'some data', delta: largeDelta })); + + JasmineSidetreeErrorValidator.expectSidetreeErrorToBeThrown(() => { Did['constructCreateOperationFromEncodedJcs'](testInitialState); }, ErrorCode.DeltaExceedsMaximumSize); + }); }); describe('create()', async () => {