diff --git a/packages/dapi/lib/grpcServer/handlers/createGrpcErrorFromDriveResponse.js b/packages/dapi/lib/grpcServer/handlers/createGrpcErrorFromDriveResponse.js index 924b5a709e..b6e7032f85 100644 --- a/packages/dapi/lib/grpcServer/handlers/createGrpcErrorFromDriveResponse.js +++ b/packages/dapi/lib/grpcServer/handlers/createGrpcErrorFromDriveResponse.js @@ -101,7 +101,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // Undefined Drive and DAPI errors - if (code >= 17 && code < 1000) { + if (code >= 17 && code < 10000) { return new GrpcError( GrpcErrorCodes.UNKNOWN, message, @@ -110,7 +110,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // DPP errors - if (code >= 1000 && code < 5000) { + if (code >= 10000 && code < 50000) { let consensusError; try { consensusError = deserializeConsensusError(data.serializedError || []); @@ -125,7 +125,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // Basic - if (code >= 1000 && code < 2000) { + if (code >= 10000 && code < 20000) { return new InvalidArgumentGrpcError( consensusError.message, { code, ...createRawMetadata(data) }, @@ -133,7 +133,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // Signature - if (code >= 2000 && code < 3000) { + if (code >= 20000 && code < 30000) { return new GrpcError( GrpcErrorCodes.UNAUTHENTICATED, consensusError.message, @@ -142,7 +142,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // Fee - if (code >= 3000 && code < 4000) { + if (code >= 30000 && code < 40000) { return new FailedPreconditionGrpcError( consensusError.message, { code, ...createRawMetadata(data) }, @@ -150,7 +150,7 @@ async function createGrpcErrorFromDriveResponse(code, info) { } // State - if (code >= 4000 && code < 5000) { + if (code >= 40000 && code < 50000) { return new InvalidArgumentGrpcError( consensusError.message, { code, ...createRawMetadata(data) }, diff --git a/packages/dapi/test/unit/grpcServer/handlers/createGrpcErrorFromDriveResponse.spec.js b/packages/dapi/test/unit/grpcServer/handlers/createGrpcErrorFromDriveResponse.spec.js index 88420d1f43..48a4c32e78 100644 --- a/packages/dapi/test/unit/grpcServer/handlers/createGrpcErrorFromDriveResponse.spec.js +++ b/packages/dapi/test/unit/grpcServer/handlers/createGrpcErrorFromDriveResponse.spec.js @@ -66,23 +66,23 @@ describe('createGrpcErrorFromDriveResponse', () => { }); }); - it('should throw basic consensus error if error code = 1000', async () => { + it('should throw basic consensus error if error code = 10000', async () => { const consensusError = new ProtocolVersionParsingError('test'); const data = { serializedError: consensusError.serialize() }; info = { data }; - const error = await createGrpcErrorFromDriveResponse(1000, cbor.encode(info).toString('base64')); + const error = await createGrpcErrorFromDriveResponse(10000, cbor.encode(info).toString('base64')); expect(error).to.be.an.instanceOf(InvalidArgumentGrpcError); expect(error.message).to.be.equals(consensusError.message); expect(error.getRawMetadata()).to.deep.equal({ - code: 1000, + code: 10000, 'drive-error-data-bin': cbor.encode(data), }); }); - it('should throw signature consensus error if error code = 2000', async () => { + it('should throw signature consensus error if error code = 20000', async () => { const id = await generateRandomIdentifierAsync(); const consensusError = new IdentityNotFoundError(id); @@ -91,7 +91,7 @@ describe('createGrpcErrorFromDriveResponse', () => { info = { data }; const error = await createGrpcErrorFromDriveResponse( - 2000, + 20000, cbor.encode(info).toString('base64'), ); @@ -99,27 +99,27 @@ describe('createGrpcErrorFromDriveResponse', () => { expect(error.message).to.be.equals(consensusError.message); expect(error.getCode()).to.equal(GrpcErrorCodes.UNAUTHENTICATED); expect(error.getRawMetadata()).to.deep.equal({ - code: 2000, + code: 20000, 'drive-error-data-bin': cbor.encode(data), }); }); - it('should throw fee consensus error if error code = 3000', async () => { + it('should throw fee consensus error if error code = 30000', async () => { const consensusError = new BalanceIsNotEnoughError(BigInt(20), BigInt(10)); const data = { serializedError: consensusError.serialize() }; info = { data }; - const error = await createGrpcErrorFromDriveResponse(3000, cbor.encode(info).toString('base64')); + const error = await createGrpcErrorFromDriveResponse(30000, cbor.encode(info).toString('base64')); expect(error).to.be.an.instanceOf(FailedPreconditionGrpcError); expect(error.getRawMetadata()).to.deep.equal({ - code: 3000, + code: 30000, 'drive-error-data-bin': cbor.encode(data), }); }); - it('should throw state consensus error if error code = 4000', async () => { + it('should throw state consensus error if error code = 40000', async () => { const dataContractId = await generateRandomIdentifierAsync(); const consensusError = new DataContractAlreadyPresentError(dataContractId); @@ -128,23 +128,23 @@ describe('createGrpcErrorFromDriveResponse', () => { info = { data }; const error = await createGrpcErrorFromDriveResponse( - 4000, + 40000, cbor.encode(info).toString('base64'), ); expect(error).to.be.an.instanceOf(InvalidArgumentGrpcError); expect(error.getRawMetadata()).to.deep.equal({ - code: 4000, + code: 40000, 'drive-error-data-bin': cbor.encode(data), }); }); - it('should throw Unknown error code >= 5000', async () => { - const error = await createGrpcErrorFromDriveResponse(5000, encodedInfo); + it('should throw Unknown error code >= 50000', async () => { + const error = await createGrpcErrorFromDriveResponse(50000, encodedInfo); expect(error).to.be.an.instanceOf(GrpcError); expect(error.getMessage()).to.equal('Internal error'); - expect(error.getError().message).to.deep.equal('Unknown Drive’s error code: 5000'); + expect(error.getError().message).to.deep.equal('Unknown Drive’s error code: 50000'); }); it('should return InternalGrpcError if codes is undefined', async () => { diff --git a/packages/js-dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js b/packages/js-dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js index 98043b6121..103c37bb39 100644 --- a/packages/js-dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js +++ b/packages/js-dapi-client/lib/transport/GrpcTransport/createGrpcTransportError.js @@ -118,7 +118,7 @@ async function createGrpcTransportError(grpcError, dapiAddress) { } // DPP consensus errors - if (code >= 1000 && code < 5000) { + if (code >= 10000 && code < 50000) { const consensusError = deserializeConsensusError(data.serializedError || []); delete data.serializedError; diff --git a/packages/js-dapi-client/test/unit/transport/GrpcTransport/createGrpcTransportError.spec.js b/packages/js-dapi-client/test/unit/transport/GrpcTransport/createGrpcTransportError.spec.js index 7cab061aa3..13205f6e0c 100644 --- a/packages/js-dapi-client/test/unit/transport/GrpcTransport/createGrpcTransportError.spec.js +++ b/packages/js-dapi-client/test/unit/transport/GrpcTransport/createGrpcTransportError.spec.js @@ -168,7 +168,7 @@ describe('createGrpcTransportError', () => { metadata.set('drive-error-data-bin', driveErrorDataBin); const grpcError = new GrpcError( - 1000, + 10001, 'Parsing error', ); grpcError.metadata = metadata; diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditTransfer.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditTransfer.ts index f6d05bc556..71c0f19658 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditTransfer.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditTransfer.ts @@ -28,7 +28,7 @@ export async function creditTransfer( this.logger.silly('[Identity#creditTransfer] Created IdentityCreditTransferTransition'); - const signerKeyIndex = 2; + const signerKeyIndex = 3; await signStateTransition(this, identityCreditTransferTransition, identity, signerKeyIndex); diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditWithdrawal.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditWithdrawal.ts index a8ebae7640..a2bd513397 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditWithdrawal.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/creditWithdrawal.ts @@ -43,7 +43,7 @@ export async function creditWithdrawal( amount: number, to: string, options: WithdrawalOptions = { - signingKeyIndex: 2, + signingKeyIndex: 3, }, ): Promise { await this.initialize(); diff --git a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/internal/createIdentityCreateTransition.ts b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/internal/createIdentityCreateTransition.ts index d26c80a52a..83ece7d237 100644 --- a/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/internal/createIdentityCreateTransition.ts +++ b/packages/js-dash-sdk/src/SDK/Client/Platform/methods/identities/internal/createIdentityCreateTransition.ts @@ -26,36 +26,55 @@ export async function createIdentityCreateTransition( const identityIndex = await account.getUnusedIdentityIndex(); + // Authentication master key + const { privateKey: identityMasterPrivateKey } = account.identities .getIdentityHDKeyByIndex(identityIndex, 0); const identityMasterPublicKey = identityMasterPrivateKey.toPublicKey(); - const { privateKey: identitySecondPrivateKey } = account.identities + const masterKey = new IdentityPublicKey(1); + masterKey.setId(0); + masterKey.setData(identityMasterPublicKey.toBuffer()); + masterKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MASTER); + + // Authentication high level key + + const { privateKey: identityHighAuthPrivateKey } = account.identities .getIdentityHDKeyByIndex(identityIndex, 1); - const identitySecondPublicKey = identitySecondPrivateKey.toPublicKey(); + const identityHighAuthPublicKey = identityHighAuthPrivateKey.toPublicKey(); + + const highAuthKey = new IdentityPublicKey(1); + highAuthKey.setId(1); + highAuthKey.setData(identityHighAuthPublicKey.toBuffer()); + highAuthKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.HIGH); + + // Authentication critical level key - const { privateKey: identityThirdPrivateKey } = account.identities + const { privateKey: identityCriticalAuthPrivateKey } = account.identities .getIdentityHDKeyByIndex(identityIndex, 2); - const identityThirdPublicKey = identityThirdPrivateKey.toPublicKey(); + const identityCriticalAuthPublicKey = identityCriticalAuthPrivateKey.toPublicKey(); - const keyOne = new IdentityPublicKey(1); - keyOne.setData(identityMasterPublicKey.toBuffer()); - keyOne.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MASTER); + const criticalAuthKey = new IdentityPublicKey(1); + criticalAuthKey.setId(2); + criticalAuthKey.setData(identityCriticalAuthPublicKey.toBuffer()); + criticalAuthKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.CRITICAL); - const keyTwo = new IdentityPublicKey(1); - keyTwo.setId(1); - keyTwo.setData(identitySecondPublicKey.toBuffer()); - keyTwo.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.HIGH); + // Transfer key - const keyThree = new IdentityPublicKey(1); - keyThree.setId(2); - keyThree.setData(identityThirdPublicKey.toBuffer()); - keyThree.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.CRITICAL); + const { privateKey: identityTransferPrivateKey } = account.identities + .getIdentityHDKeyByIndex(identityIndex, 3); + const identityTransferPublicKey = identityTransferPrivateKey.toPublicKey(); + + const transferKey = new IdentityPublicKey(1); + transferKey.setId(3); + transferKey.setPurpose(IdentityPublicKey.PURPOSES.TRANSFER); + transferKey.setData(identityTransferPublicKey.toBuffer()); + transferKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.CRITICAL); // Create Identity const identity = dpp.identity.create( assetLockProof.createIdentifier(), - [keyOne, keyTwo, keyThree], + [masterKey, highAuthKey, criticalAuthKey, transferKey], ); // Create ST @@ -65,35 +84,62 @@ export async function createIdentityCreateTransition( ); // Create key proofs - const [masterKey, secondKey, thirdKey] = identityCreateTransition.getPublicKeys(); + const [ + stMasterKey, stHighAuthKey, stCriticalAuthKey, stTransferKey, + ] = identityCreateTransition.getPublicKeys(); + + // Sign master key + + identityCreateTransition.signByPrivateKey( + identityMasterPrivateKey.toBuffer(), + IdentityPublicKey.TYPES.ECDSA_SECP256K1, + ); - await identityCreateTransition - .signByPrivateKey(identityMasterPrivateKey.toBuffer(), IdentityPublicKey.TYPES.ECDSA_SECP256K1); + stMasterKey.setSignature(identityCreateTransition.getSignature()); - masterKey.setSignature(identityCreateTransition.getSignature()); + identityCreateTransition.setSignature(undefined); + + // Sign high auth key + + identityCreateTransition.signByPrivateKey( + identityHighAuthPrivateKey.toBuffer(), + IdentityPublicKey.TYPES.ECDSA_SECP256K1, + ); + + stHighAuthKey.setSignature(identityCreateTransition.getSignature()); identityCreateTransition.setSignature(undefined); - await identityCreateTransition - .signByPrivateKey(identitySecondPrivateKey.toBuffer(), IdentityPublicKey.TYPES.ECDSA_SECP256K1); + // Sign critical auth key - secondKey.setSignature(identityCreateTransition.getSignature()); + identityCreateTransition.signByPrivateKey( + identityCriticalAuthPrivateKey.toBuffer(), + IdentityPublicKey.TYPES.ECDSA_SECP256K1, + ); + + stCriticalAuthKey.setSignature(identityCreateTransition.getSignature()); identityCreateTransition.setSignature(undefined); - await identityCreateTransition - .signByPrivateKey(identityThirdPrivateKey.toBuffer(), IdentityPublicKey.TYPES.ECDSA_SECP256K1); + // Sign transfer key + + identityCreateTransition.signByPrivateKey( + identityTransferPrivateKey.toBuffer(), + IdentityPublicKey.TYPES.ECDSA_SECP256K1, + ); - thirdKey.setSignature(identityCreateTransition.getSignature()); + stTransferKey.setSignature(identityCreateTransition.getSignature()); identityCreateTransition.setSignature(undefined); // Set public keys back after updating their signatures - identityCreateTransition.setPublicKeys([masterKey, secondKey, thirdKey]); + identityCreateTransition.setPublicKeys([ + stMasterKey, stHighAuthKey, stCriticalAuthKey, stTransferKey, + ]); // Sign and validate state transition - await identityCreateTransition + identityCreateTransition .signByPrivateKey(assetLockPrivateKey.toBuffer(), IdentityPublicKey.TYPES.ECDSA_SECP256K1); // TODO(versioning): restore diff --git a/packages/platform-test-suite/test/e2e/dpns.spec.js b/packages/platform-test-suite/test/e2e/dpns.spec.js index b154644cc9..0f592c07e6 100644 --- a/packages/platform-test-suite/test/e2e/dpns.spec.js +++ b/packages/platform-test-suite/test/e2e/dpns.spec.js @@ -107,7 +107,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Action is not allowed'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); it('should not be able to delete domain', async () => { @@ -123,7 +123,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Action is not allowed'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); }); @@ -153,7 +153,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Can\'t create top level domain for this identity'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); it('should be able to register a second level domain', async () => { @@ -185,7 +185,7 @@ describe('DPNS', () => { } expect(broadcastError).to.exist(); - expect(broadcastError.code).to.be.equal(4009); + expect(broadcastError.code).to.be.equal(40105); expect(broadcastError.message).to.match(/Document \w* has duplicate unique properties \["normalizedParentDomainName", "normalizedLabel"] with other documents/); }); @@ -206,7 +206,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Parent domain is not present'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); it('should be able to search a domain', async () => { @@ -251,7 +251,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Action is not allowed'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); it('should not be able to delete domain', async () => { @@ -267,7 +267,7 @@ describe('DPNS', () => { expect(broadcastError).to.exist(); expect(broadcastError.message).to.be.equal('Action is not allowed'); - expect(broadcastError.code).to.equal(4001); + expect(broadcastError.code).to.equal(40500); }); it('should not be able to register two domains with same `dashAliasIdentityId` record'); diff --git a/packages/platform-test-suite/test/e2e/withdrawals.spec.js b/packages/platform-test-suite/test/e2e/withdrawals.spec.js index 1b146edaea..02e4548329 100644 --- a/packages/platform-test-suite/test/e2e/withdrawals.spec.js +++ b/packages/platform-test-suite/test/e2e/withdrawals.spec.js @@ -202,7 +202,7 @@ describe('Withdrawals', function withdrawalsTest() { expect.fail('should throw broadcast error'); } catch (e) { expect(e.message).to.be.equal('Action is not allowed'); - expect(e.code).to.equal(4001); + expect(e.code).to.equal(40500); } }); @@ -244,7 +244,7 @@ describe('Withdrawals', function withdrawalsTest() { expect.fail('should throw broadcast error'); } catch (e) { expect(e.message).to.be.equal('withdrawal deletion is allowed only for COMPLETE statuses'); - expect(e.code).to.equal(4001); + expect(e.code).to.equal(40500); } }); @@ -267,7 +267,7 @@ describe('Withdrawals', function withdrawalsTest() { expect.fail('should throw broadcast error'); } catch (e) { expect(e.message).to.be.equal('Action is not allowed'); - expect(e.code).to.equal(4001); + expect(e.code).to.equal(40500); } }); }); diff --git a/packages/platform-test-suite/test/functional/platform/DataContract.spec.js b/packages/platform-test-suite/test/functional/platform/DataContract.spec.js index 6f75e906ba..775a842d5e 100644 --- a/packages/platform-test-suite/test/functional/platform/DataContract.spec.js +++ b/packages/platform-test-suite/test/functional/platform/DataContract.spec.js @@ -55,7 +55,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(2000); + expect(broadcastError.getCause().getCode()).to.equal(20000); expect(broadcastError.getCause()).to.be.an.instanceOf(IdentityNotFoundError); }); @@ -101,7 +101,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(1050); + expect(broadcastError.getCause().getCode()).to.equal(10212); expect(broadcastError.getCause()).to.be.an.instanceOf(InvalidDataContractVersionError); }); @@ -127,7 +127,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(1051); + expect(broadcastError.getCause().getCode()).to.equal(10213); expect(broadcastError.getCause()).to.be.an.instanceOf(IncompatibleDataContractSchemaError); }); diff --git a/packages/platform-test-suite/test/functional/platform/Document.spec.js b/packages/platform-test-suite/test/functional/platform/Document.spec.js index 3b03f98586..55b5c03a48 100644 --- a/packages/platform-test-suite/test/functional/platform/Document.spec.js +++ b/packages/platform-test-suite/test/functional/platform/Document.spec.js @@ -196,7 +196,7 @@ describe('Platform', () => { expect(broadcastError.code) .to .be - .equal(4009); + .equal(40105); expect(broadcastError.message) .to .match(/Document \w* has duplicate unique properties \["\$ownerId", "firstName"] with other documents/); diff --git a/packages/platform-test-suite/test/functional/platform/Identity.spec.js b/packages/platform-test-suite/test/functional/platform/Identity.spec.js index 7016119ec5..4d39d67755 100644 --- a/packages/platform-test-suite/test/functional/platform/Identity.spec.js +++ b/packages/platform-test-suite/test/functional/platform/Identity.spec.js @@ -66,7 +66,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(4029); + expect(broadcastError.getCause().getCode()).to.equal(40212); expect(broadcastError.getCause()).to.be.an.instanceOf( InvalidAssetLockProofValueError, ); @@ -104,7 +104,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(1042); + expect(broadcastError.getCause().getCode()).to.equal(10513); expect(broadcastError.getCause()).to.be.an.instanceOf( InvalidInstantAssetLockProofSignatureError, ); @@ -158,7 +158,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(1033); + expect(broadcastError.getCause().getCode()).to.equal(10504); expect(broadcastError.getCause()).to.be.an.instanceOf( IdentityAssetLockTransactionOutPointAlreadyExistsError, ); @@ -209,7 +209,7 @@ describe('Platform', () => { } expect(broadcastError).to.be.an.instanceOf(StateTransitionBroadcastError); - expect(broadcastError.getCause().getCode()).to.equal(2009); + expect(broadcastError.getCause().getCode()).to.equal(20009); expect(broadcastError.getCause()).to.be.an.instanceOf( BasicECDSAError, ); @@ -585,7 +585,7 @@ describe('Platform', () => { it('should be able to add public key to the identity', async () => { const identityBeforeUpdate = identity.toObject(); - expect(identityBeforeUpdate.publicKeys[3]).to.not.exist(); + const nextKeyId = identityBeforeUpdate.publicKeys.length; const account = await client.platform.client.getWalletAccount(); const identityIndex = await account.getUnusedIdentityIndex(); @@ -597,7 +597,7 @@ describe('Platform', () => { const identityPublicKey = identityPrivateKey.toPublicKey().toBuffer(); const newPublicKey = new IdentityPublicKeyWithWitness(1); - newPublicKey.setId(3); + newPublicKey.setId(nextKeyId); newPublicKey.setSecurityLevel(IdentityPublicKey.SECURITY_LEVELS.MEDIUM); newPublicKey.setData(identityPublicKey); @@ -623,7 +623,7 @@ describe('Platform', () => { expect(identity.getPublicKeyById(2)).to.exist(); const newPublicKeyObject = newPublicKey.toObject(true); - const expectedPublicKey = identity.getPublicKeyById(3).toObject(true); + const expectedPublicKey = identity.getPublicKeyById(4).toObject(true); delete expectedPublicKey.disabledAt; expect(expectedPublicKey).to.deep.equal( newPublicKeyObject, diff --git a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/mod.rs b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/mod.rs index 8dad4f62c0..dc7019cf7a 100644 --- a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/mod.rs @@ -1,5 +1,7 @@ mod v0; +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; use crate::data_contract::document_type::DocumentType; use crate::ProtocolError; use platform_value::Value; @@ -18,7 +20,13 @@ impl DocumentType { .schema .enrich_with_base_schema { - 0 => v0::enrich_with_base_schema_v0(schema, schema_defs), + 0 => Ok( + v0::enrich_with_base_schema_v0(schema, schema_defs).map_err(|e| { + ProtocolError::ConsensusError( + ConsensusError::BasicError(BasicError::ContractError(e)).into(), + ) + })?, + ), version => Err(ProtocolError::UnknownVersionMismatch { method: "enrich_with_base_schema".to_string(), known_versions: vec![0], diff --git a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs index 706070c876..74401626f3 100644 --- a/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/schema/enrich_with_base_schema/v0/mod.rs @@ -1,9 +1,6 @@ -use crate::consensus::basic::BasicError; -use crate::consensus::ConsensusError; use crate::data_contract::document_type::property_names; use crate::data_contract::errors::DataContractError; use crate::data_contract::serialized_version::v0::property_names as contract_property_names; -use crate::ProtocolError; use platform_value::{Value, ValueMapHelper}; pub const DATA_CONTRACT_SCHEMA_URI_V0: &str = @@ -16,27 +13,17 @@ const TIMESTAMPS: [&str; 2] = ["$createdAt", "$updatedAt"]; pub fn enrich_with_base_schema_v0( mut schema: Value, schema_defs: Option, -) -> Result { +) -> Result { let schema_map = schema.to_map_mut().map_err(|err| { - ProtocolError::ConsensusError( - ConsensusError::BasicError(BasicError::ContractError( - DataContractError::InvalidContractStructure(format!( - "document schema must be an object: {err}" - )), - )) - .into(), - ) + DataContractError::InvalidContractStructure(format!( + "document schema must be an object: {err}" + )) })?; // Add $schema if schema_map.get_optional_key(PROPERTY_SCHEMA).is_some() { - return Err(ProtocolError::ConsensusError( - ConsensusError::BasicError(BasicError::ContractError( - DataContractError::InvalidContractStructure( - "document schema shouldn't contain '$schema' property".to_string(), - ), - )) - .into(), + return Err(DataContractError::InvalidContractStructure( + "document schema shouldn't contain '$schema' property".to_string(), )); } @@ -50,13 +37,8 @@ pub fn enrich_with_base_schema_v0( .get_optional_key(contract_property_names::DEFINITIONS) .is_some() { - return Err(ProtocolError::ConsensusError( - ConsensusError::BasicError(BasicError::ContractError( - DataContractError::InvalidContractStructure( - "document schema shouldn't contain '$defs' property".to_string(), - ), - )) - .into(), + return Err(DataContractError::InvalidContractStructure( + "document schema shouldn't contain '$defs' property".to_string(), )); } diff --git a/packages/rs-dpp/src/data_contract/document_type/schema/recursive_schema_validator/mod.rs b/packages/rs-dpp/src/data_contract/document_type/schema/recursive_schema_validator/mod.rs index 4a550196fa..2910e97487 100644 --- a/packages/rs-dpp/src/data_contract/document_type/schema/recursive_schema_validator/mod.rs +++ b/packages/rs-dpp/src/data_contract/document_type/schema/recursive_schema_validator/mod.rs @@ -114,7 +114,7 @@ mod test { err.pattern(), "^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$".to_string() ); - assert_eq!(consensus_error.code(), 1009); + assert_eq!(consensus_error.code(), 10202); } _ => panic!("Expected error to be IncompatibleRe2PatternError"), } @@ -157,7 +157,7 @@ mod test { err.pattern(), "^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$".to_string() ); - assert_eq!(consensus_error.code(), 1009); + assert_eq!(consensus_error.code(), 10202); } _ => panic!("Expected error to be IncompatibleRe2PatternError"), } @@ -187,7 +187,7 @@ mod test { err.pattern(), "^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$".to_string() ); - assert_eq!(consensus_error.code(), 1009); + assert_eq!(consensus_error.code(), 10202); } _ => panic!("Expected error to be IncompatibleRe2PatternError"), } diff --git a/packages/rs-dpp/src/data_contract/methods/validation/v0/mod.rs b/packages/rs-dpp/src/data_contract/methods/validation/v0/mod.rs index c84d23d11d..4b1791ac2b 100644 --- a/packages/rs-dpp/src/data_contract/methods/validation/v0/mod.rs +++ b/packages/rs-dpp/src/data_contract/methods/validation/v0/mod.rs @@ -3,6 +3,8 @@ use crate::data_contract::document_type::accessors::DocumentTypeV0Getters; use crate::data_contract::document_type::{DocumentType, DocumentTypeRef}; use crate::consensus::basic::document::{InvalidDocumentTypeError, MissingDocumentTypeError}; +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; use crate::data_contract::schema::DataContractSchemaMethodsV0; use crate::data_contract::DataContract; use crate::document::{property_names, Document, DocumentV0Getters}; @@ -47,6 +49,8 @@ impl DataContract { // Compile json schema validator if it's not yet compiled if !validator.is_compiled(platform_version)? { + // It is normal that we get a protocol error here, since the document type is coming + // from the state let root_schema = DocumentType::enrich_with_base_schema( // TODO: I just wondering if we could you references here // instead of cloning @@ -62,11 +66,12 @@ impl DataContract { validator.compile(&root_json_schema, platform_version)?; } - let json_value = value - .try_into_validating_json() - .map_err(ProtocolError::ValueError)?; - - validator.validate(&json_value, platform_version) + match value.try_into_validating_json() { + Ok(json_value) => validator.validate(&json_value, platform_version), + Err(e) => Ok(SimpleConsensusValidationResult::new_with_error( + ConsensusError::BasicError(BasicError::ValueError(e.into())), + )), + } } // TODO: Move to document diff --git a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs index d29eb47fb0..516c49f9a5 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/basic_error.rs @@ -46,6 +46,7 @@ use crate::consensus::basic::identity::{ InvalidIdentityUpdateTransitionDisableKeysError, InvalidIdentityUpdateTransitionEmptyError, InvalidInstantAssetLockProofError, InvalidInstantAssetLockProofSignatureError, MissingMasterPublicKeyError, NotImplementedIdentityCreditWithdrawalTransitionPoolingError, + TooManyMasterPublicKeyError, }; use crate::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use crate::consensus::basic::state_transition::{ @@ -59,6 +60,7 @@ use crate::consensus::basic::json_schema_compilation_error::JsonSchemaCompilatio use crate::consensus::basic::json_schema_error::JsonSchemaError; use crate::consensus::basic::unsupported_version_error::UnsupportedVersionError; use crate::consensus::basic::value_error::ValueError; +use crate::consensus::state::identity::master_public_key_update_error::MasterPublicKeyUpdateError; use crate::data_contract::errors::DataContractError; #[derive(Error, Debug, PlatformSerialize, PlatformDeserialize, Encode, Decode, Clone)] @@ -277,6 +279,12 @@ pub enum BasicError { #[error(transparent)] MissingMasterPublicKeyError(MissingMasterPublicKeyError), + #[error(transparent)] + TooManyMasterPublicKeyError(TooManyMasterPublicKeyError), + + #[error(transparent)] + MasterPublicKeyUpdateError(MasterPublicKeyUpdateError), + #[error(transparent)] InvalidDocumentTypeRequiredSecurityLevelError(InvalidDocumentTypeRequiredSecurityLevelError), diff --git a/packages/rs-dpp/src/errors/consensus/basic/identity/mod.rs b/packages/rs-dpp/src/errors/consensus/basic/identity/mod.rs index 2193b587c2..6a62261e5d 100644 --- a/packages/rs-dpp/src/errors/consensus/basic/identity/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/basic/identity/mod.rs @@ -26,6 +26,7 @@ pub use invalid_instant_asset_lock_proof_error::*; pub use invalid_instant_asset_lock_proof_signature_error::*; pub use missing_master_public_key_error::*; pub use not_implemented_identity_credit_withdrawal_transition_pooling_error::*; +pub use too_many_master_public_key_error::*; mod data_contract_bounds_not_present_error; mod disabling_key_id_also_being_added_in_same_transition_error; @@ -55,3 +56,4 @@ mod invalid_instant_asset_lock_proof_error; mod invalid_instant_asset_lock_proof_signature_error; mod missing_master_public_key_error; mod not_implemented_identity_credit_withdrawal_transition_pooling_error; +mod too_many_master_public_key_error; diff --git a/packages/rs-dpp/src/errors/consensus/basic/identity/too_many_master_public_key_error.rs b/packages/rs-dpp/src/errors/consensus/basic/identity/too_many_master_public_key_error.rs new file mode 100644 index 0000000000..0b8bda2d2c --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/basic/identity/too_many_master_public_key_error.rs @@ -0,0 +1,42 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::errors::ProtocolError; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +use bincode::{Decode, Encode}; + +#[derive( + Error, + Debug, + Clone, + PartialEq, + Eq, + Default, + Encode, + Decode, + PlatformSerialize, + PlatformDeserialize, +)] +#[error( + "Identity is trying to be created with more than one master key. Please only use one master key." +)] +#[platform_serialize(unversioned)] +pub struct TooManyMasterPublicKeyError; + +/* + +DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + +*/ + +impl TooManyMasterPublicKeyError { + pub fn new() -> Self { + Self + } +} +impl From for ConsensusError { + fn from(err: TooManyMasterPublicKeyError) -> Self { + Self::BasicError(BasicError::TooManyMasterPublicKeyError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/codes.rs b/packages/rs-dpp/src/errors/consensus/codes.rs index 838c419f5d..a843928069 100644 --- a/packages/rs-dpp/src/errors/consensus/codes.rs +++ b/packages/rs-dpp/src/errors/consensus/codes.rs @@ -26,122 +26,121 @@ impl ErrorWithCode for ConsensusError { } } } - impl ErrorWithCode for BasicError { fn code(&self) -> u32 { match self { - // Versioning - Self::UnsupportedVersionError(_) => 1100, - // Decoding - Self::ProtocolVersionParsingError { .. } => 1000, - Self::SerializedObjectParsingError { .. } => 1001, - Self::UnsupportedProtocolVersionError(_) => 1002, - Self::IncompatibleProtocolVersionError(_) => 1003, - Self::VersionError(_) => 1004, - - // Structure error - Self::JsonSchemaCompilationError(..) => 1004, - Self::JsonSchemaError(_) => 1005, - Self::InvalidIdentifierError { .. } => 1006, - Self::ValueError(_) => 1060, - - // DataContract - Self::DataContractMaxDepthExceedError { .. } => 1007, - Self::DuplicateIndexError { .. } => 1008, - Self::IncompatibleRe2PatternError { .. } => 1009, - Self::InvalidCompoundIndexError { .. } => 1010, - Self::InvalidDataContractIdError { .. } => 1011, - Self::InvalidIndexedPropertyConstraintError { .. } => 1012, - Self::InvalidIndexPropertyTypeError { .. } => 1013, - Self::InvalidJsonSchemaRefError { .. } => 1014, - Self::SystemPropertyIndexAlreadyPresentError { .. } => 1015, - Self::UndefinedIndexPropertyError { .. } => 1016, - Self::UniqueIndicesLimitReachedError { .. } => 1017, - Self::DuplicateIndexNameError { .. } => 1048, - Self::InvalidDataContractVersionError { .. } => 1050, - Self::IncompatibleDataContractSchemaError { .. } => 1051, - Self::DataContractEmptySchemaError { .. } => 1069, - Self::DataContractImmutablePropertiesUpdateError { .. } => 1052, - Self::DataContractUniqueIndicesChangedError { .. } => 1053, - Self::DataContractInvalidIndexDefinitionUpdateError { .. } => 1054, - Self::DataContractHaveNewUniqueIndexError { .. } => 1055, - Self::InvalidDocumentTypeRequiredSecurityLevelError { .. } => 1071, - Self::UnknownSecurityLevelError { .. } => 1072, - Self::UnknownStorageKeyRequirementsError { .. } => 1073, - Self::ContractError(DataContractError::DecodingContractError { .. }) => 1074, - Self::ContractError(DataContractError::DecodingDocumentError { .. }) => 1076, - Self::ContractError(DataContractError::InvalidDocumentTypeError { .. }) => 1077, - Self::ContractError(DataContractError::MissingRequiredKey(_)) => 1078, - Self::ContractError(DataContractError::FieldRequirementUnmet(_)) => 1079, - Self::ContractError(DataContractError::KeyWrongType(_)) => 1080, - Self::ContractError(DataContractError::ValueWrongType(_)) => 1081, - Self::ContractError(DataContractError::ValueDecodingError(_)) => 1082, - Self::ContractError(DataContractError::EncodingDataStructureNotSupported(_)) => 1083, - Self::ContractError(DataContractError::InvalidContractStructure(_)) => 1084, - Self::ContractError(DataContractError::DocumentTypeNotFound(_)) => 1085, - Self::ContractError(DataContractError::DocumentTypeFieldNotFound(_)) => 1086, - Self::ContractError(DataContractError::ReferenceDefinitionNotFound(_)) => 1087, - Self::ContractError(DataContractError::DocumentOwnerIdMissing(_)) => 1088, - Self::ContractError(DataContractError::DocumentIdMissing(_)) => 1089, - Self::ContractError(DataContractError::Unsupported(_)) => 1090, - Self::ContractError(DataContractError::CorruptedSerialization(_)) => 1091, - Self::ContractError(DataContractError::JsonSchema(_)) => 1092, - Self::ContractError(DataContractError::InvalidURI(_)) => 1093, - Self::ContractError(DataContractError::KeyWrongBounds(_)) => 1094, - Self::ContractError(DataContractError::KeyValueMustExist(_)) => 1095, - - // Document - Self::DataContractNotPresentError { .. } => 1018, - Self::DuplicateDocumentTransitionsWithIdsError { .. } => 1019, - Self::DuplicateDocumentTransitionsWithIndicesError { .. } => 1020, - Self::InconsistentCompoundIndexDataError { .. } => 1021, - Self::InvalidDocumentTransitionActionError { .. } => 1022, - Self::InvalidDocumentTransitionIdError { .. } => 1023, - Self::InvalidDocumentTypeError { .. } => 1024, - Self::MissingDataContractIdBasicError { .. } => 1025, - Self::MissingDocumentTransitionActionError { .. } => 1026, - Self::MissingDocumentTransitionTypeError { .. } => 1027, - Self::MissingDocumentTypeError { .. } => 1028, - Self::MissingPositionsInDocumentTypePropertiesError { .. } => 1067, - Self::MaxDocumentsTransitionsExceededError { .. } => 1065, - Self::DocumentTransitionsAreAbsentError { .. } => 1068, - Self::IdentityContractNonceOutOfBoundsError(_) => 1069, - - // Identity - Self::DuplicatedIdentityPublicKeyBasicError(_) => 1029, - Self::DuplicatedIdentityPublicKeyIdBasicError(_) => 1030, - Self::IdentityAssetLockProofLockedTransactionMismatchError(_) => 1031, - Self::IdentityAssetLockTransactionIsNotFoundError(_) => 1032, - Self::IdentityAssetLockTransactionOutPointAlreadyExistsError(_) => 1033, - Self::IdentityAssetLockTransactionOutputNotFoundError(_) => 1034, - Self::InvalidAssetLockProofCoreChainHeightError(_) => 1035, - Self::InvalidAssetLockProofTransactionHeightError(_) => 1036, - Self::InvalidAssetLockTransactionOutputReturnSizeError(_) => 1037, - Self::InvalidIdentityAssetLockTransactionError(_) => 1038, - Self::InvalidIdentityAssetLockTransactionOutputError(_) => 1039, - Self::InvalidIdentityPublicKeyDataError(_) => 1040, - Self::InvalidInstantAssetLockProofError(_) => 1041, - Self::InvalidInstantAssetLockProofSignatureError(_) => 1042, - Self::InvalidIdentityAssetLockProofChainLockValidationError(_) => 1043, - Self::DataContractBoundsNotPresentError(_) => 1066, - Self::DisablingKeyIdAlsoBeingAddedInSameTransitionError(_) => 1096, - - Self::MissingMasterPublicKeyError(_) => 1046, - Self::InvalidIdentityPublicKeySecurityLevelError(_) => 1047, - Self::InvalidIdentityKeySignatureError { .. } => 1056, - Self::InvalidIdentityCreditWithdrawalTransitionOutputScriptError(_) => 1057, - Self::InvalidIdentityCreditWithdrawalTransitionCoreFeeError(_) => 1058, - Self::NotImplementedIdentityCreditWithdrawalTransitionPoolingError(_) => 1059, - Self::InvalidIdentityCreditTransferAmountError(_) => 1061, - Self::InvalidIdentityCreditWithdrawalTransitionAmountError(_) => 1062, - Self::InvalidIdentityUpdateTransitionEmptyError(_) => 1063, - Self::InvalidIdentityUpdateTransitionDisableKeysError(_) => 1064, - Self::IdentityCreditTransferToSelfError(_) => 1070, - - // State Transition - Self::InvalidStateTransitionTypeError { .. } => 1043, - Self::MissingStateTransitionTypeError { .. } => 1044, - Self::StateTransitionMaxSizeExceededError { .. } => 1045, + // Versioning Errors: 10000-10099 + Self::UnsupportedVersionError(_) => 10000, + Self::ProtocolVersionParsingError { .. } => 10001, + Self::SerializedObjectParsingError { .. } => 10002, + Self::UnsupportedProtocolVersionError(_) => 10003, + Self::IncompatibleProtocolVersionError(_) => 10004, + Self::VersionError(_) => 10005, + + // Structure Errors: 10100-10199 + Self::JsonSchemaCompilationError(..) => 10100, + Self::JsonSchemaError(_) => 10101, + Self::InvalidIdentifierError { .. } => 10102, + Self::ValueError(_) => 10103, + + // DataContract Errors: 10200-10399 + Self::DataContractMaxDepthExceedError { .. } => 10200, + Self::DuplicateIndexError { .. } => 10201, + Self::IncompatibleRe2PatternError { .. } => 10202, + Self::InvalidCompoundIndexError { .. } => 10203, + Self::InvalidDataContractIdError { .. } => 10204, + Self::InvalidIndexedPropertyConstraintError { .. } => 10205, + Self::InvalidIndexPropertyTypeError { .. } => 10206, + Self::InvalidJsonSchemaRefError { .. } => 10207, + Self::SystemPropertyIndexAlreadyPresentError { .. } => 10208, + Self::UndefinedIndexPropertyError { .. } => 10209, + Self::UniqueIndicesLimitReachedError { .. } => 10210, + Self::DuplicateIndexNameError { .. } => 10211, + Self::InvalidDataContractVersionError { .. } => 10212, + Self::IncompatibleDataContractSchemaError { .. } => 10213, + Self::DataContractEmptySchemaError { .. } => 10214, + Self::DataContractImmutablePropertiesUpdateError { .. } => 10215, + Self::DataContractUniqueIndicesChangedError { .. } => 10216, + Self::DataContractInvalidIndexDefinitionUpdateError { .. } => 10217, + Self::DataContractHaveNewUniqueIndexError { .. } => 10218, + Self::InvalidDocumentTypeRequiredSecurityLevelError { .. } => 10219, + Self::UnknownSecurityLevelError { .. } => 10220, + Self::UnknownStorageKeyRequirementsError { .. } => 10221, + Self::ContractError(DataContractError::DecodingContractError { .. }) => 10222, + Self::ContractError(DataContractError::DecodingDocumentError { .. }) => 10223, + Self::ContractError(DataContractError::InvalidDocumentTypeError { .. }) => 10224, + Self::ContractError(DataContractError::MissingRequiredKey(_)) => 10225, + Self::ContractError(DataContractError::FieldRequirementUnmet(_)) => 10226, + Self::ContractError(DataContractError::KeyWrongType(_)) => 10227, + Self::ContractError(DataContractError::ValueWrongType(_)) => 10228, + Self::ContractError(DataContractError::ValueDecodingError(_)) => 10229, + Self::ContractError(DataContractError::EncodingDataStructureNotSupported(_)) => 10230, + Self::ContractError(DataContractError::InvalidContractStructure(_)) => 10231, + Self::ContractError(DataContractError::DocumentTypeNotFound(_)) => 10232, + Self::ContractError(DataContractError::DocumentTypeFieldNotFound(_)) => 10233, + Self::ContractError(DataContractError::ReferenceDefinitionNotFound(_)) => 10234, + Self::ContractError(DataContractError::DocumentOwnerIdMissing(_)) => 10235, + Self::ContractError(DataContractError::DocumentIdMissing(_)) => 10236, + Self::ContractError(DataContractError::Unsupported(_)) => 10237, + Self::ContractError(DataContractError::CorruptedSerialization(_)) => 10238, + Self::ContractError(DataContractError::JsonSchema(_)) => 10239, + Self::ContractError(DataContractError::InvalidURI(_)) => 10240, + Self::ContractError(DataContractError::KeyWrongBounds(_)) => 10241, + Self::ContractError(DataContractError::KeyValueMustExist(_)) => 10242, + + // Document Errors: 10400-10499 + Self::DataContractNotPresentError { .. } => 10400, + Self::DuplicateDocumentTransitionsWithIdsError { .. } => 10401, + Self::DuplicateDocumentTransitionsWithIndicesError { .. } => 10402, + Self::InconsistentCompoundIndexDataError { .. } => 10403, + Self::InvalidDocumentTransitionActionError { .. } => 10404, + Self::InvalidDocumentTransitionIdError { .. } => 10405, + Self::InvalidDocumentTypeError { .. } => 10406, + Self::MissingDataContractIdBasicError { .. } => 10407, + Self::MissingDocumentTransitionActionError { .. } => 10408, + Self::MissingDocumentTransitionTypeError { .. } => 10409, + Self::MissingDocumentTypeError { .. } => 10410, + Self::MissingPositionsInDocumentTypePropertiesError { .. } => 10411, + Self::MaxDocumentsTransitionsExceededError { .. } => 10412, + Self::DocumentTransitionsAreAbsentError { .. } => 10413, + Self::IdentityContractNonceOutOfBoundsError(_) => 10414, + + // Identity Errors: 10500-10599 + Self::DuplicatedIdentityPublicKeyBasicError(_) => 10500, + Self::DuplicatedIdentityPublicKeyIdBasicError(_) => 10501, + Self::IdentityAssetLockProofLockedTransactionMismatchError(_) => 10502, + Self::IdentityAssetLockTransactionIsNotFoundError(_) => 10503, + Self::IdentityAssetLockTransactionOutPointAlreadyExistsError(_) => 10504, + Self::IdentityAssetLockTransactionOutputNotFoundError(_) => 10505, + Self::InvalidAssetLockProofCoreChainHeightError(_) => 10506, + Self::InvalidAssetLockProofTransactionHeightError(_) => 10507, + Self::InvalidAssetLockTransactionOutputReturnSizeError(_) => 10508, + Self::InvalidIdentityAssetLockTransactionError(_) => 10509, + Self::InvalidIdentityAssetLockTransactionOutputError(_) => 10510, + Self::InvalidIdentityPublicKeyDataError(_) => 10511, + Self::InvalidInstantAssetLockProofError(_) => 10512, + Self::InvalidInstantAssetLockProofSignatureError(_) => 10513, + Self::InvalidIdentityAssetLockProofChainLockValidationError(_) => 10514, + Self::DataContractBoundsNotPresentError(_) => 10515, + Self::DisablingKeyIdAlsoBeingAddedInSameTransitionError(_) => 10516, + Self::MissingMasterPublicKeyError(_) => 10517, + Self::TooManyMasterPublicKeyError(_) => 10518, + Self::InvalidIdentityPublicKeySecurityLevelError(_) => 10519, + Self::InvalidIdentityKeySignatureError { .. } => 10520, + Self::InvalidIdentityCreditWithdrawalTransitionOutputScriptError(_) => 10521, + Self::InvalidIdentityCreditWithdrawalTransitionCoreFeeError(_) => 10522, + Self::NotImplementedIdentityCreditWithdrawalTransitionPoolingError(_) => 10523, + Self::InvalidIdentityCreditTransferAmountError(_) => 10524, + Self::InvalidIdentityCreditWithdrawalTransitionAmountError(_) => 10525, + Self::InvalidIdentityUpdateTransitionEmptyError(_) => 10526, + Self::InvalidIdentityUpdateTransitionDisableKeysError(_) => 10527, + Self::IdentityCreditTransferToSelfError(_) => 10528, + Self::MasterPublicKeyUpdateError(_) => 10529, + + // State Transition Errors: 10600-10699 + Self::InvalidStateTransitionTypeError { .. } => 10600, + Self::MissingStateTransitionTypeError { .. } => 10601, + Self::StateTransitionMaxSizeExceededError { .. } => 10602, } } } @@ -149,17 +148,18 @@ impl ErrorWithCode for BasicError { impl ErrorWithCode for SignatureError { fn code(&self) -> u32 { match self { - Self::IdentityNotFoundError { .. } => 2000, - Self::InvalidIdentityPublicKeyTypeError { .. } => 2001, - Self::InvalidStateTransitionSignatureError { .. } => 2002, - Self::MissingPublicKeyError { .. } => 2003, - Self::InvalidSignaturePublicKeySecurityLevelError { .. } => 2004, - Self::WrongPublicKeyPurposeError { .. } => 2005, - Self::PublicKeyIsDisabledError { .. } => 2006, - Self::PublicKeySecurityLevelNotMetError { .. } => 2007, - Self::SignatureShouldNotBePresentError(_) => 2008, - Self::BasicECDSAError(_) => 2009, - Self::BasicBLSError(_) => 2010, + Self::IdentityNotFoundError { .. } => 20000, + Self::InvalidIdentityPublicKeyTypeError { .. } => 20001, + Self::InvalidStateTransitionSignatureError { .. } => 20002, + Self::MissingPublicKeyError { .. } => 20003, + Self::InvalidSignaturePublicKeySecurityLevelError { .. } => 20004, + Self::WrongPublicKeyPurposeError { .. } => 20005, + Self::PublicKeyIsDisabledError { .. } => 20006, + Self::PublicKeySecurityLevelNotMetError { .. } => 20007, + Self::SignatureShouldNotBePresentError(_) => 20008, + Self::BasicECDSAError(_) => 20009, + Self::BasicBLSError(_) => 20010, + Self::InvalidSignaturePublicKeyPurposeError(_) => 20011, } } } @@ -167,7 +167,7 @@ impl ErrorWithCode for SignatureError { impl ErrorWithCode for FeeError { fn code(&self) -> u32 { match self { - Self::BalanceIsNotEnoughError { .. } => 3000, + Self::BalanceIsNotEnoughError { .. } => 30000, } } } @@ -175,38 +175,40 @@ impl ErrorWithCode for FeeError { impl ErrorWithCode for StateError { fn code(&self) -> u32 { match self { - // Data contract - Self::DataContractAlreadyPresentError { .. } => 4000, - Self::DataContractIsReadonlyError { .. } => 4026, + // Data contract Errors: 40000-40099 + Self::DataContractAlreadyPresentError { .. } => 40000, + Self::DataContractIsReadonlyError { .. } => 40001, + Self::DataContractConfigUpdateError { .. } => 40002, + + // Document Errors: 40100-40199 + Self::DocumentAlreadyPresentError { .. } => 40100, + Self::DocumentNotFoundError { .. } => 40101, + Self::DocumentOwnerIdMismatchError { .. } => 40102, + Self::DocumentTimestampsMismatchError { .. } => 40103, + Self::DocumentTimestampWindowViolationError { .. } => 40104, + Self::DuplicateUniqueIndexError { .. } => 40105, + Self::InvalidDocumentRevisionError { .. } => 40106, + Self::DocumentTimestampsAreEqualError(_) => 40107, + + // Identity Errors: 40200-40299 + Self::IdentityAlreadyExistsError(_) => 40200, + Self::IdentityPublicKeyIsReadOnlyError { .. } => 40201, + Self::InvalidIdentityPublicKeyIdError { .. } => 40202, + Self::InvalidIdentityRevisionError { .. } => 40203, + Self::InvalidIdentityNonceError(_) => 40204, + Self::MaxIdentityPublicKeyLimitReachedError { .. } => 40205, + Self::DuplicatedIdentityPublicKeyStateError { .. } => 40206, + Self::DuplicatedIdentityPublicKeyIdStateError { .. } => 40207, + Self::IdentityPublicKeyIsDisabledError { .. } => 40208, + Self::MissingIdentityPublicKeyIdsError { .. } => 40209, + Self::IdentityInsufficientBalanceError(_) => 40210, + Self::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError(_) => 40211, + Self::InvalidAssetLockProofValueError(_) => 40212, + Self::DocumentTypeUpdateError(_) => 40213, + + // Data trigger errors: 40500-40799 #[cfg(feature = "state-transition-validation")] Self::DataTriggerError(ref e) => e.code(), - Self::DataContractConfigUpdateError { .. } => 4027, - - // Document - Self::DocumentAlreadyPresentError { .. } => 4004, - Self::DocumentNotFoundError { .. } => 4005, - Self::DocumentOwnerIdMismatchError { .. } => 4006, - Self::DocumentTimestampsMismatchError { .. } => 4007, - Self::DocumentTimestampWindowViolationError { .. } => 4008, - Self::DuplicateUniqueIndexError { .. } => 4009, - Self::InvalidDocumentRevisionError { .. } => 4010, - Self::DocumentTimestampsAreEqualError(_) => 4031, - - // Identity - Self::IdentityAlreadyExistsError(_) => 4011, - Self::IdentityPublicKeyIsReadOnlyError { .. } => 4017, - Self::InvalidIdentityPublicKeyIdError { .. } => 4018, - Self::InvalidIdentityRevisionError { .. } => 4019, - Self::InvalidIdentityNonceError(_) => 4020, - Self::MaxIdentityPublicKeyLimitReachedError { .. } => 4021, - Self::DuplicatedIdentityPublicKeyStateError { .. } => 4022, - Self::DuplicatedIdentityPublicKeyIdStateError { .. } => 4023, - Self::IdentityPublicKeyIsDisabledError { .. } => 4024, - Self::MissingIdentityPublicKeyIdsError { .. } => 4025, - Self::IdentityInsufficientBalanceError(_) => 4026, - Self::IdentityPublicKeyAlreadyExistsForUniqueContractBoundsError(_) => 4028, - Self::InvalidAssetLockProofValueError(_) => 4029, - Self::DocumentTypeUpdateError(_) => 4030, } } } @@ -215,9 +217,9 @@ impl ErrorWithCode for StateError { impl ErrorWithCode for DataTriggerError { fn code(&self) -> u32 { match self { - Self::DataTriggerConditionError { .. } => 4001, - Self::DataTriggerExecutionError { .. } => 4002, - Self::DataTriggerInvalidResultError { .. } => 4003, + Self::DataTriggerConditionError { .. } => 40500, + Self::DataTriggerExecutionError { .. } => 40501, + Self::DataTriggerInvalidResultError { .. } => 40502, } } } diff --git a/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_purpose_error.rs b/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_purpose_error.rs new file mode 100644 index 0000000000..55a0596439 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/signature/invalid_signature_public_key_purpose_error.rs @@ -0,0 +1,47 @@ +use thiserror::Error; + +use crate::consensus::signature::signature_error::SignatureError; +use crate::consensus::ConsensusError; +use crate::identity::Purpose; + +use crate::errors::ProtocolError; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; + +use bincode::{Decode, Encode}; + +#[derive( + Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize, +)] +#[error("Invalid public key purpose {public_key_purpose}. The state transition requires {allowed_key_purpose}")] +#[platform_serialize(unversioned)] +pub struct InvalidSignaturePublicKeyPurposeError { + /* + + DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + + */ + public_key_purpose: Purpose, + allowed_key_purpose: Purpose, +} + +impl InvalidSignaturePublicKeyPurposeError { + pub fn new(public_key_purpose: Purpose, allowed_key_purpose: Purpose) -> Self { + Self { + public_key_purpose, + allowed_key_purpose, + } + } + + pub fn public_key_purpose(&self) -> Purpose { + self.public_key_purpose + } + pub fn allowed_key_purpose(&self) -> Purpose { + self.allowed_key_purpose + } +} + +impl From for ConsensusError { + fn from(err: InvalidSignaturePublicKeyPurposeError) -> Self { + Self::SignatureError(SignatureError::InvalidSignaturePublicKeyPurposeError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/signature/mod.rs b/packages/rs-dpp/src/errors/consensus/signature/mod.rs index 37be8d8a87..46c0b6282a 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/mod.rs @@ -2,6 +2,7 @@ mod basic_bls_error; mod basic_ecdsa_error; mod identity_not_found_error; mod invalid_identity_public_key_type_error; +mod invalid_signature_public_key_purpose_error; mod invalid_signature_public_key_security_level_error; mod invalid_state_transition_signature_error; mod missing_public_key_error; @@ -15,6 +16,7 @@ pub use crate::consensus::signature::basic_bls_error::BasicBLSError; pub use crate::consensus::signature::basic_ecdsa_error::BasicECDSAError; pub use crate::consensus::signature::identity_not_found_error::IdentityNotFoundError; pub use crate::consensus::signature::invalid_identity_public_key_type_error::InvalidIdentityPublicKeyTypeError; +pub use crate::consensus::signature::invalid_signature_public_key_purpose_error::InvalidSignaturePublicKeyPurposeError; pub use crate::consensus::signature::invalid_signature_public_key_security_level_error::InvalidSignaturePublicKeySecurityLevelError; pub use crate::consensus::signature::invalid_state_transition_signature_error::InvalidStateTransitionSignatureError; pub use crate::consensus::signature::missing_public_key_error::MissingPublicKeyError; diff --git a/packages/rs-dpp/src/errors/consensus/signature/signature_error.rs b/packages/rs-dpp/src/errors/consensus/signature/signature_error.rs index af4047782d..74b2c6a724 100644 --- a/packages/rs-dpp/src/errors/consensus/signature/signature_error.rs +++ b/packages/rs-dpp/src/errors/consensus/signature/signature_error.rs @@ -8,6 +8,7 @@ use crate::consensus::ConsensusError; use bincode::{Decode, Encode}; use thiserror::Error; +use crate::consensus::signature::invalid_signature_public_key_purpose_error::InvalidSignaturePublicKeyPurposeError; use crate::errors::ProtocolError; use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; @@ -30,6 +31,9 @@ pub enum SignatureError { #[error(transparent)] MissingPublicKeyError(MissingPublicKeyError), + #[error(transparent)] + InvalidSignaturePublicKeyPurposeError(InvalidSignaturePublicKeyPurposeError), + #[error(transparent)] InvalidSignaturePublicKeySecurityLevelError(InvalidSignaturePublicKeySecurityLevelError), diff --git a/packages/rs-dpp/src/errors/consensus/state/identity/master_public_key_update_error.rs b/packages/rs-dpp/src/errors/consensus/state/identity/master_public_key_update_error.rs new file mode 100644 index 0000000000..bde78547a7 --- /dev/null +++ b/packages/rs-dpp/src/errors/consensus/state/identity/master_public_key_update_error.rs @@ -0,0 +1,66 @@ +use crate::consensus::basic::BasicError; +use crate::consensus::ConsensusError; +use crate::errors::ProtocolError; +use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize}; +use thiserror::Error; + +use bincode::{Decode, Encode}; + +#[derive( + Error, + Debug, + Clone, + PartialEq, + Eq, + Default, + Encode, + Decode, + PlatformSerialize, + PlatformDeserialize, +)] +#[error("Failed to update the master public key: {description}. Ensure the operation is valid and permissible under current system rules.")] +#[platform_serialize(unversioned)] +pub struct MasterPublicKeyUpdateError { + adding: usize, + removing: usize, + description: String, +} + +/* + +DO NOT CHANGE ORDER OF FIELDS WITHOUT INTRODUCING OF NEW VERSION + +*/ + +impl MasterPublicKeyUpdateError { + pub fn new(adding: usize, removing: usize) -> Self { + let description = match (adding, removing) { + (1, _) => "Attempt to add a new master key is not allowed unless one is being disabled" + .to_string(), + (0, _) => "Removing a master key without adding one is not allowed".to_string(), + (_, 1) | (_, 0) => "Attempt to add more than one master key is not allowed".to_string(), + (adding, removing) => format!( + "Attempting to add {adding} master keys while removing {removing} master keys" + ), + }; + + Self { + adding, + removing, + description, + } + } + + pub fn adding(&self) -> usize { + self.adding + } + + pub fn removing(&self) -> usize { + self.removing + } +} +impl From for ConsensusError { + fn from(err: MasterPublicKeyUpdateError) -> Self { + Self::BasicError(BasicError::MasterPublicKeyUpdateError(err)) + } +} diff --git a/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs b/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs index 178b283855..71209abf21 100644 --- a/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs +++ b/packages/rs-dpp/src/errors/consensus/state/identity/mod.rs @@ -12,5 +12,6 @@ pub mod invalid_asset_lock_proof_value; pub mod invalid_identity_contract_nonce_error; pub mod invalid_identity_public_key_id_error; pub mod invalid_identity_revision_error; +pub mod master_public_key_update_error; pub mod max_identity_public_key_limit_reached_error; pub mod missing_identity_public_key_ids_error; diff --git a/packages/rs-dpp/src/identity/identity_public_key/purpose.rs b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs index be9a491177..3d47322d2e 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/purpose.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/purpose.rs @@ -1,4 +1,4 @@ -use crate::identity::Purpose::{AUTHENTICATION, DECRYPTION, ENCRYPTION, SYSTEM, VOTING, WITHDRAW}; +use crate::identity::Purpose::{AUTHENTICATION, DECRYPTION, ENCRYPTION, SYSTEM, TRANSFER, VOTING}; use anyhow::bail; use bincode::{Decode, Encode}; #[cfg(feature = "cbor")] @@ -31,14 +31,33 @@ pub enum Purpose { ENCRYPTION = 1, /// this key cannot be used for signing documents DECRYPTION = 2, - /// this key cannot be used for signing documents - WITHDRAW = 3, + /// this key is used to sign credit transfer and withdrawal state transitions + TRANSFER = 3, /// this key cannot be used for signing documents SYSTEM = 4, /// this key cannot be used for signing documents VOTING = 5, } +impl From for [u8; 1] { + fn from(purpose: Purpose) -> Self { + [purpose as u8] + } +} + +impl From for &'static [u8; 1] { + fn from(purpose: Purpose) -> Self { + match purpose { + AUTHENTICATION => &[0], + ENCRYPTION => &[1], + DECRYPTION => &[2], + TRANSFER => &[3], + SYSTEM => &[4], + VOTING => &[5], + } + } +} + impl TryFrom for Purpose { type Error = anyhow::Error; fn try_from(value: u8) -> Result { @@ -46,7 +65,7 @@ impl TryFrom for Purpose { 0 => Ok(AUTHENTICATION), 1 => Ok(ENCRYPTION), 2 => Ok(DECRYPTION), - 3 => Ok(WITHDRAW), + 3 => Ok(TRANSFER), 4 => Ok(SYSTEM), 5 => Ok(VOTING), value => bail!("unrecognized purpose: {}", value), @@ -69,11 +88,11 @@ impl std::fmt::Display for Purpose { impl Purpose { /// The full range of purposes pub fn full_range() -> [Purpose; 4] { - [AUTHENTICATION, ENCRYPTION, DECRYPTION, WITHDRAW] + [AUTHENTICATION, ENCRYPTION, DECRYPTION, TRANSFER] } /// Just the authentication and withdraw purposes - pub fn authentication_withdraw() -> [Purpose; 2] { - [AUTHENTICATION, WITHDRAW] + pub fn authentication_and_transfer() -> [Purpose; 2] { + [AUTHENTICATION, TRANSFER] } /// Just the encryption and decryption purposes pub fn encryption_decryption() -> [Purpose; 2] { @@ -81,6 +100,6 @@ impl Purpose { } /// The last purpose pub fn last() -> Purpose { - Self::WITHDRAW + Self::TRANSFER } } diff --git a/packages/rs-dpp/src/identity/identity_public_key/random.rs b/packages/rs-dpp/src/identity/identity_public_key/random.rs index 80c28b9829..ca8543c184 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/random.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/random.rs @@ -1,6 +1,6 @@ use crate::identity::identity_public_key::v0::IdentityPublicKeyV0; -use crate::identity::{IdentityPublicKey, KeyCount, KeyID}; +use crate::identity::{IdentityPublicKey, KeyCount, KeyID, KeyType, Purpose, SecurityLevel}; use crate::version::PlatformVersion; use crate::ProtocolError; @@ -243,6 +243,58 @@ impl IdentityPublicKey { } } + /// Generates a random key based on the platform version. + /// + /// # Parameters + /// + /// * `id`: The `KeyID` for the generated key. + /// * `rng`: A mutable reference to a random number generator of type `StdRng`. + /// * `used_key_matrix`: An optional tuple that contains the count of keys that have already been used + /// and a mutable reference to a matrix (or vector) that tracks which keys have been used. + /// * `platform_version`: The platform version which determines the structure of the identity key. + /// + /// # Returns + /// + /// * `Result`: If successful, returns an instance of `Self`. + /// In case of an error, it returns a `ProtocolError`. + /// + /// # Errors + /// + /// * `ProtocolError::PublicKeyGenerationError`: This error is returned if too many keys have already been created. + /// * `ProtocolError::UnknownVersionMismatch`: This error is returned if the provided platform version is not recognized. + /// + pub fn random_key_with_known_attributes( + id: KeyID, + rng: &mut StdRng, + purpose: Purpose, + security_level: SecurityLevel, + key_type: KeyType, + platform_version: &PlatformVersion, + ) -> Result<(Self, Vec), ProtocolError> { + match platform_version + .dpp + .identity_versions + .identity_key_structure_version + { + 0 => { + let (key, private_key) = IdentityPublicKeyV0::random_key_with_known_attributes( + id, + rng, + purpose, + security_level, + key_type, + platform_version, + )?; + Ok((key.into(), private_key)) + } + version => Err(ProtocolError::UnknownVersionMismatch { + method: "IdentityPublicKey::random_key_with_known_attributes".to_string(), + known_versions: vec![0], + received: version, + }), + } + } + /// Generates a random ECDSA master authentication public key along with its corresponding private key. /// /// This method constructs a random ECDSA (using the secp256k1 curve) master authentication public key @@ -287,6 +339,33 @@ impl IdentityPublicKey { } } + /// Generates a random ECDSA master-level authentication public key along with its corresponding private key. + /// + /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key + /// and returns both the public key and its corresponding private key. + /// + /// # Parameters + /// + /// * `id`: The `KeyID` for the generated key. + /// * `seed`: A seed that will create a random number generator `StdRng`. + /// + /// # Returns + /// + /// * `(Self, Vec)`: A tuple where the first element is an instance of the `IdentityPublicKey` struct, + /// and the second element is the corresponding private key. + /// + pub fn random_ecdsa_master_authentication_key( + id: KeyID, + seed: Option, + platform_version: &PlatformVersion, + ) -> Result<(Self, Vec), ProtocolError> { + let mut rng = match seed { + None => StdRng::from_entropy(), + Some(seed_value) => StdRng::seed_from_u64(seed_value), + }; + Self::random_ecdsa_master_authentication_key_with_rng(id, &mut rng, platform_version) + } + /// Generates a random ECDSA critical-level authentication public key along with its corresponding private key. /// /// This method constructs a random ECDSA (using the secp256k1 curve) high-level authentication public key @@ -507,6 +586,9 @@ impl IdentityPublicKey { used_key_matrix[0] = true; used_key_matrix[1] = true; used_key_matrix[2] = true; + used_key_matrix[4] = true; //also a master key + used_key_matrix[8] = true; //also a master key + used_key_matrix[12] = true; //also a master key main_keys.extend((3..key_count).map(|i| { Self::random_authentication_key_with_private_key_with_rng( i, diff --git a/packages/rs-dpp/src/identity/identity_public_key/v0/random.rs b/packages/rs-dpp/src/identity/identity_public_key/v0/random.rs index 29c1cea85b..2ba6c75e02 100644 --- a/packages/rs-dpp/src/identity/identity_public_key/v0/random.rs +++ b/packages/rs-dpp/src/identity/identity_public_key/v0/random.rs @@ -115,6 +115,31 @@ impl IdentityPublicKeyV0 { )) } + pub fn random_key_with_known_attributes( + id: KeyID, + rng: &mut StdRng, + purpose: Purpose, + security_level: SecurityLevel, + key_type: KeyType, + platform_version: &PlatformVersion, + ) -> Result<(Self, Vec), ProtocolError> { + let read_only = false; + let (public_data, private_data) = + key_type.random_public_and_private_key_data(rng, platform_version)?; + let data = BinaryData::new(public_data); + let identity_public_key = IdentityPublicKeyV0 { + id, + key_type, + purpose, + security_level, + read_only, + disabled_at: None, + data, + contract_bounds: None, + }; + Ok((identity_public_key, private_data)) + } + pub fn random_key_with_rng( id: KeyID, rng: &mut StdRng, diff --git a/packages/rs-dpp/src/serialization/serialization_traits.rs b/packages/rs-dpp/src/serialization/serialization_traits.rs index ced6d61b98..db57810d48 100644 --- a/packages/rs-dpp/src/serialization/serialization_traits.rs +++ b/packages/rs-dpp/src/serialization/serialization_traits.rs @@ -172,7 +172,7 @@ pub trait PlatformMessageSignable { public_key_type: KeyType, public_key_data: &[u8], signature: &[u8], - ) -> Result; + ) -> SimpleConsensusValidationResult; #[cfg(feature = "message-signing")] fn sign_by_private_key( diff --git a/packages/rs-dpp/src/signing.rs b/packages/rs-dpp/src/signing.rs index d63b6db0d6..96c810ff36 100644 --- a/packages/rs-dpp/src/signing.rs +++ b/packages/rs-dpp/src/signing.rs @@ -7,8 +7,7 @@ use crate::serialization::PlatformMessageSignable; #[cfg(feature = "message-signature-verification")] use crate::validation::SimpleConsensusValidationResult; #[cfg(feature = "message-signing")] -use crate::BlsModule; -use crate::ProtocolError; +use crate::{BlsModule, ProtocolError}; use dashcore::signer; impl PlatformMessageSignable for &[u8] { @@ -18,7 +17,7 @@ impl PlatformMessageSignable for &[u8] { public_key_type: KeyType, public_key_data: &[u8], signature: &[u8], - ) -> Result { + ) -> SimpleConsensusValidationResult { let signable_data = self; match public_key_type { KeyType::ECDSA_SECP256K1 => { @@ -31,11 +30,11 @@ impl PlatformMessageSignable for &[u8] { // hex::encode(signable_data), // hex::encode(public_key_data) // )); - Ok(SimpleConsensusValidationResult::new_with_error( + SimpleConsensusValidationResult::new_with_error( SignatureError::BasicECDSAError(BasicECDSAError::new(e.to_string())).into(), - )) + ) } else { - Ok(SimpleConsensusValidationResult::default()) + SimpleConsensusValidationResult::default() } } KeyType::BLS12_381 => { @@ -43,61 +42,61 @@ impl PlatformMessageSignable for &[u8] { Ok(public_key) => public_key, Err(e) => { // dbg!(format!("bls public_key could not be recovered")); - return Ok(SimpleConsensusValidationResult::new_with_error( + return SimpleConsensusValidationResult::new_with_error( SignatureError::BasicBLSError(BasicBLSError::new(e.to_string())).into(), - )); + ); } }; let signature = match bls_signatures::Signature::from_bytes(signature) { Ok(public_key) => public_key, Err(e) => { // dbg!(format!("bls signature could not be recovered")); - return Ok(SimpleConsensusValidationResult::new_with_error( + return SimpleConsensusValidationResult::new_with_error( SignatureError::BasicBLSError(BasicBLSError::new(e.to_string())).into(), - )); + ); } }; if !public_key.verify(&signature, signable_data) { - Ok(SimpleConsensusValidationResult::new_with_error( + SimpleConsensusValidationResult::new_with_error( SignatureError::BasicBLSError(BasicBLSError::new( "bls signature was incorrect".to_string(), )) .into(), - )) + ) } else { - Ok(SimpleConsensusValidationResult::default()) + SimpleConsensusValidationResult::default() } } KeyType::ECDSA_HASH160 => { if !signature.is_empty() { - Ok(SimpleConsensusValidationResult::new_with_error( + SimpleConsensusValidationResult::new_with_error( SignatureError::SignatureShouldNotBePresentError( SignatureShouldNotBePresentError::new("ecdsa_hash160 keys should not have a signature as that would reveal the public key".to_string()), ).into() - )) + ) } else { - Ok(SimpleConsensusValidationResult::default()) + SimpleConsensusValidationResult::default() } } KeyType::BIP13_SCRIPT_HASH => { if !signature.is_empty() { - Ok(SimpleConsensusValidationResult::new_with_error( + SimpleConsensusValidationResult::new_with_error( SignatureError::SignatureShouldNotBePresentError( SignatureShouldNotBePresentError::new("script hash keys should not have a signature as that would reveal the script".to_string()) - ).into())) + ).into()) } else { - Ok(SimpleConsensusValidationResult::default()) + SimpleConsensusValidationResult::default() } } KeyType::EDDSA_25519_HASH160 => { if !signature.is_empty() { - Ok(SimpleConsensusValidationResult::new_with_error( + SimpleConsensusValidationResult::new_with_error( SignatureError::SignatureShouldNotBePresentError( SignatureShouldNotBePresentError::new("eddsa hash 160 keys should not have a signature as that would reveal the script".to_string()) ).into() - )) + ) } else { - Ok(SimpleConsensusValidationResult::default()) + SimpleConsensusValidationResult::default() } } } diff --git a/packages/rs-dpp/src/state_transition/mod.rs b/packages/rs-dpp/src/state_transition/mod.rs index 1102f63335..0ca096ab50 100644 --- a/packages/rs-dpp/src/state_transition/mod.rs +++ b/packages/rs-dpp/src/state_transition/mod.rs @@ -57,7 +57,6 @@ use crate::identity::identity_public_key::accessors::v0::IdentityPublicKeyGetter #[cfg(feature = "state-transition-signing")] use crate::identity::signer::Signer; use crate::identity::state_transition::OptionallyAssetLockProved; -#[cfg(feature = "state-transition-signing")] use crate::identity::Purpose; #[cfg(any( feature = "state-transition-signing", @@ -332,11 +331,16 @@ impl StateTransition { call_getter_method_identity_signed!(self, signature_public_key_id) } - /// returns the security level requirement for the state transition + /// returns the key security level requirement for the state transition pub fn security_level_requirement(&self) -> Option> { call_getter_method_identity_signed!(self, security_level_requirement) } + /// returns the key purpose requirement for the state transition + pub fn purpose_requirement(&self) -> Option { + call_getter_method_identity_signed!(self, purpose_requirement) + } + /// returns the signature as a byte-array pub fn owner_id(&self) -> Identifier { call_method!(self, owner_id) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/identity_signed.rs index 5aec8aea2e..c7b4464dec 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/contract/data_contract_create_transition/v0/identity_signed.rs @@ -1,4 +1,4 @@ -use crate::identity::SecurityLevel::CRITICAL; +use crate::identity::SecurityLevel::{CRITICAL, HIGH}; use crate::identity::{KeyID, SecurityLevel}; use crate::state_transition::data_contract_create_transition::DataContractCreateTransitionV0; use crate::state_transition::StateTransitionIdentitySigned; @@ -13,6 +13,6 @@ impl StateTransitionIdentitySigned for DataContractCreateTransitionV0 { } fn security_level_requirement(&self) -> Vec { - vec![CRITICAL] + vec![CRITICAL, HIGH] } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/identity_signed.rs index 0100b34f87..4b3b448eb5 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/identity_signed.rs @@ -1,4 +1,4 @@ -use crate::identity::{KeyID, SecurityLevel}; +use crate::identity::{KeyID, Purpose, SecurityLevel}; use crate::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; use crate::state_transition::StateTransitionIdentitySigned; @@ -26,4 +26,10 @@ impl StateTransitionIdentitySigned for IdentityCreditTransferTransition { } } } + + fn purpose_requirement(&self) -> Purpose { + match self { + IdentityCreditTransferTransition::V0(transition) => transition.purpose_requirement(), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/identity_signed.rs index bee0594ba1..bcab635e22 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_transfer_transition/v0/identity_signed.rs @@ -1,5 +1,5 @@ use crate::identity::SecurityLevel::CRITICAL; -use crate::identity::{KeyID, SecurityLevel}; +use crate::identity::{KeyID, Purpose, SecurityLevel}; use crate::state_transition::identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0; use crate::state_transition::StateTransitionIdentitySigned; @@ -15,4 +15,8 @@ impl StateTransitionIdentitySigned for IdentityCreditTransferTransitionV0 { fn security_level_requirement(&self) -> Vec { vec![CRITICAL] } + + fn purpose_requirement(&self) -> Purpose { + Purpose::TRANSFER + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/identity_signed.rs index 1455089e1e..2dd369f3b3 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/identity_signed.rs @@ -1,4 +1,4 @@ -use crate::identity::{KeyID, SecurityLevel}; +use crate::identity::{KeyID, Purpose, SecurityLevel}; use crate::state_transition::identity_credit_withdrawal_transition::IdentityCreditWithdrawalTransition; use crate::state_transition::StateTransitionIdentitySigned; @@ -26,4 +26,10 @@ impl StateTransitionIdentitySigned for IdentityCreditWithdrawalTransition { } } } + + fn purpose_requirement(&self) -> Purpose { + match self { + IdentityCreditWithdrawalTransition::V0(transition) => transition.purpose_requirement(), + } + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/identity_signed.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/identity_signed.rs index 7207aa59e2..2c8011f2fd 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/identity_signed.rs @@ -1,5 +1,5 @@ use crate::identity::SecurityLevel::CRITICAL; -use crate::identity::{KeyID, SecurityLevel}; +use crate::identity::{KeyID, Purpose, SecurityLevel}; use crate::state_transition::identity_credit_withdrawal_transition::v0::IdentityCreditWithdrawalTransitionV0; use crate::state_transition::StateTransitionIdentitySigned; @@ -16,4 +16,8 @@ impl StateTransitionIdentitySigned for IdentityCreditWithdrawalTransitionV0 { fn security_level_requirement(&self) -> Vec { vec![CRITICAL] } + + fn purpose_requirement(&self) -> Purpose { + Purpose::TRANSFER + } } diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/v0_methods.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/v0_methods.rs index 8824c15498..53200c82e9 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/v0_methods.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/identity_credit_withdrawal_transition/v0/v0_methods.rs @@ -49,7 +49,7 @@ impl IdentityCreditWithdrawalTransitionMethodsV0 for IdentityCreditWithdrawalTra let identity_public_key = identity .get_first_public_key_matching( - Purpose::WITHDRAW, + Purpose::TRANSFER, SecurityLevel::full_range().into(), KeyType::all_key_types().into(), ) diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/mod.rs index f186a2e424..e002fffb27 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/mod.rs @@ -8,6 +8,7 @@ pub mod v0; impl IdentityPublicKeyInCreation { pub fn validate_identity_public_keys_structure( identity_public_keys_with_witness: &[IdentityPublicKeyInCreation], + in_create_identity: bool, platform_version: &PlatformVersion, ) -> Result { match platform_version @@ -18,6 +19,7 @@ impl IdentityPublicKeyInCreation { { 0 => Self::validate_identity_public_keys_structure_v0( identity_public_keys_with_witness, + in_create_identity, platform_version, ), version => Err(ProtocolError::UnknownVersionMismatch { diff --git a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs index 6751461f62..4319b9a676 100644 --- a/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs +++ b/packages/rs-dpp/src/state_transition/state_transitions/identity/public_key_in_creation/methods/validate_identity_public_keys_structure/v0/mod.rs @@ -1,11 +1,12 @@ use crate::consensus::basic::identity::{ - DuplicatedIdentityPublicKeyIdBasicError, InvalidIdentityPublicKeySecurityLevelError, + DuplicatedIdentityPublicKeyBasicError, DuplicatedIdentityPublicKeyIdBasicError, + InvalidIdentityPublicKeySecurityLevelError, MissingMasterPublicKeyError, + TooManyMasterPublicKeyError, }; use crate::consensus::basic::BasicError; use lazy_static::lazy_static; use std::collections::HashMap; -use crate::consensus::state::identity::duplicated_identity_public_key_state_error::DuplicatedIdentityPublicKeyStateError; use crate::consensus::state::identity::max_identity_public_key_limit_reached_error::MaxIdentityPublicKeyLimitReachedError; use crate::consensus::state::state_error::StateError; @@ -33,7 +34,7 @@ lazy_static! { ); m.insert(Purpose::ENCRYPTION, vec![SecurityLevel::MEDIUM]); m.insert(Purpose::DECRYPTION, vec![SecurityLevel::MEDIUM]); - m.insert(Purpose::WITHDRAW, vec![SecurityLevel::CRITICAL]); + m.insert(Purpose::TRANSFER, vec![SecurityLevel::CRITICAL]); m }; } @@ -43,6 +44,7 @@ impl IdentityPublicKeyInCreation { /// attack vectors. pub(super) fn validate_identity_public_keys_structure_v0( identity_public_keys_with_witness: &[IdentityPublicKeyInCreation], + in_create_identity: bool, platform_version: &PlatformVersion, ) -> Result { if identity_public_keys_with_witness.len() > MAX_PUBLIC_KEYS { @@ -75,13 +77,33 @@ impl IdentityPublicKeyInCreation { )?; if !duplicated_key_ids.is_empty() { return Ok(SimpleConsensusValidationResult::new_with_error( - StateError::DuplicatedIdentityPublicKeyStateError( - DuplicatedIdentityPublicKeyStateError::new(duplicated_key_ids), + BasicError::DuplicatedIdentityPublicKeyBasicError( + DuplicatedIdentityPublicKeyBasicError::new(duplicated_key_ids), ) .into(), )); } + if in_create_identity { + // We should check that we are only adding one master authentication key + + let master_key_count = identity_public_keys_with_witness + .iter() + .filter(|key| key.security_level() == SecurityLevel::MASTER) + .count(); + if master_key_count == 0 { + return Ok(SimpleConsensusValidationResult::new_with_error( + BasicError::MissingMasterPublicKeyError(MissingMasterPublicKeyError::new()) + .into(), + )); + } else if master_key_count > 1 { + return Ok(SimpleConsensusValidationResult::new_with_error( + BasicError::TooManyMasterPublicKeyError(TooManyMasterPublicKeyError::new()) + .into(), + )); + } + } + // We should check all the security levels let validation_errors = identity_public_keys_with_witness .iter() diff --git a/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs b/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs index 8e956af747..c81029a7fe 100644 --- a/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs +++ b/packages/rs-dpp/src/state_transition/traits/state_transition_identity_signed.rs @@ -22,7 +22,8 @@ use crate::state_transition::StateTransitionLike; feature = "state-transition-signing", feature = "state-transition-validation" ))] -use crate::identity::{IdentityPublicKey, Purpose}; +use crate::identity::IdentityPublicKey; +use crate::identity::Purpose; use crate::{ identity::{KeyID, SecurityLevel}, prelude::*, @@ -57,9 +58,9 @@ pub trait StateTransitionIdentitySigned: StateTransitionLike { )); } - if public_key.purpose() != Purpose::AUTHENTICATION { + if public_key.purpose() != self.purpose_requirement() { return Err(ProtocolError::WrongPublicKeyPurposeError( - WrongPublicKeyPurposeError::new(public_key.purpose(), Purpose::AUTHENTICATION), + WrongPublicKeyPurposeError::new(public_key.purpose(), self.purpose_requirement()), )); } Ok(()) @@ -85,6 +86,13 @@ pub trait StateTransitionIdentitySigned: StateTransitionLike { /// Returns minimal key security level that can be used to sign this ST. /// Override this method if the ST requires a different security level. fn security_level_requirement(&self) -> Vec; + + /// The purpose requirement for the signing key + /// The default is authentication + /// However for Withdrawals and Fund Transfers the requirement is TRANSFER + fn purpose_requirement(&self) -> Purpose { + Purpose::AUTHENTICATION + } } pub fn get_compressed_public_ec_key(private_key: &[u8]) -> Result<[u8; 33], ProtocolError> { diff --git a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs index 6a7d59032d..5914b0f48c 100644 --- a/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs @@ -1347,6 +1347,12 @@ mod tests { let mut rng = StdRng::seed_from_u64(567); + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key(0, Some(3), platform_version) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( 1, Some(19), @@ -1370,7 +1376,7 @@ mod tests { let identity: Identity = IdentityV0 { id: identifier, - public_keys: BTreeMap::from([(1, key.clone())]), + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), balance: 1000000000, revision: 0, } @@ -1526,6 +1532,12 @@ mod tests { let mut rng = StdRng::seed_from_u64(567); + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key(0, Some(3), platform_version) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( 1, Some(19), @@ -1549,7 +1561,7 @@ mod tests { let identity: Identity = IdentityV0 { id: identifier, - public_keys: BTreeMap::from([(1, key.clone())]), + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), balance: 1000000000, revision: 0, } @@ -1656,6 +1668,12 @@ mod tests { let mut rng = StdRng::seed_from_u64(567); + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key(0, Some(3), platform_version) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( 1, Some(19), @@ -1679,7 +1697,7 @@ mod tests { let identity: Identity = IdentityV0 { id: identifier, - public_keys: BTreeMap::from([(1, key.clone())]), + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), balance: 1000000000, revision: 0, } @@ -1910,6 +1928,12 @@ mod tests { let mut rng = StdRng::seed_from_u64(567); + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key(0, Some(3), platform_version) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( 1, Some(19), @@ -1933,7 +1957,7 @@ mod tests { let identity: Identity = IdentityV0 { id: identifier, - public_keys: BTreeMap::from([(1, key.clone())]), + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), balance: 1000000000, revision: 0, } @@ -2025,6 +2049,12 @@ mod tests { let mut signer = SimpleSigner::default(); + let (master_key, master_private_key) = + IdentityPublicKey::random_ecdsa_master_authentication_key(0, Some(4), platform_version) + .expect("expected to get key pair"); + + signer.add_key(master_key.clone(), master_private_key.clone()); + let (key, private_key) = IdentityPublicKey::random_ecdsa_critical_level_authentication_key( 1, Some(50), @@ -2040,7 +2070,7 @@ mod tests { let identity: Identity = IdentityV0 { id: identifier, - public_keys: BTreeMap::from([(1, key.clone())]), + public_keys: BTreeMap::from([(0, master_key.clone()), (1, key.clone())]), balance: 1000000000, revision: 0, } diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/disable_identity_keys/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/disable_identity_keys/v0/mod.rs index 91d385e98d..88b2ccbdf9 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/disable_identity_keys/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/disable_identity_keys/v0/mod.rs @@ -4,7 +4,7 @@ use crate::rpc::core::CoreRPCLike; use dashcore_rpc::dashcore_rpc_json::MasternodeListItem; use dpp::block::block_info::BlockInfo; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; -use dpp::identity::Purpose::WITHDRAW; +use dpp::identity::Purpose::TRANSFER; use dpp::version::PlatformVersion; use drive::drive::batch::DriveOperation; use drive::drive::batch::DriveOperation::IdentityOperation; @@ -62,7 +62,7 @@ where )? .into_iter() .filter_map(|(key_id, key)| { - if key.is_disabled() || key.purpose() == WITHDRAW { + if key.is_disabled() || key.purpose() == TRANSFER { None // Don't disable withdrawal keys } else { Some(key_id) diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_operator_identity_keys/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_operator_identity_keys/v0/mod.rs index 6df7c15c6e..ff3a889950 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_operator_identity_keys/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_operator_identity_keys/v0/mod.rs @@ -30,7 +30,7 @@ where IdentityPublicKeyV0 { id: 1, key_type: KeyType::ECDSA_HASH160, - purpose: Purpose::WITHDRAW, + purpose: Purpose::TRANSFER, security_level: SecurityLevel::CRITICAL, read_only: true, data: BinaryData::new(operator_payout_address.to_vec()), diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_owner_identity_key/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_owner_identity_key/v0/mod.rs index 03865a481c..eb478c5acc 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_owner_identity_key/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/get_owner_identity_key/v0/mod.rs @@ -16,7 +16,7 @@ where Ok(IdentityPublicKeyV0 { id: key_id, key_type: KeyType::ECDSA_HASH160, - purpose: Purpose::WITHDRAW, + purpose: Purpose::TRANSFER, security_level: SecurityLevel::CRITICAL, read_only: true, data: BinaryData::new(payout_address.to_vec()), diff --git a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/update_operator_identity/v0/mod.rs b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/update_operator_identity/v0/mod.rs index 68d9515b03..82e98c3477 100644 --- a/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/update_operator_identity/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/platform_events/core_based_updates/update_masternode_identities/update_operator_identity/v0/mod.rs @@ -14,7 +14,7 @@ use dpp::identity::accessors::IdentityGettersV0; use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; use dpp::identity::identity_public_key::v0::IdentityPublicKeyV0; -use dpp::identity::Purpose::WITHDRAW; +use dpp::identity::Purpose::TRANSFER; use dpp::identity::{Identity, IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; use dpp::platform_value::BinaryData; use dpp::version::PlatformVersion; @@ -59,7 +59,7 @@ where .ok_or_else(|| { Error::Execution(ExecutionError::CorruptedCachedState(format!( "expected masternode {} to be in state", - pro_tx_hash.to_string() + pro_tx_hash ))) })?; @@ -191,7 +191,7 @@ where let key = IdentityPublicKeyV0 { id: new_key_id, key_type: KeyType::ECDSA_HASH160, - purpose: WITHDRAW, + purpose: TRANSFER, security_level: SecurityLevel::CRITICAL, read_only: true, data: BinaryData::new(new_operator_payout_address.to_vec()), diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs index fa08af7a16..0e2e4b91b7 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/check_tx_verification/v0/mod.rs @@ -154,7 +154,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC None }; - // + // Validating signatures let result = state_transition.validate_identity_and_signatures( platform.drive, action.as_ref(), @@ -162,7 +162,7 @@ pub(super) fn state_transition_to_execution_event_for_check_tx_v0<'a, C: CoreRPC &mut state_transition_execution_context, platform_version, )?; - // Validating signatures + if !result.is_valid() { return Ok( ConsensusValidationResult::>::new_with_errors( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/mod.rs index c27af2cf33..bbd758939b 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/mod.rs @@ -3,5 +3,6 @@ pub mod asset_lock; pub mod validate_identity_public_key_contract_bounds; pub mod validate_identity_public_key_ids_dont_exist_in_state; pub mod validate_identity_public_key_ids_exist_in_state; +pub mod validate_not_disabling_last_master_key; pub mod validate_state_transition_identity_signed; pub mod validate_unique_identity_public_key_hashes_in_state; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/mod.rs index 933e1ec9c8..aa252d7d03 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/mod.rs @@ -1,6 +1,6 @@ use dpp::identifier::Identifier; -use dpp::identity::KeyID; -use dpp::validation::SimpleConsensusValidationResult; +use dpp::identity::{IdentityPublicKey, KeyID}; +use dpp::validation::ConsensusValidationResult; use drive::drive::Drive; use drive::grovedb::TransactionArg; use dpp::version::PlatformVersion; @@ -18,7 +18,7 @@ pub(crate) fn validate_identity_public_key_ids_exist_in_state( execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, -) -> Result { +) -> Result>, Error> { match platform_version .drive_abci .validation_and_processing diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/v0/mod.rs index 3751c64b84..6422faf196 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_identity_public_key_ids_exist_in_state/v0/mod.rs @@ -2,18 +2,18 @@ use crate::error::Error; use dpp::consensus::state::identity::missing_identity_public_key_ids_error::MissingIdentityPublicKeyIdsError; -use dpp::identity::KeyID; +use dpp::identity::{IdentityPublicKey, KeyID}; use dpp::platform_value::Identifier; +use dpp::prelude::ConsensusValidationResult; -use dpp::validation::SimpleConsensusValidationResult; - -use drive::drive::identity::key::fetch::{IdentityKeysRequest, KeyIDVec, KeyRequestType}; +use drive::drive::identity::key::fetch::{ + IdentityKeysRequest, KeyIDIdentityPublicKeyPairBTreeMap, KeyRequestType, +}; use drive::drive::Drive; use drive::grovedb::TransactionArg; use crate::execution::types::state_transition_execution_context::StateTransitionExecutionContext; use dpp::version::PlatformVersion; -use std::collections::BTreeSet; /// This will validate that all keys are valid against the state pub(super) fn validate_identity_public_key_ids_exist_in_state_v0( @@ -23,7 +23,7 @@ pub(super) fn validate_identity_public_key_ids_exist_in_state_v0( _execution_context: &mut StateTransitionExecutionContext, transaction: TransactionArg, platform_version: &PlatformVersion, -) -> Result { +) -> Result>, Error> { let limit = key_ids.len() as u16; let identity_key_request = IdentityKeysRequest { identity_id: identity_id.to_buffer(), @@ -31,20 +31,20 @@ pub(super) fn validate_identity_public_key_ids_exist_in_state_v0( limit: Some(limit), offset: None, }; - let keys = drive.fetch_identity_keys::( + let to_remove_keys = drive.fetch_identity_keys::( identity_key_request, transaction, platform_version, )?; - if keys.len() != key_ids.len() { - let to_remove = BTreeSet::from_iter(keys); + if to_remove_keys.len() != key_ids.len() { let mut missing_keys = key_ids.to_vec(); - missing_keys.retain(|found_key| !to_remove.contains(found_key)); + missing_keys.retain(|found_key| !to_remove_keys.contains_key(found_key)); // keys should all exist - Ok(SimpleConsensusValidationResult::new_with_error( + Ok(ConsensusValidationResult::new_with_error( MissingIdentityPublicKeyIdsError::new(missing_keys).into(), )) } else { - Ok(SimpleConsensusValidationResult::default()) + let values: Vec<_> = to_remove_keys.into_values().collect(); + Ok(ConsensusValidationResult::new_with_data(values)) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/mod.rs new file mode 100644 index 0000000000..a4d29d4b8b --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/mod.rs @@ -0,0 +1,30 @@ +use dpp::identity::IdentityPublicKey; +use dpp::state_transition::public_key_in_creation::IdentityPublicKeyInCreation; +use dpp::validation::SimpleConsensusValidationResult; +use dpp::version::PlatformVersion; +use crate::error::Error; +use crate::error::execution::ExecutionError; +use crate::execution::validation::state_transition::common::validate_not_disabling_last_master_key::v0::validate_master_key_uniqueness_v0; + +pub mod v0; + +pub(crate) fn validate_master_key_uniqueness( + public_keys_being_added: &[IdentityPublicKeyInCreation], + public_keys_to_disable: &[IdentityPublicKey], + platform_version: &PlatformVersion, +) -> Result { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .common_validation_methods + .validate_master_key_uniqueness + { + 0 => validate_master_key_uniqueness_v0(public_keys_being_added, public_keys_to_disable), + version => Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "validate_not_disabling_last_master_key".to_string(), + known_versions: vec![0], + received: version, + })), + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/v0/mod.rs new file mode 100644 index 0000000000..3abdc332e3 --- /dev/null +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_not_disabling_last_master_key/v0/mod.rs @@ -0,0 +1,42 @@ +use crate::error::Error; +use dpp::consensus::basic::BasicError; +use dpp::consensus::state::identity::master_public_key_update_error::MasterPublicKeyUpdateError; + +use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV0; +use dpp::identity::{IdentityPublicKey, SecurityLevel}; +use dpp::state_transition::public_key_in_creation::accessors::IdentityPublicKeyInCreationV0Getters; + +use dpp::state_transition::public_key_in_creation::IdentityPublicKeyInCreation; +use dpp::validation::SimpleConsensusValidationResult; + +/// This will validate that all keys are valid against the state +pub(super) fn validate_master_key_uniqueness_v0( + public_keys_being_added: &[IdentityPublicKeyInCreation], + public_keys_to_disable: &[IdentityPublicKey], +) -> Result { + let master_keys_to_disable_count = public_keys_to_disable + .iter() + .filter(|key| key.security_level() == SecurityLevel::MASTER) + .count(); + + let master_keys_being_added_count = public_keys_being_added + .iter() + .filter(|key| key.security_level() == SecurityLevel::MASTER) + .count(); + + // Check that at most one master key is being disabled and at most one is being added + if master_keys_to_disable_count > 1 + || master_keys_being_added_count > 1 + || ((master_keys_to_disable_count == 1) ^ (master_keys_being_added_count == 1)) + { + Ok(SimpleConsensusValidationResult::new_with_error( + BasicError::MasterPublicKeyUpdateError(MasterPublicKeyUpdateError::new( + master_keys_being_added_count, + master_keys_to_disable_count, + )) + .into(), + )) + } else { + Ok(SimpleConsensusValidationResult::default()) + } +} diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_state_transition_identity_signed/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_state_transition_identity_signed/v0/mod.rs index f7d929ab80..82afdd2418 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_state_transition_identity_signed/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/common/validate_state_transition_identity_signed/v0/mod.rs @@ -1,8 +1,9 @@ use crate::error::Error; use dpp::consensus::signature::{ - IdentityNotFoundError, InvalidSignaturePublicKeySecurityLevelError, - InvalidStateTransitionSignatureError, PublicKeySecurityLevelNotMetError, + IdentityNotFoundError, InvalidSignaturePublicKeyPurposeError, + InvalidSignaturePublicKeySecurityLevelError, InvalidStateTransitionSignatureError, + PublicKeySecurityLevelNotMetError, }; use dpp::identity::PartialIdentity; @@ -79,24 +80,39 @@ impl<'a> ValidateStateTransitionIdentitySignatureV0<'a> for StateTransition { let security_levels = match self { StateTransition::DocumentsBatch(_) => { - let action = action.ok_or(ProtocolError::CorruptedCodeExecution( - "we expect a state transition action when validating the signature of the documents batch transition".to_string(), - ))?; - let StateTransitionAction::DocumentsBatchAction(documents_batch_action) = action - else { - return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( - "we expect a documents batch state transition action when validating the signature of the documents batch transition", - ))); - }; - documents_batch_action.contract_based_security_level_requirement() + // We will have an action during consensus validation, but not on mempool check_tx + if let Some(action) = action { + let StateTransitionAction::DocumentsBatchAction(documents_batch_action) = + action + else { + return Err(Error::Execution(ExecutionError::CorruptedCodeExecution( + "we expect a documents batch state transition action when validating the signature of the documents batch transition", + ))); + }; + documents_batch_action.contract_based_security_level_requirement() + } else { + // In this case we just validate the transition + // If it is not valid during consensus validation because the key wasn't the + // right level then we will disable the key as it most likely is an attack + self.security_level_requirement() + .ok_or(ProtocolError::CorruptedCodeExecution( + "state_transition does not have security level".to_string(), + )) + } } _ => self .security_level_requirement() .ok_or(ProtocolError::CorruptedCodeExecution( - "state_transition does not have a owner Id to verify".to_string(), + "state_transition does not have security level".to_string(), )), }?; + let purpose = self + .purpose_requirement() + .ok_or(ProtocolError::CorruptedCodeExecution( + "state_transition does not have a key purpose requirement".to_string(), + ))?; + let key_request = IdentityKeysRequest::new_specific_key_query(owner_id.as_bytes(), key_id); let maybe_partial_identity = if request_identity_revision { @@ -141,6 +157,13 @@ impl<'a> ValidateStateTransitionIdentitySignatureV0<'a> for StateTransition { return Ok(validation_result); } + if purpose != public_key.purpose() { + validation_result.add_error(SignatureError::InvalidSignaturePublicKeyPurposeError( + InvalidSignaturePublicKeyPurposeError::new(public_key.purpose(), purpose), + )); + return Ok(validation_result); + } + if !security_levels.contains(&public_key.security_level()) { validation_result.add_error( SignatureError::InvalidSignaturePublicKeySecurityLevelError( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs index acff8bcfbd..d8b1eff9d8 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/processor/v0/mod.rs @@ -7,6 +7,7 @@ use crate::rpc::core::CoreRPCLike; use dpp::block::block_info::BlockInfo; use dpp::identity::PartialIdentity; use dpp::prelude::ConsensusValidationResult; +use dpp::ProtocolError; use crate::error::execution::ExecutionError; use dpp::serialization::Signable; @@ -19,7 +20,7 @@ use drive::state_transition_action::StateTransitionAction; use crate::execution::types::state_transition_execution_context::{StateTransitionExecutionContext}; use crate::execution::validation::state_transition::common::validate_state_transition_identity_signed::{ValidateStateTransitionIdentitySignature}; -use crate::execution::validation::state_transition::state_transitions::identity_update::identity_and_signatures::v0::IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0; +use crate::execution::validation::state_transition::state_transitions::identity_update::advanced_structure::v0::IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0; use crate::execution::validation::state_transition::state_transitions::identity_create::identity_and_signatures::v0::IdentityCreateStateTransitionIdentityAndSignaturesValidationV0; use crate::execution::validation::state_transition::state_transitions::identity_top_up::identity_retrieval::v0::IdentityTopUpStateTransitionIdentityRetrievalV0; use crate::execution::validation::state_transition::ValidationMode; @@ -114,7 +115,16 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( // Next we have advanced structure validation, this is structure validation that does not require // state but isn't checked on check_tx. If advanced structure fails identity nonces or identity // contract nonces will be bumped - let consensus_result = state_transition.validate_advanced_structure(platform_version)?; + let identity = maybe_identity + .as_ref() + .ok_or(ProtocolError::CorruptedCodeExecution( + "the identity should always be known on advanced structure validation".to_string(), + ))?; + let consensus_result = state_transition.validate_advanced_structure( + identity, + &mut state_transition_execution_context, + platform_version, + )?; if !consensus_result.is_valid() { return consensus_result.map_result(|action| { @@ -141,11 +151,15 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( transaction, )?; if !state_transition_action_result.is_valid_with_data() { - return Ok( - ConsensusValidationResult::::new_with_errors( - state_transition_action_result.errors, - ), - ); + return state_transition_action_result.map_result(|action| { + ExecutionEvent::create_from_state_transition_action( + action, + maybe_identity, + platform.state.last_committed_block_epoch_ref(), + state_transition_execution_context, + platform_version, + ) + }); } state_transition_action_result.into_data()? }; @@ -157,7 +171,15 @@ pub(in crate::execution) fn process_state_transition_v0<'a, C: CoreRPCLike>( platform_version, )?; if !result.is_valid() { - return Ok(ConsensusValidationResult::::new_with_errors(result.errors)); + return result.map_result(|action| { + ExecutionEvent::create_from_state_transition_action( + action, + maybe_identity, + platform.state.last_committed_block_epoch_ref(), + state_transition_execution_context, + platform_version, + ) + }); } Some(action) @@ -273,6 +295,8 @@ pub(crate) trait StateTransitionAdvancedStructureValidationV0 { /// * `Result` - A result with either a SimpleConsensusValidationResult or an Error. fn validate_advanced_structure( &self, + identity: &PartialIdentity, + execution_context: &mut StateTransitionExecutionContext, platform_version: &PlatformVersion, ) -> Result, Error>; @@ -325,7 +349,7 @@ pub(crate) trait StateTransitionStructureKnownInStateValidationV0 { platform: &PlatformStateRef, action: &StateTransitionAction, platform_version: &PlatformVersion, - ) -> Result; + ) -> Result, Error>; /// This means we should transform into the action before validation of the structure fn requires_advance_structure_validation_from_state(&self) -> bool { @@ -499,14 +523,49 @@ impl StateTransitionBalanceValidationV0 for StateTransition { impl StateTransitionAdvancedStructureValidationV0 for StateTransition { fn has_advanced_structure_validation(&self) -> bool { - false + matches!(self, StateTransition::IdentityUpdate(_)) } fn validate_advanced_structure( &self, - _platform_version: &PlatformVersion, + identity: &PartialIdentity, + execution_context: &mut StateTransitionExecutionContext, + platform_version: &PlatformVersion, ) -> Result, Error> { - Ok(ConsensusValidationResult::::new()) + match self { + StateTransition::IdentityUpdate(st) => { + match platform_version + .drive_abci + .validation_and_processing + .state_transitions + .identity_update_state_transition + .advanced_structure + { + Some(0) => { + let signable_bytes: Vec = self.signable_bytes()?; + st.validate_identity_update_state_transition_signatures_v0( + signable_bytes, + identity, + execution_context, + ) + } + Some(version) => { + Err(Error::Execution(ExecutionError::UnknownVersionMismatch { + method: "identity update transition: validate_advanced_structure" + .to_string(), + known_versions: vec![0], + received: version, + })) + } + None => Err(Error::Execution(ExecutionError::VersionNotActive { + method: "identity update transition: validate_advanced_structure" + .to_string(), + known_versions: vec![0], + })), + } + } + _ => Ok(ConsensusValidationResult::::new()), + } } } @@ -516,12 +575,12 @@ impl StateTransitionStructureKnownInStateValidationV0 for StateTransition { platform: &PlatformStateRef, action: &StateTransitionAction, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match self { StateTransition::DocumentsBatch(st) => { st.validate_advanced_structure_from_state(platform, action, platform_version) } - _ => Ok(SimpleConsensusValidationResult::new()), + _ => Ok(ConsensusValidationResult::new()), } } @@ -558,53 +617,18 @@ impl StateTransitionSignatureValidationV0 for StateTransition { )? .map(Some)) } - StateTransition::IdentityUpdate(st) => { - match platform_version - .drive_abci - .validation_and_processing - .state_transitions - .identity_update_state_transition - .identity_signatures - { - Some(0) => { - let signable_bytes: Vec = self.signable_bytes()?; - let mut validation_result = self - .validate_state_transition_identity_signed( - drive, - action, - true, - tx, - execution_context, - platform_version, - )?; - if !validation_result.is_valid() { - Ok(validation_result.map(Some)) - } else { - let partial_identity = validation_result.data_as_borrowed()?; - let result = st - .validate_identity_update_state_transition_signatures_v0( - signable_bytes, - partial_identity, - execution_context, - )?; - validation_result.merge(result); - Ok(validation_result.map(Some)) - } - } - None => Err(Error::Execution(ExecutionError::VersionNotActive { - method: "identity update transition: validate_identity_and_signatures" - .to_string(), - known_versions: vec![0], - })), - Some(version) => { - Err(Error::Execution(ExecutionError::UnknownVersionMismatch { - method: "identity update transition: validate_identity_and_signatures" - .to_string(), - known_versions: vec![0], - received: version, - })) - } - } + StateTransition::IdentityUpdate(_) => { + //Basic signature verification + Ok(self + .validate_state_transition_identity_signed( + drive, + action, + true, + tx, + execution_context, + platform_version, + )? + .map(Some)) } StateTransition::IdentityCreate(st) => { match platform_version @@ -623,7 +647,7 @@ impl StateTransitionSignatureValidationV0 for StateTransition { let result = st.validate_identity_create_state_transition_signatures_v0( signable_bytes, execution_context, - )?; + ); validation_result.merge(result); validation_result.set_data(None); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs index b938cf97f2..5f81fc02ad 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_create/state/v0/mod.rs @@ -80,7 +80,7 @@ impl DataContractCreateStateTransitionStateValidationV0 for DataContractCreateTr match result { Err(ProtocolError::ConsensusError(consensus_error)) => { let bump_action = StateTransitionAction::BumpIdentityNonceAction( - BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self)?, + BumpIdentityNonceAction::from_borrowed_data_contract_create_transition(self), ); Ok(ConsensusValidationResult::new_with_data_and_errors( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs index 093fed9188..0a818d94b1 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/data_contract_update/state/v0/mod.rs @@ -106,7 +106,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -132,7 +132,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -167,7 +167,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -195,9 +195,9 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr if !validate_update_result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( - self, - )?, + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( + self, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -222,7 +222,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -247,7 +247,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -273,9 +273,9 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr if let Some(old_defs) = old_data_contract.schema_defs() { let Some(new_defs) = self.data_contract().schema_defs() else { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( - self, - )?, + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( + self, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -304,7 +304,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); let data_contract_error: DataContractError = @@ -327,9 +327,9 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr get_operation_and_property_name_json(&diffs[0]); let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( - self, - )?, + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( + self, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -368,7 +368,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( self, - )?, + ), ); let data_contract_error: DataContractError = @@ -394,9 +394,9 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr get_operation_and_property_name_json(&diffs[0]); let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( - self, - )?, + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition( + self, + ), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -434,7 +434,7 @@ impl DataContractUpdateStateTransitionStateValidationV0 for DataContractUpdateTr match result { Err(ProtocolError::ConsensusError(consensus_error)) => { let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( - BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition(self)?, + BumpIdentityDataContractNonceAction::from_borrowed_data_contract_update_transition(self), ); Ok(ConsensusValidationResult::new_with_data_and_errors( diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs index 53ff2d122a..9bfc0321fe 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/advanced_structure/v0/mod.rs @@ -3,12 +3,14 @@ use dpp::consensus::basic::document::InvalidDocumentTransitionIdError; use dpp::document::Document; use dpp::state_transition::documents_batch_transition::accessors::DocumentsBatchTransitionAccessorsV0; use dpp::state_transition::documents_batch_transition::document_base_transition::v0::v0_methods::DocumentBaseTransitionV0Methods; -use dpp::state_transition::documents_batch_transition::document_transition::DocumentTransition; +use dpp::state_transition::documents_batch_transition::document_transition::{ + DocumentTransition, DocumentTransitionV0Methods, +}; use dpp::state_transition::documents_batch_transition::DocumentsBatchTransition; use dpp::state_transition::StateTransitionLike; -use dpp::validation::SimpleConsensusValidationResult; +use dpp::validation::ConsensusValidationResult; use dpp::version::PlatformVersion; @@ -18,6 +20,8 @@ use crate::execution::validation::state_transition::state_transitions::documents use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_delete_transition_action::DocumentDeleteTransitionActionValidation; use crate::execution::validation::state_transition::state_transitions::documents_batch::action_validation::document_create_transition_action::DocumentCreateTransitionActionValidation; use dpp::state_transition::documents_batch_transition::document_create_transition::v0::v0_methods::DocumentCreateTransitionV0Methods; +use drive::state_transition_action::StateTransitionAction; +use drive::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceAction; use crate::error::execution::ExecutionError; pub(in crate::execution::validation::state_transition::state_transitions::documents_batch) trait DocumentsBatchStateTransitionStructureValidationV0 @@ -26,7 +30,7 @@ pub(in crate::execution::validation::state_transition::state_transitions::docume &self, action: &DocumentsBatchTransitionAction, platform_version: &PlatformVersion, - ) -> Result; + ) -> Result, Error>; } impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransition { @@ -34,7 +38,7 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi &self, action: &DocumentsBatchTransitionAction, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { // We should validate that all newly created documents have valid ids for transition in self.transitions() { if let DocumentTransition::Create(create_transition) = transition { @@ -48,8 +52,19 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi let id = create_transition.base().id(); if generated_document_id != id { - return Ok(SimpleConsensusValidationResult::new_with_error( - InvalidDocumentTransitionIdError::new(generated_document_id, id).into(), + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition( + transition.base(), + self.owner_id(), + self.user_fee_increase(), + ), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![ + InvalidDocumentTransitionIdError::new(generated_document_id, id).into(), + ], )); } } @@ -61,19 +76,40 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi DocumentTransitionAction::CreateAction(create_action) => { let result = create_action.validate_structure(platform_version)?; if !result.is_valid() { - return Ok(result); + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); } } DocumentTransitionAction::ReplaceAction(replace_action) => { let result = replace_action.validate_structure(platform_version)?; if !result.is_valid() { - return Ok(result); + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); } } DocumentTransitionAction::DeleteAction(delete_action) => { let result = delete_action.validate_structure(platform_version)?; if !result.is_valid() { - return Ok(result); + let bump_action = StateTransitionAction::BumpIdentityDataContractNonceAction( + BumpIdentityDataContractNonceAction::from_borrowed_document_base_transition_action(transition.base().expect("there is always a base for the create action"), self.owner_id(), self.user_fee_increase()), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + result.errors, + )); } } DocumentTransitionAction::BumpIdentityDataContractNonce(_) => { @@ -83,6 +119,6 @@ impl DocumentsBatchStateTransitionStructureValidationV0 for DocumentsBatchTransi } } } - Ok(SimpleConsensusValidationResult::new()) + Ok(ConsensusValidationResult::new()) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs index ebcfdd56d6..20e1b22015 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/mod.rs @@ -131,7 +131,7 @@ impl StateTransitionStructureKnownInStateValidationV0 for DocumentsBatchTransiti _platform: &PlatformStateRef, action: &StateTransitionAction, platform_version: &PlatformVersion, - ) -> Result { + ) -> Result, Error> { match platform_version .drive_abci .validation_and_processing diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs index e3d1bbb2c3..91cc4c5b02 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/documents_batch/state/v0/mod.rs @@ -95,7 +95,7 @@ impl DocumentsBatchStateTransitionStateValidationV0 for DocumentsBatchTransition ))?, owner_id, state_transition_action.user_fee_increase(), - )?, + ), ), ); } else if platform.config.execution.use_document_triggers { @@ -136,7 +136,7 @@ impl DocumentsBatchStateTransitionStateValidationV0 for DocumentsBatchTransition ))?, owner_id, state_transition_action.user_fee_increase(), - )?, + ), )); } else { validated_transitions.push(transition); diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/identity_and_signatures/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/identity_and_signatures/v0/mod.rs index be5acc7827..6c76374166 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/identity_and_signatures/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/identity_and_signatures/v0/mod.rs @@ -1,4 +1,3 @@ -use crate::error::Error; use dpp::consensus::basic::identity::IdentityAssetLockTransactionOutputNotFoundError; use dpp::consensus::basic::invalid_identifier_error::InvalidIdentifierError; use dpp::consensus::basic::BasicError; @@ -22,7 +21,7 @@ pub(crate) trait IdentityCreateStateTransitionIdentityAndSignaturesValidationV0 &self, signable_bytes: Vec, execution_context: &mut StateTransitionExecutionContext, - ) -> Result; + ) -> SimpleConsensusValidationResult; } impl IdentityCreateStateTransitionIdentityAndSignaturesValidationV0 for IdentityCreateTransition { @@ -30,37 +29,30 @@ impl IdentityCreateStateTransitionIdentityAndSignaturesValidationV0 for Identity &self, signable_bytes: Vec, execution_context: &mut StateTransitionExecutionContext, - ) -> Result { - let mut validation_result = SimpleConsensusValidationResult::default(); + ) -> SimpleConsensusValidationResult { for key in self.public_keys().iter() { let result = signable_bytes.as_slice().verify_signature( key.key_type(), key.data().as_slice(), key.signature().as_slice(), - )?; + ); execution_context.add_operation(ValidationOperation::SignatureVerification( SignatureVerificationOperation::new(key.key_type()), )); if !result.is_valid() { - validation_result.add_errors(result.errors); + return result; } } - if !validation_result.is_valid() { - return Ok(validation_result); - } - // We should validate that the identity id is created from the asset lock proof let identifier_from_outpoint = match self.asset_lock_proof().create_identifier() { Ok(identifier) => identifier, Err(_) => { - return Ok(ConsensusValidationResult::new_with_error( - ConsensusError::BasicError( - BasicError::IdentityAssetLockTransactionOutputNotFoundError( - IdentityAssetLockTransactionOutputNotFoundError::new( - self.asset_lock_proof().output_index() as usize, - ), + return ConsensusValidationResult::new_with_error(ConsensusError::BasicError( + BasicError::IdentityAssetLockTransactionOutputNotFoundError( + IdentityAssetLockTransactionOutputNotFoundError::new( + self.asset_lock_proof().output_index() as usize, ), ), )) @@ -68,16 +60,14 @@ impl IdentityCreateStateTransitionIdentityAndSignaturesValidationV0 for Identity }; if identifier_from_outpoint != self.identity_id() { - return Ok(ConsensusValidationResult::new_with_error( - ConsensusError::BasicError(BasicError::InvalidIdentifierError( - InvalidIdentifierError::new( - "identity_id".to_string(), - "does not match created identifier from asset lock".to_string(), - ), + return ConsensusValidationResult::new_with_error(ConsensusError::BasicError( + BasicError::InvalidIdentifierError(InvalidIdentifierError::new( + "identity_id".to_string(), + "does not match created identifier from asset lock".to_string(), )), )); } - Ok(validation_result) + SimpleConsensusValidationResult::new() } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/structure/v0/mod.rs index 502f1c6d3a..43ede0b10e 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_create/structure/v0/mod.rs @@ -29,6 +29,7 @@ impl IdentityCreateStateTransitionStructureValidationV0 for IdentityCreateTransi IdentityPublicKeyInCreation::validate_identity_public_keys_structure( self.public_keys(), + true, platform_version, ) .map_err(Error::Protocol) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/identity_and_signatures/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/advanced_structure/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/identity_and_signatures/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/advanced_structure/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/identity_and_signatures/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/advanced_structure/v0/mod.rs similarity index 64% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/identity_and_signatures/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/advanced_structure/v0/mod.rs index f91ad92ab0..a5071a5d3a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/identity_and_signatures/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/advanced_structure/v0/mod.rs @@ -15,7 +15,9 @@ use dpp::serialization::PlatformMessageSignable; use dpp::state_transition::identity_update_transition::accessors::IdentityUpdateTransitionAccessorsV0; use dpp::state_transition::identity_update_transition::IdentityUpdateTransition; use dpp::state_transition::public_key_in_creation::accessors::IdentityPublicKeyInCreationV0Getters; -use dpp::validation::SimpleConsensusValidationResult; +use dpp::validation::ConsensusValidationResult; +use drive::state_transition_action::system::bump_identity_nonce_action::BumpIdentityNonceAction; +use drive::state_transition_action::StateTransitionAction; pub(in crate::execution::validation::state_transition) trait IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0 { @@ -24,7 +26,7 @@ pub(in crate::execution::validation::state_transition) trait IdentityUpdateState signable_bytes: Vec, partial_identity: &PartialIdentity, execution_context: &mut StateTransitionExecutionContext, - ) -> Result; + ) -> Result, Error>; } impl IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0 for IdentityUpdateTransition { @@ -33,37 +35,52 @@ impl IdentityUpdateStateTransitionIdentityAndSignaturesValidationV0 for Identity signable_bytes: Vec, partial_identity: &PartialIdentity, execution_context: &mut StateTransitionExecutionContext, - ) -> Result { - let mut result = SimpleConsensusValidationResult::default(); + ) -> Result, Error> { + let Some(revision) = partial_identity.revision else { + return Err(Error::Execution(CorruptedCodeExecution( + "revision should exist", + ))); + }; + + // Check revision + if revision + 1 != self.revision() { + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), + ); + + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + vec![ + StateError::InvalidIdentityRevisionError(InvalidIdentityRevisionError::new( + self.identity_id(), + revision, + )) + .into(), + ], + )); + } for key in self.public_keys_to_add().iter() { let validation_result = signable_bytes.as_slice().verify_signature( key.key_type(), key.data().as_slice(), key.signature().as_slice(), - )?; + ); execution_context.add_operation(ValidationOperation::SignatureVerification( SignatureVerificationOperation::new(key.key_type()), )); if !validation_result.is_valid() { - result.add_errors(validation_result.errors); - } - } + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), + ); - let Some(revision) = partial_identity.revision else { - return Err(Error::Execution(CorruptedCodeExecution( - "revision should exist", - ))); - }; - - // Check revision - if revision + 1 != self.revision() { - result.add_error(StateError::InvalidIdentityRevisionError( - InvalidIdentityRevisionError::new(self.identity_id(), revision), - )); - return Ok(result); + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + validation_result.errors, + )); + } } - Ok(result) + Ok(ConsensusValidationResult::new()) } } diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/structure/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/basic_structure/mod.rs similarity index 100% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/structure/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/basic_structure/mod.rs diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/structure/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/basic_structure/v0/mod.rs similarity index 99% rename from packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/structure/v0/mod.rs rename to packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/basic_structure/v0/mod.rs index b17952d8ff..b8f750804a 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/structure/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/basic_structure/v0/mod.rs @@ -81,6 +81,7 @@ impl IdentityUpdateStateTransitionStructureValidationV0 for IdentityUpdateTransi IdentityPublicKeyInCreation::validate_identity_public_keys_structure( self.public_keys_to_add(), + false, platform_version, ) .map_err(Error::Protocol) diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs index 571f999ea1..17729bb336 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/mod.rs @@ -1,7 +1,7 @@ -pub(crate) mod identity_and_signatures; +pub(crate) mod advanced_structure; +mod basic_structure; mod nonce; mod state; -mod structure; use dpp::block::block_info::BlockInfo; use dpp::state_transition::identity_update_transition::IdentityUpdateTransition; @@ -18,8 +18,8 @@ use crate::execution::types::state_transition_execution_context::StateTransition use crate::platform_types::platform::PlatformRef; use crate::rpc::core::CoreRPCLike; +use crate::execution::validation::state_transition::identity_update::basic_structure::v0::IdentityUpdateStateTransitionStructureValidationV0; use crate::execution::validation::state_transition::identity_update::state::v0::IdentityUpdateStateTransitionStateValidationV0; -use crate::execution::validation::state_transition::identity_update::structure::v0::IdentityUpdateStateTransitionStructureValidationV0; use crate::execution::validation::state_transition::processor::v0::{ StateTransitionBasicStructureValidationV0, StateTransitionStateValidationV0, }; diff --git a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs index dbfb3fdbb3..08997950bf 100644 --- a/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs +++ b/packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/identity_update/state/v0/mod.rs @@ -18,6 +18,7 @@ use crate::execution::types::state_transition_execution_context::StateTransition use crate::execution::validation::state_transition::common::validate_identity_public_key_contract_bounds::validate_identity_public_keys_contract_bounds; use crate::execution::validation::state_transition::common::validate_identity_public_key_ids_dont_exist_in_state::validate_identity_public_key_ids_dont_exist_in_state; use crate::execution::validation::state_transition::common::validate_identity_public_key_ids_exist_in_state::validate_identity_public_key_ids_exist_in_state; +use crate::execution::validation::state_transition::common::validate_not_disabling_last_master_key::validate_master_key_uniqueness; use crate::execution::validation::state_transition::common::validate_unique_identity_public_key_hashes_in_state::validate_unique_identity_public_key_hashes_not_in_state; pub(in crate::execution::validation::state_transition::state_transitions::identity_update) trait IdentityUpdateStateTransitionStateValidationV0 @@ -60,7 +61,7 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition if !validation_result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityNonceAction( - BumpIdentityNonceAction::from_borrowed_identity_update_transition(self)?, + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -83,7 +84,7 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition if !validation_result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityNonceAction( - BumpIdentityNonceAction::from_borrowed_identity_update_transition(self)?, + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -108,7 +109,7 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition if !validation_result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityNonceAction( - BumpIdentityNonceAction::from_borrowed_identity_update_transition(self)?, + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( @@ -118,8 +119,7 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition } if !self.public_key_ids_to_disable().is_empty() { - // We need to validate that all keys removed existed - validation_result.add_errors( + let validation_result_and_keys_to_disable = validate_identity_public_key_ids_exist_in_state( self.identity_id(), self.public_key_ids_to_disable(), @@ -127,13 +127,29 @@ impl IdentityUpdateStateTransitionStateValidationV0 for IdentityUpdateTransition &mut state_transition_execution_context, tx, platform_version, - )? - .errors, - ); + )?; + // We need to validate that all keys removed existed + if !validation_result_and_keys_to_disable.is_valid() { + let bump_action = StateTransitionAction::BumpIdentityNonceAction( + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), + ); + return Ok(ConsensusValidationResult::new_with_data_and_errors( + bump_action, + validation_result_and_keys_to_disable.errors, + )); + } + + let keys_to_disable = validation_result_and_keys_to_disable.into_data()?; + + let validation_result = validate_master_key_uniqueness( + self.public_keys_to_add(), + keys_to_disable.as_slice(), + platform_version, + )?; if !validation_result.is_valid() { let bump_action = StateTransitionAction::BumpIdentityNonceAction( - BumpIdentityNonceAction::from_borrowed_identity_update_transition(self)?, + BumpIdentityNonceAction::from_borrowed_identity_update_transition(self), ); return Ok(ConsensusValidationResult::new_with_data_and_errors( diff --git a/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs b/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs index c5fda75422..56c1c8df75 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/chain_lock_update.rs @@ -8,7 +8,7 @@ mod tests { use drive_abci::test::helpers::setup::TestPlatformBuilder; use strategy_tests::frequency::Frequency; - use strategy_tests::{StartIdentities, Strategy}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; #[test] fn run_chain_lock_update_quorums_not_changing() { @@ -19,10 +19,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, diff --git a/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs index de8eddbf67..88a439f29f 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/core_update_tests.rs @@ -9,7 +9,7 @@ mod tests { use drive_abci::platform_types::validator_set::v0::ValidatorSetV0Getters; use drive_abci::test::helpers::setup::TestPlatformBuilder; use strategy_tests::frequency::Frequency; - use strategy_tests::{StartIdentities, Strategy}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; #[test] fn run_chain_random_bans() { @@ -18,10 +18,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -118,10 +116,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -204,10 +200,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, diff --git a/packages/rs-drive-abci/tests/strategy_tests/execution.rs b/packages/rs-drive-abci/tests/strategy_tests/execution.rs index 9c628c1481..66ba2f947e 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/execution.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/execution.rs @@ -869,16 +869,15 @@ pub(crate) fn continue_chain_for_strategy( .validator_set .get(i as usize) .unwrap(); - let (state_transitions, finalize_block_operations) = strategy - .state_transitions_for_block( - platform, - &block_info, - &mut current_identities, - &mut current_identity_nonce_counter, - &mut current_identity_contract_nonce_counter, - &mut signer, - &mut rng, - ); + let (state_transitions, finalize_block_operations) = strategy.state_transitions_for_block( + platform, + &block_info, + &mut current_identities, + &mut current_identity_nonce_counter, + &mut current_identity_contract_nonce_counter, + &mut signer, + &mut rng, + ); state_transitions_per_block.insert(block_height, state_transitions.clone()); diff --git a/packages/rs-drive-abci/tests/strategy_tests/failures.rs b/packages/rs-drive-abci/tests/strategy_tests/failures.rs index ea50c4439c..d7d7eb9ccc 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/failures.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/failures.rs @@ -5,7 +5,7 @@ mod tests { use strategy_tests::frequency::Frequency; use crate::strategy::{FailureStrategy, NetworkStrategy}; - use strategy_tests::{StartIdentities, Strategy}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; use drive_abci::config::{ExecutionConfig, PlatformConfig, PlatformTestConfig}; @@ -47,10 +47,14 @@ mod tests { )], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -67,7 +71,7 @@ mod tests { dont_finalize_block: false, expect_every_block_errors_with_codes: vec![], rounds_before_successful_block: None, - expect_specific_block_errors_with_codes: HashMap::from([(3, vec![1067])]), //missing position (we skipped pos 6) + expect_specific_block_errors_with_codes: HashMap::from([(3, vec![10411])]), //missing position (we skipped pos 6) }), query_testing: None, verify_state_transition_results: true, @@ -124,10 +128,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, diff --git a/packages/rs-drive-abci/tests/strategy_tests/main.rs b/packages/rs-drive-abci/tests/strategy_tests/main.rs index 390e244f84..fb19363487 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/main.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/main.rs @@ -85,7 +85,7 @@ mod tests { use strategy_tests::operations::{ DocumentAction, DocumentOp, IdentityUpdateOp, Operation, OperationType, }; - use strategy_tests::StartIdentities; + use strategy_tests::{IdentityInsertInfo, StartIdentities}; use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; use dpp::dashcore::bls_sig_utils::BLSSignature; @@ -111,6 +111,7 @@ mod tests { use itertools::Itertools; use tenderdash_abci::proto::abci::{RequestInfo, ResponseInfo}; + use dpp::identity::{KeyType, Purpose, SecurityLevel}; use dpp::state_transition::StateTransition; use tenderdash_abci::Application; @@ -147,10 +148,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -193,10 +192,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -240,10 +237,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -368,10 +363,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -503,10 +496,14 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -554,7 +551,7 @@ mod tests { .expect("expected to fetch balances") .expect("expected to have an identity to get balance from"); - assert_eq!(balance, 99864802180) + assert_eq!(balance, 99864800180) } #[test] @@ -564,10 +561,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -614,10 +609,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -672,10 +665,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -735,10 +726,7 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), identity_contract_nonce_gaps: None, signer: None, }, @@ -811,10 +799,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -876,10 +862,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -944,10 +928,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -1039,10 +1021,14 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1093,10 +1079,14 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1151,7 +1141,7 @@ mod tests { .unwrap() .unwrap() ), - "6e2987b90789a80ebd2afbc7fc6f86925e504c5f06aad2fbe3982c12d8fbea8b".to_string() + "8e1e8d1ae51b3fc8a9e4acd0d312c9494943f2b7a5b957cc1379ab246ebd678d".to_string() ) } @@ -1171,10 +1161,14 @@ mod tests { contracts_with_updates: vec![(contract, None)], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1278,10 +1272,14 @@ mod tests { )], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1378,10 +1376,14 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1454,10 +1456,14 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1558,10 +1564,14 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1662,10 +1672,14 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -1722,7 +1736,7 @@ mod tests { .unwrap() .unwrap() ), - "8797928259c0545f1f12d945b56db05c9e3f9a9511be8e984ef6e505dad50135".to_string() + "665ec5018021b0a14a25b7ac6de780edc943a73adb3dc7e2eb623959a08056c3".to_string() ) } @@ -1781,10 +1795,14 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: Some(Frequency { times_per_block_range: 1..3, chance_per_block: Some(0.5), @@ -1843,7 +1861,7 @@ mod tests { .unwrap() .unwrap() ), - "e98075d5d775e0ae9eca7d4c062999076185ff7e71910a65fb0dc10d4bbffd7f".to_string() + "3f1cfdfd2e1019e941434cc841282fbc156ee19062569e393a51af621447c7a7".to_string() ) } @@ -1902,10 +1920,14 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: Some(Frequency { times_per_block_range: 24..25, chance_per_block: Some(1.0), @@ -2012,10 +2034,14 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: Some(Frequency { times_per_block_range: 25..26, chance_per_block: Some(1.0), @@ -2122,10 +2148,15 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..30, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..30, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -2165,7 +2196,7 @@ mod tests { .build_with_mock_rpc(); let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); - assert_eq!(outcome.identities.len() as u64, 421); + assert_eq!(outcome.identities.len() as u64, 470); assert_eq!(outcome.masternode_identity_balances.len(), 100); let balance_count = outcome .masternode_identity_balances @@ -2246,10 +2277,15 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..6, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..6, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -2289,7 +2325,7 @@ mod tests { .build_with_mock_rpc(); let outcome = run_chain_for_strategy(&mut platform, block_count, strategy, config, 15); - assert_eq!(outcome.identities.len() as u64, 86); + assert_eq!(outcome.identities.len() as u64, 90); assert_eq!(outcome.masternode_identity_balances.len(), 100); let balance_count = outcome .masternode_identity_balances @@ -2314,10 +2350,14 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -2388,10 +2428,14 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -2469,10 +2513,14 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + ..Default::default() }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -2558,9 +2606,17 @@ mod tests { }, ], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 1..2, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + start_keys: 3, + extra_keys: [( + Purpose::TRANSFER, + [(SecurityLevel::CRITICAL, vec![KeyType::ECDSA_SECP256K1])].into(), + )] + .into(), }, identity_contract_nonce_gaps: None, signer: None, @@ -2771,7 +2827,7 @@ mod tests { // Run block 4 // Should change pooled status to broadcasted - let last_block_broadcased_withdrawals_amount = last_block_withdrawals.len(); + let last_block_broadcasted_withdrawals_amount = last_block_withdrawals.len(); let ( ChainExecutionOutcome { abci_app, @@ -2836,7 +2892,7 @@ mod tests { // And extra withdrawals broadcasted let withdrawals_broadcasted_expected = - last_block_broadcased_withdrawals_amount + outcome.withdrawals.len(); + last_block_broadcasted_withdrawals_amount + outcome.withdrawals.len(); assert_eq!( withdrawal_documents_broadcasted.len(), withdrawals_broadcasted_expected @@ -2859,7 +2915,7 @@ mod tests { status_result.status = AssetUnlockStatus::Chainlocked; }); - // Then increase chainlocked height, so that withdrawals for chainlocked tranasctions + // Then increase chainlocked height, so that withdrawals for chainlocked transactions // could be completed in the next block // TODO: do we need this var? chain_locked_height += 1; @@ -3114,11 +3170,16 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { + identities_inserts: IdentityInsertInfo { //we do this to create some paying transactions - times_per_block_range: 1..2, - chance_per_block: None, + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -3274,11 +3335,16 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { + identities_inserts: IdentityInsertInfo { //we do this to create some paying transactions - times_per_block_range: 1..2, - chance_per_block: None, + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -3405,11 +3471,16 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { + identities_inserts: IdentityInsertInfo { //we do this to create some paying transactions - times_per_block_range: 1..2, - chance_per_block: None, + frequency: Frequency { + times_per_block_range: 1..2, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -3537,10 +3608,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -3670,10 +3739,20 @@ mod tests { }, }], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: 6..10, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + //we do this to create some paying transactions + frequency: Frequency { + times_per_block_range: 6..10, + chance_per_block: None, + }, + start_keys: 3, + extra_keys: [( + Purpose::TRANSFER, + [(SecurityLevel::CRITICAL, vec![KeyType::ECDSA_SECP256K1])].into(), + )] + .into(), }, + identity_contract_nonce_gaps: None, signer: None, }, @@ -3725,7 +3804,7 @@ mod tests { ) .expect("expected to fetch balances"); - assert_eq!(outcome.identities.len(), 110); + assert_eq!(outcome.identities.len(), 106); } // Test should filter out transactions exceeding max tx bytes per block @@ -3733,10 +3812,15 @@ mod tests { fn run_transactions_exceeding_max_block_size() { let strategy = NetworkStrategy { strategy: Strategy { - identities_inserts: Frequency { - times_per_block_range: 5..6, - chance_per_block: None, + identities_inserts: IdentityInsertInfo { + frequency: Frequency { + times_per_block_range: 5..6, + chance_per_block: None, + }, + start_keys: 5, + extra_keys: Default::default(), }, + ..Default::default() }, max_tx_bytes_per_block: 3500, diff --git a/packages/rs-drive-abci/tests/strategy_tests/query.rs b/packages/rs-drive-abci/tests/strategy_tests/query.rs index 1ace93ed31..bd68dfbbf2 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/query.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/query.rs @@ -337,7 +337,7 @@ mod tests { use drive_abci::test::helpers::setup::TestPlatformBuilder; - use strategy_tests::{StartIdentities, Strategy}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; use crate::strategy::CoreHeightIncrease::RandomCoreHeightIncrease; @@ -372,10 +372,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -472,10 +470,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -573,10 +569,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, diff --git a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs index e26d2317ec..1835c10fb2 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/strategy.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/strategy.rs @@ -19,7 +19,7 @@ use strategy_tests::operations::{ use dpp::document::DocumentV0Getters; use dpp::fee::Credits; -use dpp::identity::{Identity, KeyID, KeyType, Purpose, SecurityLevel}; +use dpp::identity::{Identity, IdentityPublicKey, KeyID, KeyType, Purpose, SecurityLevel}; use dpp::serialization::PlatformSerializableWithPlatformVersion; use dpp::state_transition::data_contract_create_transition::DataContractCreateTransition; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; @@ -39,7 +39,7 @@ use drive_abci::platform_types::platform::Platform; use drive_abci::rpc::core::MockCoreRPCLike; use rand::prelude::{IteratorRandom, SliceRandom, StdRng}; use rand::Rng; -use strategy_tests::Strategy; +use strategy_tests::{KeyMaps, Strategy}; use strategy_tests::transitions::{create_state_transitions_for_identities, instant_asset_lock_proof_fixture}; use std::borrow::Cow; use std::collections::{BTreeMap, HashMap, HashSet}; @@ -369,19 +369,21 @@ impl NetworkStrategy { if block_info.height == 1 && self.strategy.start_identities.number_of_identities > 0 { let mut new_transitions = NetworkStrategy::create_identities_state_transitions( self.strategy.start_identities.number_of_identities.into(), - 5, + self.strategy.identities_inserts.start_keys as KeyID, + &self.strategy.identities_inserts.extra_keys, signer, rng, platform_version, ); state_transitions.append(&mut new_transitions); } - let frequency = &self.strategy.identities_inserts; + let frequency = &self.strategy.identities_inserts.frequency; if frequency.check_hit(rng) { let count = frequency.events(rng); let mut new_transitions = NetworkStrategy::create_identities_state_transitions( count, - 5, + self.strategy.identities_inserts.start_keys as KeyID, + &self.strategy.identities_inserts.extra_keys, signer, rng, platform_version, @@ -1088,13 +1090,14 @@ impl NetworkStrategy { // There can also be contract updates - let mut contract_update_state_transitions = self.initial_contract_update_state_transitions( - current_identities, - block_info.height, - signer, - contract_nonce_counter, - platform_version, - ); + let mut contract_update_state_transitions = self + .initial_contract_update_state_transitions( + current_identities, + block_info.height, + signer, + contract_nonce_counter, + platform_version, + ); state_transitions.append(&mut contract_update_state_transitions); } @@ -1105,17 +1108,37 @@ impl NetworkStrategy { fn create_identities_state_transitions( count: u16, key_count: KeyID, + extra_keys: &KeyMaps, signer: &mut SimpleSigner, rng: &mut StdRng, platform_version: &PlatformVersion, ) -> Vec<(Identity, StateTransition)> { - let (identities, keys) = Identity::random_identities_with_private_keys_with_rng::>( - count, - key_count, - rng, - platform_version, - ) + let (mut identities, mut keys) = Identity::random_identities_with_private_keys_with_rng::< + Vec<_>, + >(count, key_count, rng, platform_version) .expect("expected to create identities"); + + for identity in identities.iter_mut() { + for (purpose, security_to_key_type_map) in extra_keys { + for (security_level, key_types) in security_to_key_type_map { + for key_type in key_types { + let (key, private_key) = + IdentityPublicKey::random_key_with_known_attributes( + (identity.public_keys().len() + 1) as KeyID, + rng, + *purpose, + *security_level, + *key_type, + platform_version, + ) + .expect("expected to create key"); + identity.add_public_key(key.clone()); + keys.push((key, private_key)); + } + } + } + } + signer.add_keys(keys); create_state_transitions_for_identities(identities, signer, rng, platform_version) } diff --git a/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs b/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs index a5070a898c..6a6598a7c6 100644 --- a/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs +++ b/packages/rs-drive-abci/tests/strategy_tests/upgrade_fork_tests.rs @@ -16,8 +16,7 @@ mod tests { use drive_abci::test::helpers::setup::TestPlatformBuilder; use platform_version::version::mocks::v2_test::TEST_PROTOCOL_VERSION_2; use platform_version::version::mocks::v3_test::TEST_PROTOCOL_VERSION_3; - use strategy_tests::frequency::Frequency; - use strategy_tests::{StartIdentities, Strategy}; + use strategy_tests::{IdentityInsertInfo, StartIdentities, Strategy}; #[test] fn run_chain_version_upgrade() { @@ -36,10 +35,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -279,10 +276,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -511,10 +506,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -740,10 +733,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -900,10 +891,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -1060,10 +1049,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, @@ -1162,10 +1149,8 @@ mod tests { contracts_with_updates: vec![], operations: vec![], start_identities: StartIdentities::default(), - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: IdentityInsertInfo::default(), + identity_contract_nonce_gaps: None, signer: None, }, diff --git a/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs b/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs index 149c4da3c2..f7a49a2bd7 100644 --- a/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/estimation_costs/for_purpose_in_key_reference_tree/v0/mod.rs @@ -37,12 +37,12 @@ impl Drive { let estimated_layer_count = match purpose { Purpose::AUTHENTICATION => ApproximateElements(4), Purpose::ENCRYPTION => { - unreachable!() + return; } Purpose::DECRYPTION => { - unreachable!() + return; } - Purpose::WITHDRAW => ApproximateElements(1), + Purpose::TRANSFER => ApproximateElements(1), Purpose::SYSTEM => ApproximateElements(1), Purpose::VOTING => ApproximateElements(1), }; @@ -50,12 +50,12 @@ impl Drive { let estimated_layer_sizes = match purpose { Purpose::AUTHENTICATION => AllSubtrees(1, NoSumTrees, None), Purpose::ENCRYPTION => { - unreachable!() + return; } Purpose::DECRYPTION => { - unreachable!() + return; } - Purpose::WITHDRAW => AllReference(1, KEY_REFERENCE_SIZE, None), + Purpose::TRANSFER => AllReference(1, KEY_REFERENCE_SIZE, None), Purpose::SYSTEM => AllReference(1, KEY_REFERENCE_SIZE, None), Purpose::VOTING => AllReference(1, KEY_REFERENCE_SIZE, None), }; diff --git a/packages/rs-drive/src/drive/identity/key/insert/create_new_identity_key_query_trees/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert/create_new_identity_key_query_trees/v0/mod.rs index e3f720f2e6..309c2957f8 100644 --- a/packages/rs-drive/src/drive/identity/key/insert/create_new_identity_key_query_trees/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert/create_new_identity_key_query_trees/v0/mod.rs @@ -33,8 +33,8 @@ impl Drive { )?; } - // There are 4 Purposes: Authentication, Encryption, Decryption, Withdrawal - for purpose in Purpose::authentication_withdraw() { + // There are 4 Purposes: Authentication, Encryption, Decryption, Transfer + for purpose in Purpose::authentication_and_transfer() { self.batch_insert_empty_tree( identity_query_key_tree, DriveKeyInfo::Key(vec![purpose as u8]), diff --git a/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs index 95c523c67c..588d686cbe 100644 --- a/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert/insert_key_searchable_references/v0/mod.rs @@ -1,8 +1,9 @@ use crate::drive::flags::SINGLE_EPOCH_FLAGS_SIZE; use crate::drive::grove_operations::BatchInsertTreeApplyType; use crate::drive::identity::{ - identity_key_location_within_identity_vec, identity_query_keys_full_tree_path, - identity_query_keys_purpose_tree_path, + identity_key_location_within_identity_vec, + identity_query_keys_for_authentication_full_tree_path, + identity_query_keys_for_transfer_full_tree_path, identity_query_keys_purpose_tree_path, }; use crate::drive::object_size_info::PathKeyElementInfo::PathFixedSizeKeyRefElement; use crate::drive::object_size_info::PathKeyInfo::PathFixedSizeKey; @@ -63,54 +64,76 @@ impl Drive { // Now lets add in references so we can query keys. // We assume the following, the identity already has a the basic Query Tree - if !(purpose == Purpose::AUTHENTICATION && security_level == SecurityLevel::MEDIUM) { - // Not Medium (Medium is already pre-inserted) + match purpose { + Purpose::AUTHENTICATION => { + if security_level != SecurityLevel::MEDIUM { + // Not Medium (Medium is already pre-inserted) - let purpose_path = identity_query_keys_purpose_tree_path( - identity_id.as_slice(), - purpose_vec.as_slice(), - ); + let purpose_path = identity_query_keys_purpose_tree_path( + identity_id.as_slice(), + purpose_vec.as_slice(), + ); - let apply_type = if estimated_costs_only_with_layer_info.is_none() { - BatchInsertTreeApplyType::StatefulBatchInsertTree - } else { - BatchInsertTreeApplyType::StatelessBatchInsertTree { - in_tree_using_sums: false, - is_sum_tree: false, - flags_len: SINGLE_EPOCH_FLAGS_SIZE, - } - }; + let apply_type = if estimated_costs_only_with_layer_info.is_none() { + BatchInsertTreeApplyType::StatefulBatchInsertTree + } else { + BatchInsertTreeApplyType::StatelessBatchInsertTree { + in_tree_using_sums: false, + is_sum_tree: false, + flags_len: SINGLE_EPOCH_FLAGS_SIZE, + } + }; - // We need to insert the security level if it doesn't yet exist - self.batch_insert_empty_tree_if_not_exists_check_existing_operations( - PathFixedSizeKey((purpose_path, vec![security_level as u8])), - None, - apply_type, - transaction, - drive_operations, - drive_version, - )?; - } + // We need to insert the security level if it doesn't yet exist + self.batch_insert_empty_tree_if_not_exists_check_existing_operations( + PathFixedSizeKey((purpose_path, vec![security_level as u8])), + None, + apply_type, + transaction, + drive_operations, + drive_version, + )?; + } - // Now let's set the reference - let reference_path = identity_query_keys_full_tree_path( - identity_id.as_slice(), - purpose_vec.as_slice(), - security_level_vec.as_slice(), - ); + // Now let's set the reference + let reference_path = identity_query_keys_for_authentication_full_tree_path( + identity_id.as_slice(), + security_level_vec.as_slice(), + ); - let key_reference = identity_key_location_within_identity_vec(key_id_bytes); - self.batch_insert( - PathFixedSizeKeyRefElement(( - reference_path, - key_id_bytes, - Element::new_reference_with_flags( - ReferencePathType::UpstreamRootHeightReference(2, key_reference), - None, - ), - )), - drive_operations, - drive_version, - ) + let key_reference = identity_key_location_within_identity_vec(key_id_bytes); + self.batch_insert( + PathFixedSizeKeyRefElement(( + reference_path, + key_id_bytes, + Element::new_reference_with_flags( + ReferencePathType::UpstreamRootHeightReference(2, key_reference), + None, + ), + )), + drive_operations, + drive_version, + ) + } + Purpose::TRANSFER => { + // Now let's set the reference + let reference_path = + identity_query_keys_for_transfer_full_tree_path(identity_id.as_slice()); + let key_reference = identity_key_location_within_identity_vec(key_id_bytes); + self.batch_insert( + PathFixedSizeKeyRefElement(( + reference_path, + key_id_bytes, + Element::new_reference_with_flags( + ReferencePathType::UpstreamRootHeightReference(2, key_reference), + None, + ), + )), + drive_operations, + drive_version, + ) + } + _ => Ok(()), + } } } diff --git a/packages/rs-drive/src/drive/identity/key/insert/insert_new_non_unique_key/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert/insert_new_non_unique_key/v0/mod.rs index aa90b52450..e634f4c924 100644 --- a/packages/rs-drive/src/drive/identity/key/insert/insert_new_non_unique_key/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert/insert_new_non_unique_key/v0/mod.rs @@ -63,7 +63,7 @@ impl Drive { if with_searchable_inner_references && matches!( identity_key.purpose(), - Purpose::AUTHENTICATION | Purpose::WITHDRAW + Purpose::AUTHENTICATION | Purpose::TRANSFER ) { self.insert_key_searchable_references_operations( diff --git a/packages/rs-drive/src/drive/identity/key/insert/insert_new_unique_key/v0/mod.rs b/packages/rs-drive/src/drive/identity/key/insert/insert_new_unique_key/v0/mod.rs index 0f2fd40041..d876d28b05 100644 --- a/packages/rs-drive/src/drive/identity/key/insert/insert_new_unique_key/v0/mod.rs +++ b/packages/rs-drive/src/drive/identity/key/insert/insert_new_unique_key/v0/mod.rs @@ -58,7 +58,7 @@ impl Drive { if with_searchable_inner_references && matches!( identity_key.purpose(), - Purpose::AUTHENTICATION | Purpose::WITHDRAW + Purpose::AUTHENTICATION | Purpose::TRANSFER ) { self.insert_key_searchable_references_operations( diff --git a/packages/rs-drive/src/drive/identity/mod.rs b/packages/rs-drive/src/drive/identity/mod.rs index 4266517050..d57226350f 100644 --- a/packages/rs-drive/src/drive/identity/mod.rs +++ b/packages/rs-drive/src/drive/identity/mod.rs @@ -38,7 +38,9 @@ use crate::drive::object_size_info::DriveKeyInfo; use crate::drive::RootTree; #[cfg(any(feature = "full", feature = "verify"))] -use dpp::identity::{KeyID, Purpose, SecurityLevel}; +use dpp::identity::Purpose; +#[cfg(feature = "full")] +use dpp::identity::{KeyID, SecurityLevel}; #[cfg(feature = "full")] /// Everything related to withdrawals @@ -303,16 +305,27 @@ pub(crate) fn identity_query_keys_security_level_tree_path_vec( /// identity query keys full tree path #[cfg(feature = "full")] /// Identity query keys full tree path -pub(crate) fn identity_query_keys_full_tree_path<'a>( +pub(crate) fn identity_query_keys_for_transfer_full_tree_path(identity_id: &[u8]) -> [&[u8]; 4] { + [ + Into::<&[u8; 1]>::into(RootTree::Identities), + identity_id, + Into::<&[u8; 1]>::into(IdentityRootStructure::IdentityTreeKeyReferences), + Into::<&[u8; 1]>::into(Purpose::TRANSFER), + ] +} + +/// identity query keys full tree path +#[cfg(feature = "full")] +/// Identity query keys full tree path +pub(crate) fn identity_query_keys_for_authentication_full_tree_path<'a>( identity_id: &'a [u8], - purpose: &'a [u8], security_level: &'a [u8], ) -> [&'a [u8]; 5] { [ Into::<&[u8; 1]>::into(RootTree::Identities), identity_id, Into::<&[u8; 1]>::into(IdentityRootStructure::IdentityTreeKeyReferences), - purpose, + Into::<&[u8; 1]>::into(Purpose::AUTHENTICATION), security_level, ] } diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs index ec98eb4d65..e5c8c19074 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/transformer.rs @@ -1,7 +1,6 @@ use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; -use dpp::ProtocolError; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransition; use dpp::state_transition::documents_batch_transition::document_base_transition::DocumentBaseTransition; use crate::state_transition_action::contract::data_contract_update::DataContractUpdateTransitionAction; @@ -14,16 +13,16 @@ impl BumpIdentityDataContractNonceAction { value: DocumentBaseTransition, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { match value { - DocumentBaseTransition::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_base_transition( + DocumentBaseTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_base_transition( v0, identity_id, user_fee_increase, - )? - .into(), - ), + ) + .into() + } } } @@ -32,16 +31,16 @@ impl BumpIdentityDataContractNonceAction { value: &DocumentBaseTransition, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { match value { - DocumentBaseTransition::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_borrowed_base_transition( + DocumentBaseTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_base_transition( v0, identity_id, user_fee_increase, - )? - .into(), - ), + ) + .into() + } } } @@ -50,83 +49,77 @@ impl BumpIdentityDataContractNonceAction { value: DocumentBaseTransitionAction, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { match value { - DocumentBaseTransitionAction::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_base_transition_action( + DocumentBaseTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_base_transition_action( v0, identity_id, user_fee_increase, - )? - .into(), - ), + ) + .into() + } } } /// from borrowed base transition - pub fn from_document_borrowed_base_transition_action( + pub fn from_borrowed_document_base_transition_action( value: &DocumentBaseTransitionAction, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { match value { - DocumentBaseTransitionAction::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_borrowed_base_transition_action( + DocumentBaseTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_base_transition_action( v0, identity_id, user_fee_increase, - )? - .into(), - ), + ) + .into() + } } } /// from data contract update - pub fn from_data_contract_update_transition( - value: DataContractUpdateTransition, - ) -> Result { + pub fn from_data_contract_update_transition(value: DataContractUpdateTransition) -> Self { match value { - DataContractUpdateTransition::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_data_contract_update(v0)?.into(), - ), + DataContractUpdateTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_data_contract_update(v0).into() + } } } /// from borrowed data contract update pub fn from_borrowed_data_contract_update_transition( value: &DataContractUpdateTransition, - ) -> Result { + ) -> Self { match value { - DataContractUpdateTransition::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_borrowed_data_contract_update(v0)? - .into(), - ), + DataContractUpdateTransition::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_data_contract_update(v0).into() + } } } /// from data contract update action pub fn from_data_contract_update_transition_action( value: DataContractUpdateTransitionAction, - ) -> Result { + ) -> Self { match value { - DataContractUpdateTransitionAction::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_data_contract_update_action(v0)? - .into(), - ), + DataContractUpdateTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_data_contract_update_action(v0).into() + } } } /// from borrowed data contract update action pub fn from_borrowed_data_contract_update_transition_action( value: &DataContractUpdateTransitionAction, - ) -> Result { + ) -> Self { match value { - DataContractUpdateTransitionAction::V0(v0) => Ok( - BumpIdentityDataContractNonceActionV0::try_from_borrowed_data_contract_update_action( - v0, - )? - .into(), - ), + DataContractUpdateTransitionAction::V0(v0) => { + BumpIdentityDataContractNonceActionV0::from_borrowed_data_contract_update_action(v0) + .into() + } } } } diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs index 6a338e35c4..42a9912790 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_data_contract_nonce_action/v0/transformer.rs @@ -2,7 +2,6 @@ use dpp::data_contract::accessors::v0::DataContractV0Getters; use dpp::platform_value::Identifier; use dpp::prelude::UserFeeIncrease; -use dpp::ProtocolError; use dpp::state_transition::data_contract_update_transition::DataContractUpdateTransitionV0; use dpp::state_transition::documents_batch_transition::document_base_transition::v0::DocumentBaseTransitionV0; use crate::state_transition_action::contract::data_contract_update::v0::DataContractUpdateTransitionActionV0; @@ -10,151 +9,145 @@ use crate::state_transition_action::document::documents_batch::document_transiti use crate::state_transition_action::system::bump_identity_data_contract_nonce_action::BumpIdentityDataContractNonceActionV0; impl BumpIdentityDataContractNonceActionV0 { - /// try from base transition - pub fn try_from_base_transition( + /// from base transition + pub fn from_base_transition( value: DocumentBaseTransitionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { let DocumentBaseTransitionV0 { data_contract_id, identity_contract_nonce, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id, data_contract_id, identity_contract_nonce, user_fee_increase, - }) + } } - /// try from borrowed base transition - pub fn try_from_borrowed_base_transition( + /// from borrowed base transition + pub fn from_borrowed_base_transition( value: &DocumentBaseTransitionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { let DocumentBaseTransitionV0 { data_contract_id, identity_contract_nonce, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id, data_contract_id: *data_contract_id, identity_contract_nonce: *identity_contract_nonce, user_fee_increase, - }) + } } - /// try from base transition - pub fn try_from_base_transition_action( + /// from base transition + pub fn from_base_transition_action( value: DocumentBaseTransitionActionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { let DocumentBaseTransitionActionV0 { data_contract, identity_contract_nonce, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id, data_contract_id: data_contract.contract.id(), identity_contract_nonce, user_fee_increase, - }) + } } - /// try from borrowed base transition - pub fn try_from_borrowed_base_transition_action( + /// from borrowed base transition + pub fn from_borrowed_base_transition_action( value: &DocumentBaseTransitionActionV0, identity_id: Identifier, user_fee_increase: UserFeeIncrease, - ) -> Result { + ) -> Self { let DocumentBaseTransitionActionV0 { data_contract, identity_contract_nonce, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id, data_contract_id: data_contract.contract.id(), identity_contract_nonce: *identity_contract_nonce, user_fee_increase, - }) + } } - /// try from data contract update - pub fn try_from_data_contract_update( - value: DataContractUpdateTransitionV0, - ) -> Result { + /// from data contract update + pub fn from_data_contract_update(value: DataContractUpdateTransitionV0) -> Self { let DataContractUpdateTransitionV0 { data_contract, identity_contract_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id: data_contract.owner_id(), data_contract_id: data_contract.id(), identity_contract_nonce, user_fee_increase, - }) + } } - /// try from borrowed data contract update - pub fn try_from_borrowed_data_contract_update( - value: &DataContractUpdateTransitionV0, - ) -> Result { + /// from borrowed data contract update + pub fn from_borrowed_data_contract_update(value: &DataContractUpdateTransitionV0) -> Self { let DataContractUpdateTransitionV0 { data_contract, identity_contract_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id: data_contract.owner_id(), data_contract_id: data_contract.id(), identity_contract_nonce: *identity_contract_nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from data contract update action - pub fn try_from_data_contract_update_action( - value: DataContractUpdateTransitionActionV0, - ) -> Result { + /// from data contract update action + pub fn from_data_contract_update_action(value: DataContractUpdateTransitionActionV0) -> Self { let DataContractUpdateTransitionActionV0 { data_contract, identity_contract_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id: data_contract.owner_id(), data_contract_id: data_contract.id(), identity_contract_nonce, user_fee_increase, - }) + } } - /// try from borrowed data contract update action - pub fn try_from_borrowed_data_contract_update_action( + /// from borrowed data contract update action + pub fn from_borrowed_data_contract_update_action( value: &DataContractUpdateTransitionActionV0, - ) -> Result { + ) -> Self { let DataContractUpdateTransitionActionV0 { data_contract, identity_contract_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityDataContractNonceActionV0 { + BumpIdentityDataContractNonceActionV0 { identity_id: data_contract.owner_id(), data_contract_id: data_contract.id(), identity_contract_nonce: *identity_contract_nonce, user_fee_increase: *user_fee_increase, - }) + } } } diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs index ec75a3ffed..674fb61d3b 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/transformer.rs @@ -9,38 +9,31 @@ use dpp::state_transition::data_contract_create_transition::DataContractCreateTr use dpp::state_transition::identity_credit_transfer_transition::IdentityCreditTransferTransition; use dpp::state_transition::identity_credit_withdrawal_transition::IdentityCreditWithdrawalTransition; use dpp::state_transition::identity_update_transition::IdentityUpdateTransition; -use dpp::ProtocolError; impl BumpIdentityNonceAction { /// from identity update - pub fn from_identity_update_transition( - value: IdentityUpdateTransition, - ) -> Result { + pub fn from_identity_update_transition(value: IdentityUpdateTransition) -> Self { match value { IdentityUpdateTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_identity_update(v0)?.into()) + BumpIdentityNonceActionV0::from_identity_update(v0).into() } } } /// from borrowed identity update - pub fn from_borrowed_identity_update_transition( - value: &IdentityUpdateTransition, - ) -> Result { + pub fn from_borrowed_identity_update_transition(value: &IdentityUpdateTransition) -> Self { match value { IdentityUpdateTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_borrowed_identity_update(v0)?.into()) + BumpIdentityNonceActionV0::from_borrowed_identity_update(v0).into() } } } /// from identity update action - pub fn from_identity_update_transition_action( - value: IdentityUpdateTransitionAction, - ) -> Result { + pub fn from_identity_update_transition_action(value: IdentityUpdateTransitionAction) -> Self { match value { IdentityUpdateTransitionAction::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_identity_update_action(v0)?.into()) + BumpIdentityNonceActionV0::from_identity_update_action(v0).into() } } } @@ -48,21 +41,19 @@ impl BumpIdentityNonceAction { /// from borrowed identity update action pub fn from_borrowed_identity_update_transition_action( value: &IdentityUpdateTransitionAction, - ) -> Result { + ) -> Self { match value { IdentityUpdateTransitionAction::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_borrowed_identity_update_action(v0)?.into()) + BumpIdentityNonceActionV0::from_borrowed_identity_update_action(v0).into() } } } /// from data contract create transition - pub fn from_data_contract_create_transition( - value: DataContractCreateTransition, - ) -> Result { + pub fn from_data_contract_create_transition(value: DataContractCreateTransition) -> Self { match value { DataContractCreateTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_contract_create(v0)?.into()) + BumpIdentityNonceActionV0::from_contract_create(v0).into() } } } @@ -70,21 +61,19 @@ impl BumpIdentityNonceAction { /// from borrowed data contract create transition pub fn from_borrowed_data_contract_create_transition( value: &DataContractCreateTransition, - ) -> Result { + ) -> Self { match value { DataContractCreateTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_borrowed_contract_create(v0)?.into()) + BumpIdentityNonceActionV0::from_borrowed_contract_create(v0).into() } } } /// from data contract create transition action - pub fn from_data_contract_create_action( - value: DataContractCreateTransitionAction, - ) -> Result { + pub fn from_data_contract_create_action(value: DataContractCreateTransitionAction) -> Self { match value { DataContractCreateTransitionAction::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_contract_create_action(v0)?.into()) + BumpIdentityNonceActionV0::from_contract_create_action(v0).into() } } } @@ -92,10 +81,10 @@ impl BumpIdentityNonceAction { /// from borrowed data contract create transition action pub fn from_borrowed_data_contract_create_action( value: &DataContractCreateTransitionAction, - ) -> Result { + ) -> Self { match value { DataContractCreateTransitionAction::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_borrowed_contract_create_action(v0)?.into()) + BumpIdentityNonceActionV0::from_borrowed_contract_create_action(v0).into() } } } @@ -103,10 +92,10 @@ impl BumpIdentityNonceAction { /// from identity transfer pub fn from_identity_credit_transfer_transition( value: IdentityCreditTransferTransition, - ) -> Result { + ) -> Self { match value { IdentityCreditTransferTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_identity_credit_transfer(v0)?.into()) + BumpIdentityNonceActionV0::from_identity_credit_transfer(v0).into() } } } @@ -114,21 +103,21 @@ impl BumpIdentityNonceAction { /// from borrowed identity transfer pub fn from_borrowed_identity_credit_transfer_transition( value: &IdentityCreditTransferTransition, - ) -> Result { + ) -> Self { match value { - IdentityCreditTransferTransition::V0(v0) => Ok( - BumpIdentityNonceActionV0::try_from_borrowed_identity_credit_transfer(v0)?.into(), - ), + IdentityCreditTransferTransition::V0(v0) => { + BumpIdentityNonceActionV0::from_borrowed_identity_credit_transfer(v0).into() + } } } /// from identity transfer action pub fn from_identity_credit_transfer_transition_action( value: IdentityCreditTransferTransitionAction, - ) -> Result { + ) -> Self { match value { IdentityCreditTransferTransitionAction::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_identity_credit_transfer_action(v0)?.into()) + BumpIdentityNonceActionV0::from_identity_credit_transfer_action(v0).into() } } } @@ -136,22 +125,21 @@ impl BumpIdentityNonceAction { /// from borrowed identity transfer action pub fn from_borrowed_identity_credit_transfer_transition_action( value: &IdentityCreditTransferTransitionAction, - ) -> Result { + ) -> Self { match value { - IdentityCreditTransferTransitionAction::V0(v0) => Ok( - BumpIdentityNonceActionV0::try_from_borrowed_identity_credit_transfer_action(v0)? - .into(), - ), + IdentityCreditTransferTransitionAction::V0(v0) => { + BumpIdentityNonceActionV0::from_borrowed_identity_credit_transfer_action(v0).into() + } } } /// from identity withdrawal pub fn from_identity_credit_withdrawal_transition( value: IdentityCreditWithdrawalTransition, - ) -> Result { + ) -> Self { match value { IdentityCreditWithdrawalTransition::V0(v0) => { - Ok(BumpIdentityNonceActionV0::try_from_identity_credit_withdrawal(v0)?.into()) + BumpIdentityNonceActionV0::from_identity_credit_withdrawal(v0).into() } } } @@ -159,34 +147,34 @@ impl BumpIdentityNonceAction { /// from borrowed identity withdrawal pub fn from_borrowed_identity_credit_withdrawal_transition( value: &IdentityCreditWithdrawalTransition, - ) -> Result { + ) -> Self { match value { - IdentityCreditWithdrawalTransition::V0(v0) => Ok( - BumpIdentityNonceActionV0::try_from_borrowed_identity_credit_withdrawal(v0)?.into(), - ), + IdentityCreditWithdrawalTransition::V0(v0) => { + BumpIdentityNonceActionV0::from_borrowed_identity_credit_withdrawal(v0).into() + } } } /// from identity withdrawal action pub fn from_identity_credit_withdrawal_transition_action( value: IdentityCreditWithdrawalTransitionAction, - ) -> Result { + ) -> Self { match value { - IdentityCreditWithdrawalTransitionAction::V0(v0) => Ok( - BumpIdentityNonceActionV0::try_from_identity_credit_withdrawal_action(v0)?.into(), - ), + IdentityCreditWithdrawalTransitionAction::V0(v0) => { + BumpIdentityNonceActionV0::from_identity_credit_withdrawal_action(v0).into() + } } } /// from borrowed identity withdrawal action pub fn from_borrowed_identity_credit_withdrawal_transition_action( value: &IdentityCreditWithdrawalTransitionAction, - ) -> Result { + ) -> Self { match value { - IdentityCreditWithdrawalTransitionAction::V0(v0) => Ok( - BumpIdentityNonceActionV0::try_from_borrowed_identity_credit_withdrawal_action(v0)? - .into(), - ), + IdentityCreditWithdrawalTransitionAction::V0(v0) => { + BumpIdentityNonceActionV0::from_borrowed_identity_credit_withdrawal_action(v0) + .into() + } } } } diff --git a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs index 5c626a336f..99cb834032 100644 --- a/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs +++ b/packages/rs-drive/src/state_transition_action/system/bump_identity_nonce_action/v0/transformer.rs @@ -8,278 +8,259 @@ use dpp::state_transition::data_contract_create_transition::DataContractCreateTr use dpp::state_transition::identity_credit_transfer_transition::v0::IdentityCreditTransferTransitionV0; use dpp::state_transition::identity_credit_withdrawal_transition::v0::IdentityCreditWithdrawalTransitionV0; use dpp::state_transition::identity_update_transition::v0::IdentityUpdateTransitionV0; -use dpp::ProtocolError; impl BumpIdentityNonceActionV0 { - /// try from identity update - pub fn try_from_identity_update( - value: IdentityUpdateTransitionV0, - ) -> Result { + /// from identity update + pub fn from_identity_update(value: IdentityUpdateTransitionV0) -> Self { let IdentityUpdateTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity update - pub fn try_from_borrowed_identity_update( - value: &IdentityUpdateTransitionV0, - ) -> Result { + /// from borrowed identity update + pub fn from_borrowed_identity_update(value: &IdentityUpdateTransitionV0) -> Self { let IdentityUpdateTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from identity update action - pub fn try_from_identity_update_action( - value: IdentityUpdateTransitionActionV0, - ) -> Result { + /// from identity update action + pub fn from_identity_update_action(value: IdentityUpdateTransitionActionV0) -> Self { let IdentityUpdateTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity update action - pub fn try_from_borrowed_identity_update_action( - value: &IdentityUpdateTransitionActionV0, - ) -> Result { + /// from borrowed identity update action + pub fn from_borrowed_identity_update_action(value: &IdentityUpdateTransitionActionV0) -> Self { let IdentityUpdateTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from contract create - pub fn try_from_contract_create( - value: DataContractCreateTransitionV0, - ) -> Result { + /// from contract create + pub fn from_contract_create(value: DataContractCreateTransitionV0) -> Self { let DataContractCreateTransitionV0 { data_contract, identity_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: data_contract.owner_id(), identity_nonce, user_fee_increase, - }) + } } - /// try from contract create - pub fn try_from_borrowed_contract_create( - value: &DataContractCreateTransitionV0, - ) -> Result { + /// from borrowed contract create + pub fn from_borrowed_contract_create(value: &DataContractCreateTransitionV0) -> Self { let DataContractCreateTransitionV0 { data_contract, identity_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: data_contract.owner_id(), identity_nonce: *identity_nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from contract create action - pub fn try_from_contract_create_action( - value: DataContractCreateTransitionActionV0, - ) -> Result { + /// from contract create action + pub fn from_contract_create_action(value: DataContractCreateTransitionActionV0) -> Self { let DataContractCreateTransitionActionV0 { data_contract, identity_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: data_contract.owner_id(), identity_nonce, user_fee_increase, - }) + } } - /// try from contract create - pub fn try_from_borrowed_contract_create_action( + /// from contract create action + pub fn from_borrowed_contract_create_action( value: &DataContractCreateTransitionActionV0, - ) -> Result { + ) -> Self { let DataContractCreateTransitionActionV0 { data_contract, identity_nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: data_contract.owner_id(), identity_nonce: *identity_nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from identity credit transfer - pub fn try_from_identity_credit_transfer( - value: IdentityCreditTransferTransitionV0, - ) -> Result { + /// from identity credit transfer + pub fn from_identity_credit_transfer(value: IdentityCreditTransferTransitionV0) -> Self { let IdentityCreditTransferTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity credit transfer - pub fn try_from_borrowed_identity_credit_transfer( + /// from borrowed identity credit transfer + pub fn from_borrowed_identity_credit_transfer( value: &IdentityCreditTransferTransitionV0, - ) -> Result { + ) -> Self { let IdentityCreditTransferTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from identity credit transfer action - pub fn try_from_identity_credit_transfer_action( + /// from identity credit transfer action + pub fn from_identity_credit_transfer_action( value: IdentityCreditTransferTransitionActionV0, - ) -> Result { + ) -> Self { let IdentityCreditTransferTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity credit transfer action - pub fn try_from_borrowed_identity_credit_transfer_action( + /// from borrowed identity credit transfer action + pub fn from_borrowed_identity_credit_transfer_action( value: &IdentityCreditTransferTransitionActionV0, - ) -> Result { + ) -> Self { let IdentityCreditTransferTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from identity credit withdrawal - pub fn try_from_identity_credit_withdrawal( - value: IdentityCreditWithdrawalTransitionV0, - ) -> Result { + /// from identity credit withdrawal + pub fn from_identity_credit_withdrawal(value: IdentityCreditWithdrawalTransitionV0) -> Self { let IdentityCreditWithdrawalTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity credit withdrawal - pub fn try_from_borrowed_identity_credit_withdrawal( + /// from borrowed identity credit withdrawal + pub fn from_borrowed_identity_credit_withdrawal( value: &IdentityCreditWithdrawalTransitionV0, - ) -> Result { + ) -> Self { let IdentityCreditWithdrawalTransitionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } - /// try from identity credit withdrawal action - pub fn try_from_identity_credit_withdrawal_action( + /// from identity credit withdrawal action + pub fn from_identity_credit_withdrawal_action( value: IdentityCreditWithdrawalTransitionActionV0, - ) -> Result { + ) -> Self { let IdentityCreditWithdrawalTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id, identity_nonce: nonce, user_fee_increase, - }) + } } - /// try from borrowed identity credit withdrawal action - pub fn try_from_borrowed_identity_credit_withdrawal_action( + /// from borrowed identity credit withdrawal action + pub fn from_borrowed_identity_credit_withdrawal_action( value: &IdentityCreditWithdrawalTransitionActionV0, - ) -> Result { + ) -> Self { let IdentityCreditWithdrawalTransitionActionV0 { identity_id, nonce, user_fee_increase, .. } = value; - Ok(BumpIdentityNonceActionV0 { + BumpIdentityNonceActionV0 { identity_id: *identity_id, identity_nonce: *nonce, user_fee_increase: *user_fee_increase, - }) + } } } diff --git a/packages/rs-platform-value/src/converter/ciborium.rs b/packages/rs-platform-value/src/converter/ciborium.rs index 8703fed88b..d6f0b8247b 100644 --- a/packages/rs-platform-value/src/converter/ciborium.rs +++ b/packages/rs-platform-value/src/converter/ciborium.rs @@ -129,8 +129,16 @@ impl TryInto for Value { ) } Value::Identifier(bytes) => CborValue::Bytes(bytes.to_vec()), - Value::EnumU8(_) => todo!(), - Value::EnumString(_) => todo!(), + Value::EnumU8(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumU8 to JSONValue".to_string(), + )) + } + Value::EnumString(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumString to JSONValue".to_string(), + )) + } }) } } diff --git a/packages/rs-platform-value/src/converter/serde_json.rs b/packages/rs-platform-value/src/converter/serde_json.rs index 6cddde462c..f4be4635ab 100644 --- a/packages/rs-platform-value/src/converter/serde_json.rs +++ b/packages/rs-platform-value/src/converter/serde_json.rs @@ -90,8 +90,16 @@ impl Value { .map(|byte| JsonValue::Number(byte.into())) .collect(), ), - Value::EnumU8(_) => todo!(), - Value::EnumString(_) => todo!(), + Value::EnumU8(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumU8 to JSONValue".to_string(), + )) + } + Value::EnumString(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumString to JSONValue".to_string(), + )) + } }) } @@ -178,8 +186,16 @@ impl Value { .map(|byte| JsonValue::Number((*byte).into())) .collect(), ), - Value::EnumU8(_) => todo!(), - Value::EnumString(_) => todo!(), + Value::EnumU8(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumU8 to JSONValue".to_string(), + )) + } + Value::EnumString(_) => { + return Err(Error::Unsupported( + "No support for conversion of EnumString to JSONValue".to_string(), + )) + } }) } } diff --git a/packages/rs-platform-value/src/display.rs b/packages/rs-platform-value/src/display.rs index 273029f7fc..973fcf0a4c 100644 --- a/packages/rs-platform-value/src/display.rs +++ b/packages/rs-platform-value/src/display.rs @@ -52,8 +52,8 @@ impl Value { "identifier {}", bs58::encode(identifier.as_slice()).into_string() ), - Value::EnumU8(_) => todo!(), - Value::EnumString(_) => todo!(), + Value::EnumU8(_) => "enum u8".to_string(), + Value::EnumString(_) => "enum string".to_string(), } } @@ -109,8 +109,8 @@ impl Value { "identifier {}", bs58::encode(identifier.as_slice()).into_string() ), - Value::EnumU8(_) => todo!(), - Value::EnumString(_) => todo!(), + Value::EnumU8(_) => "enum u8".to_string(), + Value::EnumString(_) => "enum string".to_string(), } } } diff --git a/packages/rs-platform-version/src/version/drive_abci_versions.rs b/packages/rs-platform-version/src/version/drive_abci_versions.rs index 902094ddec..0ab6c90c52 100644 --- a/packages/rs-platform-version/src/version/drive_abci_versions.rs +++ b/packages/rs-platform-version/src/version/drive_abci_versions.rs @@ -151,6 +151,7 @@ pub struct DriveAbciStateTransitionCommonValidationVersions { pub validate_identity_public_key_ids_exist_in_state: FeatureVersion, pub validate_state_transition_identity_signed: FeatureVersion, pub validate_unique_identity_public_key_hashes_in_state: FeatureVersion, + pub validate_master_key_uniqueness: FeatureVersion, } #[derive(Clone, Copy, Debug, Default)] diff --git a/packages/rs-platform-version/src/version/mocks/v2_test.rs b/packages/rs-platform-version/src/version/mocks/v2_test.rs index bb37dfb50b..165d6c4977 100644 --- a/packages/rs-platform-version/src/version/mocks/v2_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v2_test.rs @@ -594,6 +594,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { validate_identity_public_key_ids_exist_in_state: 0, validate_state_transition_identity_signed: 0, validate_unique_identity_public_key_hashes_in_state: 0, + validate_master_key_uniqueness: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), @@ -606,7 +607,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), - advanced_structure: None, + advanced_structure: Some(0), identity_signatures: Some(0), balance: None, nonce: Some(0), @@ -644,7 +645,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, contract_create_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), - advanced_structure: Some(0), + advanced_structure: None, identity_signatures: None, balance: None, nonce: Some(0), @@ -653,7 +654,7 @@ pub(crate) const TEST_PLATFORM_V2: PlatformVersion = PlatformVersion { }, contract_update_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: None, - advanced_structure: Some(0), + advanced_structure: None, identity_signatures: None, balance: None, nonce: Some(0), diff --git a/packages/rs-platform-version/src/version/mocks/v3_test.rs b/packages/rs-platform-version/src/version/mocks/v3_test.rs index 9974e6b528..c2804c84eb 100644 --- a/packages/rs-platform-version/src/version/mocks/v3_test.rs +++ b/packages/rs-platform-version/src/version/mocks/v3_test.rs @@ -594,6 +594,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { validate_identity_public_key_ids_exist_in_state: 0, validate_state_transition_identity_signed: 0, validate_unique_identity_public_key_hashes_in_state: 0, + validate_master_key_uniqueness: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), @@ -606,7 +607,7 @@ pub(crate) const TEST_PLATFORM_V3: PlatformVersion = PlatformVersion { }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), - advanced_structure: None, + advanced_structure: Some(0), identity_signatures: Some(0), balance: None, nonce: Some(0), diff --git a/packages/rs-platform-version/src/version/v1.rs b/packages/rs-platform-version/src/version/v1.rs index c4d6d59a0c..07a10eb62b 100644 --- a/packages/rs-platform-version/src/version/v1.rs +++ b/packages/rs-platform-version/src/version/v1.rs @@ -591,6 +591,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { validate_identity_public_key_ids_exist_in_state: 0, validate_state_transition_identity_signed: 0, validate_unique_identity_public_key_hashes_in_state: 0, + validate_master_key_uniqueness: 0, }, identity_create_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), @@ -603,7 +604,7 @@ pub(super) const PLATFORM_V1: PlatformVersion = PlatformVersion { }, identity_update_state_transition: DriveAbciStateTransitionValidationVersion { basic_structure: Some(0), - advanced_structure: None, + advanced_structure: Some(0), identity_signatures: Some(0), balance: None, nonce: Some(0), diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.629451923Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.629451923Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..3d60f5d361 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.629451923Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630123500Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630123500Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json new file mode 100644 index 0000000000..9b8dfdcc0b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630123500Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630642159Z_GetDataContractRequest_1d1e53ab5e04d9ec5dce4ff9ac048c03122daf7ab2e77108f4bf44af1ad15eae.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630642159Z_GetDataContractRequest_1d1e53ab5e04d9ec5dce4ff9ac048c03122daf7ab2e77108f4bf44af1ad15eae.json new file mode 100644 index 0000000000..e322097514 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630642159Z_GetDataContractRequest_1d1e53ab5e04d9ec5dce4ff9ac048c03122daf7ab2e77108f4bf44af1ad15eae.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630652428Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630652428Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json new file mode 100644 index 0000000000..9b8dfdcc0b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.630652428Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632256765Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632256765Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json new file mode 100644 index 0000000000..9b8dfdcc0b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632256765Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632500304Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632500304Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..3d60f5d361 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.632500304Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.633007782Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.633007782Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json new file mode 100644 index 0000000000..9b8dfdcc0b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.633007782Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.634383016Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.634383016Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json new file mode 100644 index 0000000000..9b8dfdcc0b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.634383016Z_GetDataContractRequest_e87a2e6acef76975c30eb7272da71733fb6ad13495beb7ca1b6a6c4ceb30e0f7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905030Z_GetDataContractRequest_e4cf74168e03a40bd159451456b501c1ba166a2dd8f6efb31b0289dc011da983.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905030Z_GetDataContractRequest_e4cf74168e03a40bd159451456b501c1ba166a2dd8f6efb31b0289dc011da983.json new file mode 100644 index 0000000000..571cb9f663 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905030Z_GetDataContractRequest_e4cf74168e03a40bd159451456b501c1ba166a2dd8f6efb31b0289dc011da983.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905411Z_GetDataContractsRequest_93bdf343bce1bafb96fd873236cabbc4ac6ad7e80f0e55fe98bbcfbebf6c0878.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905411Z_GetDataContractsRequest_93bdf343bce1bafb96fd873236cabbc4ac6ad7e80f0e55fe98bbcfbebf6c0878.json new file mode 100644 index 0000000000..c55d94b259 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.637905411Z_GetDataContractsRequest_93bdf343bce1bafb96fd873236cabbc4ac6ad7e80f0e55fe98bbcfbebf6c0878.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.639022859Z_GetDataContractsRequest_f229a0e58a5c4fb050f57c087bf067bd9ccc29eca3092a5664a5a9ba3bb7e967.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.639022859Z_GetDataContractsRequest_f229a0e58a5c4fb050f57c087bf067bd9ccc29eca3092a5664a5a9ba3bb7e967.json new file mode 100644 index 0000000000..f75ea287ad Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.639022859Z_GetDataContractsRequest_f229a0e58a5c4fb050f57c087bf067bd9ccc29eca3092a5664a5a9ba3bb7e967.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.642649491Z_GetEpochsInfoRequest_1b87e649557ccb609adb9e2904c67089535588985622579e77969e0ffd68afc7.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.642649491Z_GetEpochsInfoRequest_1b87e649557ccb609adb9e2904c67089535588985622579e77969e0ffd68afc7.json new file mode 100644 index 0000000000..d590a2f596 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.642649491Z_GetEpochsInfoRequest_1b87e649557ccb609adb9e2904c67089535588985622579e77969e0ffd68afc7.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.719566753Z_GetEpochsInfoRequest_b2b426ac4a52cb4cb08904c63386caf3663c40a12d3b03827006d66058e439ac.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.719566753Z_GetEpochsInfoRequest_b2b426ac4a52cb4cb08904c63386caf3663c40a12d3b03827006d66058e439ac.json new file mode 100644 index 0000000000..9115772729 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.719566753Z_GetEpochsInfoRequest_b2b426ac4a52cb4cb08904c63386caf3663c40a12d3b03827006d66058e439ac.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.787102609Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.787102609Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json new file mode 100644 index 0000000000..20ab77901c Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.787102609Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.791025249Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.791025249Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..1ab8cc1908 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.791025249Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.813846802Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.813846802Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..1ab8cc1908 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.813846802Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815461989Z_DocumentQuery_c104c67292061fe0b8e2f959cd2625892e0011f1264c65e1474532f59456ff51.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815461989Z_DocumentQuery_c104c67292061fe0b8e2f959cd2625892e0011f1264c65e1474532f59456ff51.json new file mode 100644 index 0000000000..9ccba2df2b Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815461989Z_DocumentQuery_c104c67292061fe0b8e2f959cd2625892e0011f1264c65e1474532f59456ff51.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815625277Z_DocumentQuery_90af5a08200f1b0e42dbd3ad7a6af38ff6415d9cabab87315b9d9d736194597f.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815625277Z_DocumentQuery_90af5a08200f1b0e42dbd3ad7a6af38ff6415d9cabab87315b9d9d736194597f.json new file mode 100644 index 0000000000..ad4ad78c55 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815625277Z_DocumentQuery_90af5a08200f1b0e42dbd3ad7a6af38ff6415d9cabab87315b9d9d736194597f.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815887401Z_GetIdentityBalanceRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815887401Z_GetIdentityBalanceRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..d66fbb0245 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.815887401Z_GetIdentityBalanceRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818184304Z_DocumentQuery_fb3b25c8fa37750a6c1b18d9085fcf0df7bf150009b1ced887a6f051ab86085b.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818184304Z_DocumentQuery_fb3b25c8fa37750a6c1b18d9085fcf0df7bf150009b1ced887a6f051ab86085b.json new file mode 100644 index 0000000000..761ee46c82 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818184304Z_DocumentQuery_fb3b25c8fa37750a6c1b18d9085fcf0df7bf150009b1ced887a6f051ab86085b.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818401023Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818401023Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..1ab8cc1908 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.818401023Z_GetIdentityRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.819407923Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.819407923Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json new file mode 100644 index 0000000000..20ab77901c Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.819407923Z_DocumentQuery_4dd78cc4a7f90bcf8393c36115a093d92d2c84b425f8393ffa9599b06a3a77be.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.823315675Z_GetIdentityBalanceAndRevisionRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.823315675Z_GetIdentityBalanceAndRevisionRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json new file mode 100644 index 0000000000..e07910549f Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.823315675Z_GetIdentityBalanceAndRevisionRequest_e4060c14ceaca6844d682c7393d7776113debe4287515ae60d0645da450a80a1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.824051072Z_GetIdentityKeysRequest_b4ecff7acf52818aef9ed37a98d4a459dc7a67570ea6df3f8858d3fae7820ffe.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.824051072Z_GetIdentityKeysRequest_b4ecff7acf52818aef9ed37a98d4a459dc7a67570ea6df3f8858d3fae7820ffe.json new file mode 100644 index 0000000000..2b6f6eecbe Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.824051072Z_GetIdentityKeysRequest_b4ecff7acf52818aef9ed37a98d4a459dc7a67570ea6df3f8858d3fae7820ffe.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.837728485Z_GetIdentityContractNonceRequest_b7c02dae0c3c762ece1f70a36f88fa69b4749b19cc1f5ef0abf37fa0c04ab2ef.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.837728485Z_GetIdentityContractNonceRequest_b7c02dae0c3c762ece1f70a36f88fa69b4749b19cc1f5ef0abf37fa0c04ab2ef.json new file mode 100644 index 0000000000..c37c61754c Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.837728485Z_GetIdentityContractNonceRequest_b7c02dae0c3c762ece1f70a36f88fa69b4749b19cc1f5ef0abf37fa0c04ab2ef.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.838169256Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.838169256Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json new file mode 100644 index 0000000000..d8710cd500 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.838169256Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.841927325Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.841927325Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json new file mode 100644 index 0000000000..d8710cd500 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.841927325Z_IdentityRequest_5789e2afa300c2ac039646d8b81c53464633a072722c5a04b15ee01f3a45de99.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866849731Z_GetProtocolVersionUpgradeStateRequest_bb149e1933b9dc561bbfacfb6d09550f0ea4a6af6f68037e7d50ff4e4de74509.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866849731Z_GetProtocolVersionUpgradeStateRequest_bb149e1933b9dc561bbfacfb6d09550f0ea4a6af6f68037e7d50ff4e4de74509.json new file mode 100644 index 0000000000..061732f09f Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866849731Z_GetProtocolVersionUpgradeStateRequest_bb149e1933b9dc561bbfacfb6d09550f0ea4a6af6f68037e7d50ff4e4de74509.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866866313Z_GetProtocolVersionUpgradeVoteStatusRequest_ec9dca65a964669b3bc8195d5ff106e5eda740be44679cc960ea35f2134af628.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866866313Z_GetProtocolVersionUpgradeVoteStatusRequest_ec9dca65a964669b3bc8195d5ff106e5eda740be44679cc960ea35f2134af628.json new file mode 100644 index 0000000000..09304945dc Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.866866313Z_GetProtocolVersionUpgradeVoteStatusRequest_ec9dca65a964669b3bc8195d5ff106e5eda740be44679cc960ea35f2134af628.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.873512881Z_GetProtocolVersionUpgradeVoteStatusRequest_983670ac95678b1166deab32209bf1acc3394d29ac72f662d38e81344496631e.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.873512881Z_GetProtocolVersionUpgradeVoteStatusRequest_983670ac95678b1166deab32209bf1acc3394d29ac72f662d38e81344496631e.json new file mode 100644 index 0000000000..87cd079c64 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.873512881Z_GetProtocolVersionUpgradeVoteStatusRequest_983670ac95678b1166deab32209bf1acc3394d29ac72f662d38e81344496631e.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.895002050Z_GetProtocolVersionUpgradeVoteStatusRequest_8534be7e0b4dd648520dc3a67209b1a05862cb8d40c088b193b59ca3564210bc.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.895002050Z_GetProtocolVersionUpgradeVoteStatusRequest_8534be7e0b4dd648520dc3a67209b1a05862cb8d40c088b193b59ca3564210bc.json new file mode 100644 index 0000000000..ed765df053 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.895002050Z_GetProtocolVersionUpgradeVoteStatusRequest_8534be7e0b4dd648520dc3a67209b1a05862cb8d40c088b193b59ca3564210bc.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.896617067Z_GetProtocolVersionUpgradeVoteStatusRequest_92a45a0fe4f69d355022d2f2f7622dfc69cc7b123be24b7ad993281979b2a3a2.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.896617067Z_GetProtocolVersionUpgradeVoteStatusRequest_92a45a0fe4f69d355022d2f2f7622dfc69cc7b123be24b7ad993281979b2a3a2.json new file mode 100644 index 0000000000..9d66399434 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.896617067Z_GetProtocolVersionUpgradeVoteStatusRequest_92a45a0fe4f69d355022d2f2f7622dfc69cc7b123be24b7ad993281979b2a3a2.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.913049807Z_IdentityRequest_8fb3b1a4ef0db316161d4ed79b93efbcc93fdbc66e012e606d530c327265c52d.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.913049807Z_IdentityRequest_8fb3b1a4ef0db316161d4ed79b93efbcc93fdbc66e012e606d530c327265c52d.json new file mode 100644 index 0000000000..8ef1f44147 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:45.913049807Z_IdentityRequest_8fb3b1a4ef0db316161d4ed79b93efbcc93fdbc66e012e606d530c327265c52d.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.146063724Z_GetEpochsInfoRequest_734f6594c67fe6a9ab170191031d592c8fe7361bed628d9a36747664c9789bf1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.146063724Z_GetEpochsInfoRequest_734f6594c67fe6a9ab170191031d592c8fe7361bed628d9a36747664c9789bf1.json new file mode 100644 index 0000000000..d3031228c6 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.146063724Z_GetEpochsInfoRequest_734f6594c67fe6a9ab170191031d592c8fe7361bed628d9a36747664c9789bf1.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.188023131Z_GetEpochsInfoRequest_ae2b6b4e09e8e68e73f2df9af38b0b93d9d2e841a5e3d60755f8e7be3b93315b.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.188023131Z_GetEpochsInfoRequest_ae2b6b4e09e8e68e73f2df9af38b0b93d9d2e841a5e3d60755f8e7be3b93315b.json new file mode 100644 index 0000000000..9e1c943fb3 Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.188023131Z_GetEpochsInfoRequest_ae2b6b4e09e8e68e73f2df9af38b0b93d9d2e841a5e3d60755f8e7be3b93315b.json differ diff --git a/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.205942235Z_GetEpochsInfoRequest_6a828350e795a088dbc835260a1add01a7428085ffdcf1e11cccf19c48c5f7a1.json b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.205942235Z_GetEpochsInfoRequest_6a828350e795a088dbc835260a1add01a7428085ffdcf1e11cccf19c48c5f7a1.json new file mode 100644 index 0000000000..c3f4a7dcbe Binary files /dev/null and b/packages/rs-sdk/tests/vectors/msg_2024-03-18T14:19:46.205942235Z_GetEpochsInfoRequest_6a828350e795a088dbc835260a1add01a7428085ffdcf1e11cccf19c48c5f7a1.json differ diff --git a/packages/rs-sdk/tests/vectors/quorum_pubkey-106-2e7d8ac39b3d5ce5c585b18badd21dcf2753e9d37578afcce21a36925ab5248a.json b/packages/rs-sdk/tests/vectors/quorum_pubkey-106-2e7d8ac39b3d5ce5c585b18badd21dcf2753e9d37578afcce21a36925ab5248a.json new file mode 100644 index 0000000000..053b43b490 --- /dev/null +++ b/packages/rs-sdk/tests/vectors/quorum_pubkey-106-2e7d8ac39b3d5ce5c585b18badd21dcf2753e9d37578afcce21a36925ab5248a.json @@ -0,0 +1 @@ +[185,142,12,82,184,33,154,30,69,210,137,255,249,64,107,251,255,229,23,73,217,177,126,109,27,231,181,124,144,100,151,35,177,119,144,89,90,178,8,184,4,16,203,174,50,47,148,89] \ No newline at end of file diff --git a/packages/strategy-tests/src/lib.rs b/packages/strategy-tests/src/lib.rs index 81e2c1d865..88e2a25020 100644 --- a/packages/strategy-tests/src/lib.rs +++ b/packages/strategy-tests/src/lib.rs @@ -24,7 +24,7 @@ use dpp::data_contract::{DataContract, DataContractFactory}; use dpp::document::{Document, DocumentV0Getters}; use dpp::identity::state_transition::asset_lock_proof::AssetLockProof; -use dpp::identity::{Identity, KeyType, PartialIdentity, Purpose, SecurityLevel}; +use dpp::identity::{Identity, KeyID, KeyType, PartialIdentity, Purpose, SecurityLevel}; use dpp::platform_value::string_encoding::Encoding; use dpp::serialization::{ PlatformDeserializableWithPotentialValidationFromVersionedStructure, @@ -42,7 +42,7 @@ use operations::{DataContractUpdateAction, DataContractUpdateOp}; use platform_version::TryFromPlatformVersioned; use rand::prelude::StdRng; use rand::{thread_rng, Rng}; -use tracing::{error, info}; +use tracing::error; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use bincode::{Decode, Encode}; use dpp::data_contract::document_type::accessors::DocumentTypeV0Getters; @@ -64,6 +64,7 @@ use simple_signer::signer::SimpleSigner; pub mod frequency; pub mod operations; pub mod transitions; +pub type KeyMaps = BTreeMap>>; /// Defines a detailed strategy for conducting simulations or tests on Dash Platform. /// @@ -106,7 +107,7 @@ pub struct Strategy { )>, pub operations: Vec, pub start_identities: StartIdentities, - pub identities_inserts: Frequency, + pub identities_inserts: IdentityInsertInfo, pub identity_contract_nonce_gaps: Option, pub signer: Option, } @@ -126,6 +127,24 @@ pub struct StartIdentities { pub starting_balances: Option, } +/// Identities to register on the first block of the strategy +#[derive(Clone, Debug, PartialEq, Encode, Decode)] +pub struct IdentityInsertInfo { + pub frequency: Frequency, + pub start_keys: u8, + pub extra_keys: KeyMaps, +} + +impl Default for IdentityInsertInfo { + fn default() -> Self { + Self { + frequency: Default::default(), + start_keys: 5, + extra_keys: Default::default(), + } + } +} + #[derive(Clone, Debug, PartialEq)] pub struct RandomDocumentQuery<'a> { pub data_contract: &'a DataContract, @@ -142,7 +161,7 @@ struct StrategyInSerializationFormat { pub contracts_with_updates: Vec<(Vec, Option>>)>, pub operations: Vec>, pub start_identities: StartIdentities, - pub identities_inserts: Frequency, + pub identities_inserts: IdentityInsertInfo, pub identity_contract_nonce_gaps: Option, pub signer: Option, } @@ -968,18 +987,17 @@ impl Strategy { if identities_count == 0 { break; } - + // Select a random identity from the current_identities let random_index = thread_rng().gen_range(0..identities_count); let random_identity = &mut current_identities[random_index]; - + // Get keys already added let keys_already_added = keys_already_added_count_map.get(&random_identity.id()) .expect("Expected to get keys_already_added in IdentityAddKeys ST creation"); - + // Create transition - let (state_transition, keys_to_add_at_end_block) = - crate::transitions::create_identity_update_transition_add_keys( + let (state_transition, keys_to_add_at_end_block) = crate::transitions::create_identity_update_transition_add_keys( random_identity, *keys_count, *keys_already_added, @@ -997,7 +1015,10 @@ impl Strategy { )); // Increment keys_already_added count - keys_already_added_count_map.insert(random_identity.id(), keys_already_added + *keys_count as u32); + keys_already_added_count_map.insert( + random_identity.id(), + keys_already_added + *keys_count as u32, + ); } } IdentityUpdateOp::IdentityUpdateDisableKey(keys_count) => { @@ -1299,6 +1320,7 @@ impl Strategy { let mut new_transitions = crate::transitions::create_identities_state_transitions( self.start_identities.number_of_identities.into(), // number of identities self.start_identities.keys_per_identity.into(), // number of keys per identity + &self.identities_inserts.extra_keys, signer, rng, create_asset_lock, @@ -1310,12 +1332,13 @@ impl Strategy { // Add identities_inserts // Don't do this on first block because we need to skip utxo refresh if block_info.height > config.start_block_height { - let frequency = &self.identities_inserts; + let frequency = &self.identities_inserts.frequency; if frequency.check_hit(rng) { let count = frequency.events(rng); let mut new_transitions = crate::transitions::create_identities_state_transitions( - count, // number of identities - 3, // number of keys per identity + count, // number of identities + self.identities_inserts.start_keys as KeyID, // number of keys per identity + &self.identities_inserts.extra_keys, signer, rng, create_asset_lock, @@ -1687,10 +1710,7 @@ mod tests { keys_per_identity: 3, starting_balances: None, }, - identities_inserts: Frequency { - times_per_block_range: Default::default(), - chance_per_block: None, - }, + identities_inserts: Default::default(), identity_contract_nonce_gaps: None, signer: Some(simple_signer), }; diff --git a/packages/strategy-tests/src/transitions.rs b/packages/strategy-tests/src/transitions.rs index 9f85336d51..fe2477efdf 100644 --- a/packages/strategy-tests/src/transitions.rs +++ b/packages/strategy-tests/src/transitions.rs @@ -34,10 +34,10 @@ use dpp::state_transition::{GetDataContractSecurityLevelRequirementFn, StateTran use dpp::version::PlatformVersion; use dpp::withdrawal::Pooling; use dpp::NativeBlsModule; -use drive::drive::identity::key; use rand::prelude::{IteratorRandom, StdRng}; use simple_signer::signer::SimpleSigner; +use crate::KeyMaps; use dpp::dashcore::transaction::special_transaction::asset_lock::AssetLockPayload; use dpp::dashcore::transaction::special_transaction::TransactionPayload; use std::collections::{BTreeMap, HashSet}; @@ -292,7 +292,8 @@ pub fn create_identity_update_transition_add_keys( ) -> (StateTransition, (Identifier, Vec)) { identity.bump_revision(); - let start_id = (identity.public_keys().len() as u32 + keys_already_added_this_block_count) as KeyID; + let start_id = + (identity.public_keys().len() as u32 + keys_already_added_this_block_count) as KeyID; let keys = IdentityPublicKey::random_authentication_keys_with_private_keys_with_rng( start_id, @@ -489,9 +490,15 @@ pub fn create_identity_withdrawal_transition( let identity_public_key = identity .get_first_public_key_matching( - Purpose::AUTHENTICATION, + Purpose::TRANSFER, HashSet::from([SecurityLevel::CRITICAL]), - HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), + HashSet::from([ + KeyType::ECDSA_SECP256K1, + KeyType::BLS12_381, + KeyType::ECDSA_HASH160, + KeyType::BIP13_SCRIPT_HASH, + KeyType::EDDSA_25519_HASH160, + ]), ) .expect("expected to get a signing key"); @@ -560,7 +567,7 @@ pub fn create_identity_credit_transfer_transition( let identity_public_key = identity .get_first_public_key_matching( - Purpose::AUTHENTICATION, + Purpose::TRANSFER, HashSet::from([SecurityLevel::CRITICAL]), HashSet::from([KeyType::ECDSA_SECP256K1, KeyType::BLS12_381]), ) @@ -617,18 +624,39 @@ pub fn create_identity_credit_transfer_transition( pub fn create_identities_state_transitions( count: u16, key_count: KeyID, + extra_keys: &KeyMaps, signer: &mut SimpleSigner, rng: &mut StdRng, create_asset_lock: &mut impl FnMut(u64) -> Option<(AssetLockProof, PrivateKey)>, platform_version: &PlatformVersion, ) -> Result, ProtocolError> { - let (identities, mut keys) = Identity::random_identities_with_private_keys_with_rng::>( - count, - key_count, - rng, - platform_version, - ) - .expect("Expected to create identities and keys"); + let (mut identities, mut keys) = + Identity::random_identities_with_private_keys_with_rng::>( + count, + key_count, + rng, + platform_version, + ) + .expect("Expected to create identities and keys"); + + for identity in identities.iter_mut() { + for (purpose, security_to_key_type_map) in extra_keys { + for (security_level, key_types) in security_to_key_type_map { + for key_type in key_types { + let (key, private_key) = IdentityPublicKey::random_key_with_known_attributes( + (identity.public_keys().len() + 1) as KeyID, + rng, + *purpose, + *security_level, + *key_type, + platform_version, + )?; + identity.add_public_key(key.clone()); + keys.push((key, private_key)); + } + } + } + } let starting_id_num = signer .private_keys diff --git a/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_purpose_error.rs b/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_purpose_error.rs new file mode 100644 index 0000000000..835d9559a8 --- /dev/null +++ b/packages/wasm-dpp/src/errors/consensus/basic/invalid_signature_public_key_purpose_error.rs @@ -0,0 +1,39 @@ +use dpp::consensus::codes::ErrorWithCode; +use dpp::consensus::signature::InvalidSignaturePublicKeyPurposeError; +use dpp::consensus::ConsensusError; + +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(js_name=InvalidSignaturePublicKeyPurposeError)] +pub struct InvalidSignaturePublicKeyPurposeErrorWasm { + inner: InvalidSignaturePublicKeyPurposeError, +} + +impl From<&InvalidSignaturePublicKeyPurposeError> for InvalidSignaturePublicKeyPurposeErrorWasm { + fn from(e: &InvalidSignaturePublicKeyPurposeError) -> Self { + Self { inner: e.clone() } + } +} + +#[wasm_bindgen(js_class=InvalidSignaturePublicKeyPurposeError)] +impl InvalidSignaturePublicKeyPurposeErrorWasm { + #[wasm_bindgen(js_name=getPublicKeyPurpose)] + pub fn get_public_key_purpose(&self) -> u8 { + self.inner.public_key_purpose() as u8 + } + + #[wasm_bindgen(js_name=getKeyPurposeRequirement)] + pub fn get_allowed_key_purpose(&self) -> u8 { + self.inner.allowed_key_purpose() as u8 + } + + #[wasm_bindgen(js_name=getCode)] + pub fn get_code(&self) -> u32 { + ConsensusError::from(self.inner.clone()).code() + } + + #[wasm_bindgen(getter)] + pub fn message(&self) -> String { + self.inner.to_string() + } +} diff --git a/packages/wasm-dpp/src/errors/consensus/basic/mod.rs b/packages/wasm-dpp/src/errors/consensus/basic/mod.rs index 93a4a87d4e..a67ecbcb52 100644 --- a/packages/wasm-dpp/src/errors/consensus/basic/mod.rs +++ b/packages/wasm-dpp/src/errors/consensus/basic/mod.rs @@ -4,6 +4,7 @@ pub mod document; pub mod identity; mod incompatible_protocol_version_error; mod invalid_identifier_error; +mod invalid_signature_public_key_purpose_error; mod invalid_signature_public_key_security_level_error; mod invalid_state_transition_signature_error; mod json_schema_compilation_error; @@ -19,6 +20,7 @@ mod wrong_public_key_purpose_error; pub use incompatible_protocol_version_error::*; pub use invalid_identifier_error::*; +pub use invalid_signature_public_key_purpose_error::*; pub use invalid_signature_public_key_security_level_error::*; pub use invalid_state_transition_signature_error::*; pub use json_schema_compilation_error::*; diff --git a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs index 81f3ab7f3a..705442b6e3 100644 --- a/packages/wasm-dpp/src/errors/consensus/consensus_error.rs +++ b/packages/wasm-dpp/src/errors/consensus/consensus_error.rs @@ -1,5 +1,6 @@ use crate::errors::consensus::basic::{ - IncompatibleProtocolVersionErrorWasm, InvalidIdentifierErrorWasm, JsonSchemaErrorWasm, + IncompatibleProtocolVersionErrorWasm, InvalidIdentifierErrorWasm, + InvalidSignaturePublicKeyPurposeErrorWasm, JsonSchemaErrorWasm, UnsupportedProtocolVersionErrorWasm, UnsupportedVersionErrorWasm, }; use dpp::consensus::ConsensusError as DPPConsensusError; @@ -417,6 +418,9 @@ fn from_signature_error(signature_error: &SignatureError) -> JsValue { } SignatureError::BasicECDSAError(err) => BasicECDSAErrorWasm::from(err).into(), SignatureError::BasicBLSError(err) => BasicBLSErrorWasm::from(err).into(), + SignatureError::InvalidSignaturePublicKeyPurposeError(err) => { + InvalidSignaturePublicKeyPurposeErrorWasm::from(err).into() + } } } diff --git a/packages/wasm-dpp/src/identity/identity_public_key/purpose.rs b/packages/wasm-dpp/src/identity/identity_public_key/purpose.rs index 0623438ef2..5e598ffa52 100644 --- a/packages/wasm-dpp/src/identity/identity_public_key/purpose.rs +++ b/packages/wasm-dpp/src/identity/identity_public_key/purpose.rs @@ -10,7 +10,7 @@ pub enum PurposeWasm { /// this key cannot be used for signing documents DECRYPTION = 2, /// this key cannot be used for signing documents - WITHDRAW = 3, + TRANSFER = 3, /// this key cannot be used for signing documents SYSTEM = 4, /// this key cannot be used for signing documents @@ -23,7 +23,7 @@ impl From for PurposeWasm { Purpose::AUTHENTICATION => PurposeWasm::AUTHENTICATION, Purpose::ENCRYPTION => PurposeWasm::ENCRYPTION, Purpose::DECRYPTION => PurposeWasm::DECRYPTION, - Purpose::WITHDRAW => PurposeWasm::WITHDRAW, + Purpose::TRANSFER => PurposeWasm::TRANSFER, Purpose::SYSTEM => PurposeWasm::SYSTEM, Purpose::VOTING => PurposeWasm::VOTING, } diff --git a/packages/wasm-dpp/test/integration/dataContract/validation/validateDataContractFactory.spec.js b/packages/wasm-dpp/test/integration/dataContract/validation/validateDataContractFactory.spec.js index fb18dd6ef8..b2c1a582e6 100644 --- a/packages/wasm-dpp/test/integration/dataContract/validation/validateDataContractFactory.spec.js +++ b/packages/wasm-dpp/test/integration/dataContract/validation/validateDataContractFactory.spec.js @@ -1133,7 +1133,7 @@ describe.skip('validateDataContractFactory', () => { const [error] = result.getErrors(); - expect(error.getCode()).to.equal(1009); + expect(error.getCode()).to.equal(10202); expect(error.getPattern()).to.equal('^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$'); expect(error.getPath()).to.equal('/documents/indexedDocument/properties/something'); }); diff --git a/packages/wasm-dpp/test/integration/error/consensus/deserializeConsensusError.spec.js b/packages/wasm-dpp/test/integration/error/consensus/deserializeConsensusError.spec.js index 338b0af120..68a3272a5f 100644 --- a/packages/wasm-dpp/test/integration/error/consensus/deserializeConsensusError.spec.js +++ b/packages/wasm-dpp/test/integration/error/consensus/deserializeConsensusError.spec.js @@ -18,14 +18,14 @@ describe('deserializeConsensusError', () => { const message = 'Can\'t read protocol version from serialized object: test'; expect(consensusError).to.be.instanceOf(ProtocolVersionParsingError); - expect(consensusError.getCode()).to.equals(1000); + expect(consensusError.getCode()).to.equals(10001); expect(consensusError.message).to.equals(message); const serializedConsensusError = consensusError.serialize(); const recoveredError = deserializeConsensusError(serializedConsensusError); expect(recoveredError).to.be.instanceOf(ProtocolVersionParsingError); - expect(recoveredError.getCode()).to.equals(1000); + expect(recoveredError.getCode()).to.equals(10001); expect(recoveredError.message).to.equals(message); }); }); diff --git a/packages/wasm-dpp/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js b/packages/wasm-dpp/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js index af71bb1ecb..2addf1f98d 100644 --- a/packages/wasm-dpp/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js +++ b/packages/wasm-dpp/test/unit/dataContract/stateTransition/DataContractUpdateTransition/validation/state/validateDataContractUpdateTransitionStateFactory.spec.js @@ -97,7 +97,7 @@ describe.skip('validateDataContractUpdateTransitionStateFactory', () => { const [error] = result.getErrors(); expect(error).to.be.an.instanceOf(InvalidDataContractVersionError); - expect(error.getCode()).to.equal(1050); + expect(error.getCode()).to.equal(10212); }); it('should return valid result', async () => { diff --git a/packages/wasm-dpp/test/unit/dataContract/validation/validateDataContractPatterns.spec.js b/packages/wasm-dpp/test/unit/dataContract/validation/validateDataContractPatterns.spec.js index d9020ce065..f7f09bc512 100644 --- a/packages/wasm-dpp/test/unit/dataContract/validation/validateDataContractPatterns.spec.js +++ b/packages/wasm-dpp/test/unit/dataContract/validation/validateDataContractPatterns.spec.js @@ -66,7 +66,7 @@ describe.skip('validateDataContractPatterns', () => { const [error] = result.getErrors(); expect(error).to.be.instanceOf(IncompatibleRe2PatternError); - expect(error.getCode()).to.equal(1009); + expect(error.getCode()).to.equal(10202); expect(error.getPattern()).to.equal('^((?!-|_)[a-zA-Z0-9-_]{0,62}[a-zA-Z0-9])$'); expect(error.getPath()).to.equal('/documents/notFineDocument/properties/bar'); }); diff --git a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js index df48283ad0..3bd09da5bc 100644 --- a/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js +++ b/packages/wasm-dpp/test/unit/document/stateTransition/DocumetsBatchTransition/validation/state/validateDocumentsUniquenessByIndicesFactory.spec.js @@ -201,7 +201,7 @@ describe.skip('validateDocumentsUniquenessByIndices', () => { await expectValidationError(result, DuplicateUniqueIndexError, 4); const errors = result.getErrors(); const [error] = result.getErrors(); - expect(error.getCode()).to.equal(4009); + expect(error.getCode()).to.equal(40105); expect(errors.map((e) => e.getDocumentId())).to.have.deep.members([ documentTransitionsJs[3].getId().toBuffer(),