From 4961d10ef4c5550d15abc9856f5e567aad2687f1 Mon Sep 17 00:00:00 2001 From: shotexa Date: Mon, 25 Mar 2024 19:13:22 +0400 Subject: [PATCH 1/4] refactor: clean up migrations (#830) * Add everything Signed-off-by: Shota Jolbordi * Remove migration tests Signed-off-by: Shota Jolbordi * add ingnore invalid create option for postres mega linter Signed-off-by: Shota Jolbordi * Try mega linter 7 Signed-off-by: Shota Jolbordi * edit megalinter.yaml Signed-off-by: Shota Jolbordi * Disable some linters Signed-off-by: Shota Jolbordi --------- Signed-off-by: Shota Jolbordi --- .github/workflows/lint.yml | 2 +- .gitignore | 4 +- .mega-linter.yml | 38 ++- .../V10__atala_object_tx_submission.sql | 15 - .../db/migration/V11__revoked_credentials.sql | 16 - .../V12__drop_atalaobjects_blockhash.sql | 11 - ...13__add_ledger_data_to_protocol_events.sql | 102 ------ ...V14__atala_object_tx_submissions_index.sql | 3 - .../V15__delete_legacy_credentials_table.sql | 3 - .../db/migration/V16__drop_blocks_table.sql | 4 - .../migration/V17__add_operation_statuses.sql | 16 - .../migration/V18__alter_public_key_table.sql | 5 - .../db/migration/V1__create_tables.sql | 312 +++++++++++++++++- .../migration/V20__alter_public_key_table.sql | 13 - ...1__alter_atala_objects_add_received_at.sql | 12 - .../migration/V22__alter_type_key_usage.sql | 1 - .../V23__add_atala_object_status.sql | 10 - .../V24__add_atala_object_id_indexes.sql | 4 - .../V25__add_protocol_versions_table.sql | 16 - .../migration/V26__add_trusted_proposers.sql | 10 - ...27__atala_operation_status_description.sql | 1 - ...ala_object_status_add_scheduled_status.sql | 1 - .../migration/V29__drop_trusted_proposers.sql | 4 - .../db/migration/V2__atala_object.sql | 24 -- .../V30__add_metrics_counters_db.sql | 4 - .../migration/V31__add_did_request_nonces.sql | 9 - ...d_services_and_service_endpoints_table.sql | 41 --- .../migration/V33__alter_type_key_usage.sql | 4 - ...rvice_endpoints_and_add_it_to_services.sql | 10 - .../db/migration/V35__add_contexts_table.sql | 20 -- .../resources/db/migration/V3__did_tables.sql | 39 --- .../db/migration/V4__credentials_table.sql | 27 -- .../db/migration/V5__key_values_table.sql | 5 - .../V6__atala_objects_add_tx_info.sql | 19 -- ...la_objects_drop_sequence_number_unique.sql | 7 - .../db/migration/V8__atala_object_tx.sql | 31 -- .../V9__credential_batches_table.sql | 31 -- node/src/main/scala/db/migration/.gitkeep | 0 .../scala/db/migration/V19__public_keys.scala | 56 ---- .../iohk/atala/prism/node/migrations/.gitkeep | 0 .../node/migrations/V19MigrationSpec.scala | 82 ----- .../migrations/V6MigrationSpec.scala | 45 --- .../migrations/V8MigrationSpec.scala | 62 ---- 43 files changed, 318 insertions(+), 801 deletions(-) delete mode 100644 node/src/main/resources/db/migration/V10__atala_object_tx_submission.sql delete mode 100644 node/src/main/resources/db/migration/V11__revoked_credentials.sql delete mode 100644 node/src/main/resources/db/migration/V12__drop_atalaobjects_blockhash.sql delete mode 100644 node/src/main/resources/db/migration/V13__add_ledger_data_to_protocol_events.sql delete mode 100644 node/src/main/resources/db/migration/V14__atala_object_tx_submissions_index.sql delete mode 100644 node/src/main/resources/db/migration/V15__delete_legacy_credentials_table.sql delete mode 100644 node/src/main/resources/db/migration/V16__drop_blocks_table.sql delete mode 100644 node/src/main/resources/db/migration/V17__add_operation_statuses.sql delete mode 100644 node/src/main/resources/db/migration/V18__alter_public_key_table.sql delete mode 100644 node/src/main/resources/db/migration/V20__alter_public_key_table.sql delete mode 100644 node/src/main/resources/db/migration/V21__alter_atala_objects_add_received_at.sql delete mode 100644 node/src/main/resources/db/migration/V22__alter_type_key_usage.sql delete mode 100644 node/src/main/resources/db/migration/V23__add_atala_object_status.sql delete mode 100644 node/src/main/resources/db/migration/V24__add_atala_object_id_indexes.sql delete mode 100644 node/src/main/resources/db/migration/V25__add_protocol_versions_table.sql delete mode 100644 node/src/main/resources/db/migration/V26__add_trusted_proposers.sql delete mode 100644 node/src/main/resources/db/migration/V27__atala_operation_status_description.sql delete mode 100644 node/src/main/resources/db/migration/V28__atala_object_status_add_scheduled_status.sql delete mode 100644 node/src/main/resources/db/migration/V29__drop_trusted_proposers.sql delete mode 100644 node/src/main/resources/db/migration/V2__atala_object.sql delete mode 100644 node/src/main/resources/db/migration/V30__add_metrics_counters_db.sql delete mode 100644 node/src/main/resources/db/migration/V31__add_did_request_nonces.sql delete mode 100644 node/src/main/resources/db/migration/V32__add_services_and_service_endpoints_table.sql delete mode 100644 node/src/main/resources/db/migration/V33__alter_type_key_usage.sql delete mode 100644 node/src/main/resources/db/migration/V34__drop_service_endpoints_and_add_it_to_services.sql delete mode 100644 node/src/main/resources/db/migration/V35__add_contexts_table.sql delete mode 100644 node/src/main/resources/db/migration/V3__did_tables.sql delete mode 100644 node/src/main/resources/db/migration/V4__credentials_table.sql delete mode 100644 node/src/main/resources/db/migration/V5__key_values_table.sql delete mode 100644 node/src/main/resources/db/migration/V6__atala_objects_add_tx_info.sql delete mode 100644 node/src/main/resources/db/migration/V7__atala_objects_drop_sequence_number_unique.sql delete mode 100644 node/src/main/resources/db/migration/V8__atala_object_tx.sql delete mode 100644 node/src/main/resources/db/migration/V9__credential_batches_table.sql create mode 100644 node/src/main/scala/db/migration/.gitkeep delete mode 100644 node/src/main/scala/db/migration/V19__public_keys.scala create mode 100644 node/src/test/scala/io/iohk/atala/prism/node/migrations/.gitkeep delete mode 100644 node/src/test/scala/io/iohk/atala/prism/node/migrations/V19MigrationSpec.scala delete mode 100644 node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V6MigrationSpec.scala delete mode 100644 node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V8MigrationSpec.scala diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index de3600b533..638994216a 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -25,7 +25,7 @@ jobs: fetch-depth: 0 - name: Mega-Linter id: ml - uses: megalinter/megalinter@v6 + uses: megalinter/megalinter@v7 - name: Archive production artifacts if: success() || failure() uses: actions/upload-artifact@v3 diff --git a/.gitignore b/.gitignore index 12b25d1797..8ae454e2e8 100644 --- a/.gitignore +++ b/.gitignore @@ -20,8 +20,7 @@ out/ **/.bloop/ *.worksheet.sc **/metals.sbt -prism-interactive-demo-web/src/protos/intdemo -*.aux +*.aux *.toc *.pdf .idea_modules @@ -35,3 +34,4 @@ mill client-storage.txt .bsp *.sc +megalinter-reports diff --git a/.mega-linter.yml b/.mega-linter.yml index febb121a33..7bf516a131 100644 --- a/.mega-linter.yml +++ b/.mega-linter.yml @@ -4,23 +4,25 @@ APPLY_FIXES: all DEFAULT_BRANCH: main DISABLE_LINTERS: [ - REPOSITORY_DEVSKIM, - REPOSITORY_GITLEAKS, - DOCKERFILE_HADOLINT, - REPOSITORY_TRIVY, - REPOSITORY_CHECKOV, - REPOSITORY_SECRETLINT, - SCALA_SCALAFIX, - SQL_TSQLLINT, - C_CPPLINT, # For pollux/lib/anoncreds/src/main/c - CPP_CPPLINT, # For pollux/lib/anoncreds/src/main/c - JAVA_CHECKSTYLE, # For pollux/lib/anoncreds/src/main/java + REPOSITORY_DEVSKIM, + REPOSITORY_GITLEAKS, + DOCKERFILE_HADOLINT, + REPOSITORY_TRIVY, + REPOSITORY_CHECKOV, + REPOSITORY_SECRETLINT, + SCALA_SCALAFIX, + SQL_TSQLLINT, + C_CPPLINT, # For pollux/lib/anoncreds/src/main/c + CPP_CPPLINT, # For pollux/lib/anoncreds/src/main/c + JAVA_CHECKSTYLE, # For pollux/lib/anoncreds/src/main/java ] DISABLE_ERRORS_LINTERS: [ - KOTLIN_KTLINT, - PROTOBUF_PROTOLINT, - OPENAPI_SPECTRAL, - MARKDOWN_MARKDOWN_LINK_CHECK, + KOTLIN_KTLINT, + PROTOBUF_PROTOLINT, + OPENAPI_SPECTRAL, + MARKDOWN_MARKDOWN_LINK_CHECK, + REPOSITORY_TRUFFLEHOG, + REPOSITORY_KICS, ] DISABLE: [COPYPASTE, SPELL, CREDENTIALS] @@ -37,13 +39,13 @@ BASH_SHELLCHECK_DISABLE_ERRORS: true # that could lead to new files in workspace created # with CLRF instead of CL due docker/python/git chain PRE_COMMANDS: - - command: git config --global core.autocrlf input - cwd: "workspace" + - command: git config --global core.autocrlf input + cwd: "workspace" # Linter customisation MARKDOWN_MARKDOWN_LINK_CHECK_FILTER_REGEX_EXCLUDE: "CHANGELOG.md" MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: "CHANGELOG.md" -SQL_SQL_LINT_ARGUMENTS: -d postgres --ignore-errors=postgres-invalid-alter-option +SQL_SQL_LINT_ARGUMENTS: -d postgres --ignore-errors=postgres-invalid-alter-option,postgres-invalid-create-option YAML_YAMLLINT_FILTER_REGEX_EXCLUDE: "infrastructure/charts/node/*" YAML_PRETTIER_FILTER_REGEX_EXCLUDE: "infrastructure/charts/node/*" YAML_V8R_FILTER_REGEX_EXCLUDE: "infrastructure/charts/node/*" diff --git a/node/src/main/resources/db/migration/V10__atala_object_tx_submission.sql b/node/src/main/resources/db/migration/V10__atala_object_tx_submission.sql deleted file mode 100644 index 0681313281..0000000000 --- a/node/src/main/resources/db/migration/V10__atala_object_tx_submission.sql +++ /dev/null @@ -1,15 +0,0 @@ -CREATE TYPE ATALA_OBJECT_TRANSACTION_STATUS AS ENUM('PENDING', 'DELETED', 'IN_LEDGER'); - --- Create table to record all transaction submissions -CREATE TABLE atala_object_tx_submissions ( - atala_object_id ATALA_OBJECT_ID NOT NULL, - ledger VARCHAR(32) NOT NULL, - transaction_id TRANSACTION_ID NOT NULL, - submission_timestamp TIMESTAMPTZ NOT NULL, - status ATALA_OBJECT_TRANSACTION_STATUS NOT NULL, - - CONSTRAINT atala_object_tx_submissions_pk PRIMARY KEY (ledger, transaction_id), - CONSTRAINT atala_object_tx_submissions_atala_object_id_fk - FOREIGN KEY (atala_object_id) - REFERENCES atala_objects (atala_object_id) -); diff --git a/node/src/main/resources/db/migration/V11__revoked_credentials.sql b/node/src/main/resources/db/migration/V11__revoked_credentials.sql deleted file mode 100644 index 8d73cbe3aa..0000000000 --- a/node/src/main/resources/db/migration/V11__revoked_credentials.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE DOMAIN CREDENTIAL_HASH AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE revoked_credentials( - batch_id ID_TYPE NOT NULL, - credential_id CREDENTIAL_HASH NOT NULL, - revoked_on TIMESTAMPTZ NOT NULL, - -- Atala Block Sequence Number (absn) of the operation that revoked the batch - revoked_on_absn INTEGER NOT NULL, - -- Operation Sequence Number (osn) of the operation that revoked the batch - revoked_on_osn INTEGER NOT NULL, - CONSTRAINT revoked_credentials_pk PRIMARY KEY (batch_id, credential_id), - CONSTRAINT revoked_credentials_batch_id_fk FOREIGN KEY (batch_id) REFERENCES credential_batches (batch_id) -); \ No newline at end of file diff --git a/node/src/main/resources/db/migration/V12__drop_atalaobjects_blockhash.sql b/node/src/main/resources/db/migration/V12__drop_atalaobjects_blockhash.sql deleted file mode 100644 index 6d540621c5..0000000000 --- a/node/src/main/resources/db/migration/V12__drop_atalaobjects_blockhash.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Set a default value for objects without content --- (this may happen only in a local dev env, so it's fine to corrupt it) -UPDATE atala_objects - SET object_content = '' - WHERE object_content IS NULL; - -ALTER TABLE atala_objects - -- Delete atala_block_hash as it's no longer used (in favor of object_content) - DROP COLUMN atala_block_hash, - -- Make object_content required - ALTER COLUMN object_content SET NOT NULL; diff --git a/node/src/main/resources/db/migration/V13__add_ledger_data_to_protocol_events.sql b/node/src/main/resources/db/migration/V13__add_ledger_data_to_protocol_events.sql deleted file mode 100644 index 373562e21d..0000000000 --- a/node/src/main/resources/db/migration/V13__add_ledger_data_to_protocol_events.sql +++ /dev/null @@ -1,102 +0,0 @@ --- As part of ATA-4153, we intend to store in the database the information of the --- underlying blockchain transaction that carried each operation. Before this story, --- we were only storing timestamp information associated to the transaction. Now, we --- will also add the transaction id and the ledger where the transaction belongs to. - --- For legacy purpose, we need to add mock data to existing tables --- We will use: --- · the InMemoryLedger, and --- · a proper byte array for transaction id - --- + did_data table -ALTER TABLE did_data - ADD COLUMN transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL, - -- we will additionally add timestamp information to this table - ADD COLUMN published_on TIMESTAMPTZ NULL, - ADD COLUMN published_on_absn INTEGER NULL, - ADD COLUMN published_on_osn INTEGER NULL; - -UPDATE did_data - SET transaction_id = last_operation::TRANSACTION_ID, -- we can take the bytes from this column - ledger = 'InMemory', - published_on = now(), - published_on_absn = 1, - published_on_osn = 1; - -ALTER TABLE did_data - ALTER COLUMN transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL, - ALTER COLUMN published_on SET NOT NULL, - ALTER COLUMN published_on_absn SET NOT NULL, - ALTER COLUMN published_on_osn SET NOT NULL; - - --- + credentials table -ALTER TABLE credentials - ADD COLUMN issued_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN revoked_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL; -- we assume the same ledger for issuance and revocation - -UPDATE credentials - SET issued_on_transaction_id = last_operation::TRANSACTION_ID, - ledger = 'InMemory'; - -ALTER TABLE credentials - ALTER COLUMN issued_on_transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL; - --- + credential_batches table -ALTER TABLE credential_batches - ADD COLUMN issued_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN revoked_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL; - -UPDATE credential_batches - SET issued_on_transaction_id = last_operation::TRANSACTION_ID, - ledger = 'InMemory'; - -ALTER TABLE credential_batches - ALTER COLUMN issued_on_transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL; - --- + revoked_credentials table -ALTER TABLE revoked_credentials - ADD COLUMN transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL; - -UPDATE revoked_credentials - SET transaction_id = credential_id::TRANSACTION_ID, - ledger = 'InMemory'; - -ALTER TABLE revoked_credentials - ALTER COLUMN transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL; - --- + public_keys table --- in this table, there is no BYTEA value we could use for default transaction_id, --- we neither have a hex encoded BYTEA we could use, we will use the function found --- here: https://dba.stackexchange.com/questions/22512/how-can-i-generate-a-random-bytea -create function random_bytea(p_length in integer) returns bytea language plpgsql as $$ -declare - o bytea := ''; -begin - for i in 1..p_length loop - o := o||decode(lpad(to_hex(width_bucket(random(), 0, 1, 256)-1),2,'0'), 'hex'); - end loop; - return o; -end;$$; --- it is not the most efficient but it will be enough for our case - -ALTER TABLE public_keys - ADD COLUMN added_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN revoked_on_transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL; -- we assume the same ledger for key addition and revocation - -UPDATE public_keys - SET added_on_transaction_id = random_bytea(32), - ledger = 'InMemory'; - -ALTER TABLE public_keys - ALTER COLUMN added_on_transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL; diff --git a/node/src/main/resources/db/migration/V14__atala_object_tx_submissions_index.sql b/node/src/main/resources/db/migration/V14__atala_object_tx_submissions_index.sql deleted file mode 100644 index 1250c6d626..0000000000 --- a/node/src/main/resources/db/migration/V14__atala_object_tx_submissions_index.sql +++ /dev/null @@ -1,3 +0,0 @@ --- Speed up queries on atala_object_tx_submissions -CREATE INDEX atala_object_tx_submissions_latest_index ON atala_object_tx_submissions USING BTREE (atala_object_id, submission_timestamp); -CREATE INDEX atala_object_tx_submissions_filter_index ON atala_object_tx_submissions USING BTREE (submission_timestamp, status, ledger); diff --git a/node/src/main/resources/db/migration/V15__delete_legacy_credentials_table.sql b/node/src/main/resources/db/migration/V15__delete_legacy_credentials_table.sql deleted file mode 100644 index dd09dd7bed..0000000000 --- a/node/src/main/resources/db/migration/V15__delete_legacy_credentials_table.sql +++ /dev/null @@ -1,3 +0,0 @@ --- We can now delete the old credentials table - -DROP TABLE credentials; diff --git a/node/src/main/resources/db/migration/V16__drop_blocks_table.sql b/node/src/main/resources/db/migration/V16__drop_blocks_table.sql deleted file mode 100644 index 7f75e1f5eb..0000000000 --- a/node/src/main/resources/db/migration/V16__drop_blocks_table.sql +++ /dev/null @@ -1,4 +0,0 @@ --- ATA-4656: We deleted the code related to the bitcoin network. --- As a consequence, we do not need the "blocks" table anymore - -DROP TABLE blocks; \ No newline at end of file diff --git a/node/src/main/resources/db/migration/V17__add_operation_statuses.sql b/node/src/main/resources/db/migration/V17__add_operation_statuses.sql deleted file mode 100644 index 1206ec1171..0000000000 --- a/node/src/main/resources/db/migration/V17__add_operation_statuses.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE TYPE ATALA_OPERATION_STATUS AS ENUM('UNKNOWN', 'RECEIVED', 'APPLIED', 'REJECTED'); -CREATE DOMAIN ATALA_OPERATION_ID AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE atala_operations( - signed_atala_operation_id ATALA_OPERATION_ID NOT NULL, - atala_object_id ATALA_OBJECT_ID NOT NULL, - atala_operation_status ATALA_OPERATION_STATUS NOT NULL, - -- constraints - CONSTRAINT signed_atala_operation_id_pk PRIMARY KEY (signed_atala_operation_id), - CONSTRAINT atala_object_id_fk - FOREIGN KEY (atala_object_id) - REFERENCES atala_objects (atala_object_id) -); diff --git a/node/src/main/resources/db/migration/V18__alter_public_key_table.sql b/node/src/main/resources/db/migration/V18__alter_public_key_table.sql deleted file mode 100644 index 92a6f4b034..0000000000 --- a/node/src/main/resources/db/migration/V18__alter_public_key_table.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE public_keys -ADD COLUMN xCompressed bytea NULL; - -ALTER TABLE public_keys -ADD CONSTRAINT x_compressed_length CHECK (LENGTH(xCompressed) = 33); diff --git a/node/src/main/resources/db/migration/V1__create_tables.sql b/node/src/main/resources/db/migration/V1__create_tables.sql index 6d1df791d0..ed6c7eb99b 100644 --- a/node/src/main/resources/db/migration/V1__create_tables.sql +++ b/node/src/main/resources/db/migration/V1__create_tables.sql @@ -1,24 +1,302 @@ +CREATE SCHEMA IF NOT EXISTS PUBLIC + AUTHORIZATION postgres; -CREATE DOMAIN BLOCKHASH_TYPE AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 +CREATE DOMAIN public.atala_object_id AS BYTEA CONSTRAINT atala_object_id_check CHECK (length(VALUE) = 32); + + +CREATE TYPE public.atala_object_status AS ENUM ('SCHEDULED', 'PENDING', 'MERGED', 'PROCESSED'); + + +CREATE TYPE public.atala_object_transaction_status AS ENUM ('PENDING', 'DELETED', 'IN_LEDGER'); + + +CREATE DOMAIN public.atala_operation_id AS BYTEA CONSTRAINT atala_operation_id_check CHECK (length(VALUE) = 32); + + +CREATE TYPE public.atala_operation_status AS ENUM ('UNKNOWN', 'RECEIVED', 'APPLIED', 'REJECTED'); + + +CREATE DOMAIN public.block_hash_type AS BYTEA CONSTRAINT block_hash_type_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.block_no AS integer CONSTRAINT block_no_check CHECK (VALUE >= 0); + + +CREATE DOMAIN public.blockhash_type AS BYTEA CONSTRAINT blockhash_type_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.content_hash AS BYTEA CONSTRAINT content_hash_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.credential_hash AS BYTEA CONSTRAINT credential_hash_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.did AS text COLLATE "default" CONSTRAINT did_check CHECK (VALUE ~ '^did:[a-z0-9]+:[a-zA-Z0-9._-]*(:[a-zA-Z0-9._-]*)*$'::text); + + +CREATE DOMAIN public.id_type AS text COLLATE "default" CONSTRAINT id_type_check CHECK (VALUE ~ '^[0-9a-f]{64}$'::text); + + +CREATE TYPE public.key_usage AS ENUM ('MASTER_KEY', 'ISSUING_KEY', 'KEY_AGREEMENT_KEY', 'AUTHENTICATION_KEY', 'REVOCATION_KEY', 'CAPABILITY_INVOCATION_KEY', 'CAPABILITY_DELEGATION_KEY'); + + +CREATE DOMAIN public.merkle_root AS BYTEA CONSTRAINT merkle_root_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.non_negative_int_type AS integer CONSTRAINT non_negative_int_type_check CHECK (VALUE >= 0); + + +CREATE DOMAIN public.operation_hash AS BYTEA CONSTRAINT operation_hash_check CHECK (length(VALUE) = 32); + + +CREATE DOMAIN public.transaction_id AS BYTEA CONSTRAINT transaction_id_check CHECK (length(VALUE) = 32); + + +CREATE TABLE public.atala_objects +( + atala_object_id public.atala_object_id NOT NULL, + object_content BYTEA NOT NULL, + received_at timestamptz NOT NULL, + atala_object_status public.atala_object_status DEFAULT 'PENDING'::atala_object_status NULL, + CONSTRAINT atala_objects_pk PRIMARY KEY (atala_object_id) +); + + +CREATE INDEX atala_objects_atala_object_status_index ON public.atala_objects USING btree (atala_object_status); + + +CREATE INDEX atala_objects_received_at ON public.atala_objects USING btree (received_at); + + +CREATE TABLE public.contexts +( + context_id public.id_type NOT NULL, + did_suffix public.id_type NOT NULL, + context text NOT NULL, + added_on_transaction_id public.transaction_id NOT NULL, + added_on timestamptz NOT NULL, + added_on_absn int4 NOT NULL, + added_on_osn int4 NOT NULL, + revoked_on_transaction_id public.transaction_id NULL, + revoked_on timestamptz NULL, + revoked_on_absn int4 NULL, + revoked_on_osn int4 NULL, + CONSTRAINT contexts_pkey PRIMARY KEY (context_id) +); + + +CREATE UNIQUE INDEX unique_did_suffix_and_context_string_on_non_revoked ON public.contexts USING btree (did_suffix, context) + WHERE (revoked_on IS NULL); + + +CREATE TABLE public.did_data +( + did_suffix public.id_type NOT NULL, + last_operation public.operation_hash NOT NULL, + transaction_id public.transaction_id NOT NULL, + ledger varchar(32) NOT NULL, + published_on timestamptz NOT NULL, + published_on_absn int4 NOT NULL, + published_on_osn int4 NOT NULL, + CONSTRAINT did_data_pk PRIMARY KEY (did_suffix) +); + + +CREATE TABLE public.did_request_nonces +( + request_nonce BYTEA NOT NULL, + did public.did NOT NULL, + CONSTRAINT did_request_nonces_pk PRIMARY KEY (request_nonce, + did) +); + + +CREATE TABLE public.key_values +( + "key" varchar(64) NOT NULL, + value text NULL, + CONSTRAINT key_values_pkey PRIMARY KEY (KEY) +); + + +CREATE TABLE public.metrics_counters +( + counter_name varchar(256) NOT NULL, + counter_value public.non_negative_int_type DEFAULT 0 NOT NULL, + CONSTRAINT metrics_counters_pkey PRIMARY KEY (counter_name) +); + + +CREATE TABLE public.protocol_versions +( + major_version public.non_negative_int_type NOT NULL, + minor_version public.non_negative_int_type NOT NULL, + version_name varchar(256) NULL, + effective_since public.block_no NOT NULL, + published_in public.transaction_id NOT NULL, + is_effective bool NOT NULL, + proposer_did public.id_type NOT NULL, + CONSTRAINT protocol_version_pk PRIMARY KEY (major_version, + minor_version) +); + + +CREATE TABLE public.public_keys +( + did_suffix public.id_type NOT NULL, + key_id text NOT NULL, + key_usage public.key_usage NOT NULL, + curve text NOT NULL, + added_on timestamptz NOT NULL, + added_on_absn int4 NOT NULL, + added_on_osn int4 NOT NULL, + revoked_on timestamptz NULL, + revoked_on_absn int4 NULL, + revoked_on_osn int4 NULL, + added_on_transaction_id public.transaction_id NOT NULL, + revoked_on_transaction_id public.transaction_id NULL, + ledger varchar(32) NOT NULL, + compressed BYTEA NOT NULL, + CONSTRAINT public_keys_pk PRIMARY KEY (did_suffix, + key_id), + CONSTRAINT x_compressed_length CHECK ((length(compressed) = 33)) +); + + +CREATE TABLE public.atala_object_tx_submissions +( + atala_object_id public.atala_object_id NOT NULL, + ledger varchar(32) NOT NULL, + transaction_id public.transaction_id NOT NULL, + submission_timestamp timestamptz NOT NULL, + status public.atala_object_transaction_status NOT NULL, + CONSTRAINT atala_object_tx_submissions_pk PRIMARY KEY (ledger, + transaction_id), + CONSTRAINT atala_object_tx_submissions_atala_object_id_fk + FOREIGN KEY (atala_object_id) REFERENCES public.atala_objects (atala_object_id) +); + + +CREATE INDEX atala_object_tx_submissions_atala_object_id_index ON public.atala_object_tx_submissions USING hash (atala_object_id); + + +CREATE INDEX atala_object_tx_submissions_filter_index ON public.atala_object_tx_submissions USING btree (submission_timestamp, status, ledger); + + +CREATE INDEX atala_object_tx_submissions_latest_index ON public.atala_object_tx_submissions USING btree (atala_object_id, submission_timestamp); + + +CREATE TABLE public.atala_object_txs +( + atala_object_id public.atala_object_id NOT NULL, + ledger varchar(32) NOT NULL, + block_number int4 NOT NULL, + block_timestamp timestamptz NOT NULL, + block_index int4 NOT NULL, + transaction_id public.transaction_id NOT NULL, + CONSTRAINT atala_object_txs_pk PRIMARY KEY (atala_object_id), + CONSTRAINT atala_object_txs_atala_object_id_fk + FOREIGN KEY (atala_object_id) REFERENCES public.atala_objects (atala_object_id) +); + + +CREATE INDEX atala_object_txs_atala_object_id_index ON public.atala_object_txs USING hash (atala_object_id); + + +CREATE TABLE public.atala_operations +( + signed_atala_operation_id public.atala_operation_id NOT NULL, + atala_object_id public.atala_object_id NOT NULL, + atala_operation_status public.atala_operation_status NOT NULL, + status_details varchar(256) DEFAULT ''::CHARACTER varying NULL, + CONSTRAINT signed_atala_operation_id_pk PRIMARY KEY (signed_atala_operation_id), + CONSTRAINT atala_object_id_fk + FOREIGN KEY (atala_object_id) REFERENCES public.atala_objects (atala_object_id) ); -CREATE DOMAIN NON_NEGATIVE_INT_TYPE AS INT -CHECK ( - VALUE >= 0 + +CREATE TABLE public.credential_batches +( + batch_id public.id_type NOT NULL, + last_operation public.operation_hash NOT NULL, + issuer_did_suffix public.id_type NOT NULL, + merkle_root public.merkle_root NOT NULL, + issued_on timestamptz NOT NULL, + issued_on_absn int4 NOT NULL, + issued_on_osn int4 NOT NULL, + revoked_on timestamptz NULL, + revoked_on_absn int4 NULL, + revoked_on_osn int4 NULL, + issued_on_transaction_id public.transaction_id NOT NULL, + revoked_on_transaction_id public.transaction_id NULL, + ledger varchar(32) NOT NULL, + CONSTRAINT credential_batches_pk PRIMARY KEY (batch_id), + CONSTRAINT revoke_on_check CHECK ((((revoked_on IS NULL) + AND (revoked_on_absn IS NULL) + AND (revoked_on_osn IS NULL)) + OR ((revoked_on IS NOT NULL) + AND (revoked_on_absn IS NOT NULL) + AND (revoked_on_osn IS NOT NULL)))), + CONSTRAINT credential_batches_issuer_did_suffix_fk + FOREIGN KEY (issuer_did_suffix) REFERENCES public.did_data (did_suffix) ); -CREATE TABLE blocks( - blockhash BLOCKHASH_TYPE NOT NULL, - previous_blockhash BLOCKHASH_TYPE NULL, - height NON_NEGATIVE_INT_TYPE NOT NULL, - time BIGINT NOT NULL, - -- constraints - CONSTRAINT blocks_blockhash_pk PRIMARY KEY (blockhash), - CONSTRAINT blocks_height_unique UNIQUE (height), - CONSTRAINT blocks_previous_blockhash_fk FOREIGN KEY (previous_blockhash) REFERENCES blocks (blockhash) + +CREATE INDEX credential_batches_issuer_did_suffix_index ON public.credential_batches USING btree (issuer_did_suffix); + + +CREATE TABLE public.revoked_credentials +( + batch_id public.id_type NOT NULL, + credential_id public.credential_hash NOT NULL, + revoked_on timestamptz NOT NULL, + revoked_on_absn int4 NOT NULL, + revoked_on_osn int4 NOT NULL, + transaction_id public.transaction_id NOT NULL, + ledger varchar(32) NOT NULL, + CONSTRAINT revoked_credentials_pk PRIMARY KEY (batch_id, + credential_id), + CONSTRAINT revoked_credentials_batch_id_fk + FOREIGN KEY (batch_id) REFERENCES public.credential_batches (batch_id) ); -CREATE INDEX blocks_time_index ON blocks USING BTREE (time); -CREATE INDEX blocks_previous_blockhash_index ON blocks USING BTREE (previous_blockhash); + +CREATE TABLE public.services +( + service_id public.id_type NOT NULL, + id text NOT NULL, + did_suffix public.id_type NOT NULL, + "type" text NOT NULL, + added_on_transaction_id public.transaction_id NOT NULL, + added_on timestamptz NOT NULL, + added_on_absn int4 NOT NULL, + added_on_osn int4 NOT NULL, + revoked_on_transaction_id public.transaction_id NULL, + revoked_on timestamptz NULL, + revoked_on_absn int4 NULL, + revoked_on_osn int4 NULL, + ledger varchar(32) NOT NULL, + service_endpoints text NOT NULL, + CONSTRAINT services_pkey PRIMARY KEY (service_id), + CONSTRAINT services_did_suffix_fk + FOREIGN KEY (did_suffix) REFERENCES public.did_data (did_suffix) +); + + +CREATE UNIQUE INDEX unique_did_suffix_and_id_on_non_revoked ON public.services USING btree (did_suffix, id) + WHERE (revoked_on IS NULL); + + +CREATE OR REPLACE FUNCTION public.random_bytea(p_length integer) RETURNS BYTEA + LANGUAGE PLPGSQL AS +$function$ +declare + o bytea := ''; +begin + for i in 1..p_length + loop + o := o || decode(lpad(to_hex(width_bucket(random(), 0, 1, 256) - 1), 2, '0'), 'hex'); + end loop; + return o; +end; +$function$; diff --git a/node/src/main/resources/db/migration/V20__alter_public_key_table.sql b/node/src/main/resources/db/migration/V20__alter_public_key_table.sql deleted file mode 100644 index 719a71d534..0000000000 --- a/node/src/main/resources/db/migration/V20__alter_public_key_table.sql +++ /dev/null @@ -1,13 +0,0 @@ -ALTER TABLE public_keys -DROP COLUMN x; - -ALTER TABLE public_keys -DROP COLUMN y; - -ALTER TABLE public_keys -RENAME COLUMN xCompressed -TO compressed; - -ALTER TABLE public_keys -ALTER COLUMN compressed -SET NOT NULL; \ No newline at end of file diff --git a/node/src/main/resources/db/migration/V21__alter_atala_objects_add_received_at.sql b/node/src/main/resources/db/migration/V21__alter_atala_objects_add_received_at.sql deleted file mode 100644 index 0bc59f5225..0000000000 --- a/node/src/main/resources/db/migration/V21__alter_atala_objects_add_received_at.sql +++ /dev/null @@ -1,12 +0,0 @@ -ALTER TABLE atala_objects - ADD COLUMN received_at TIMESTAMPTZ NULL; - --- Set a default value for objects without timestamp -UPDATE atala_objects - SET received_at = NOW(); - -ALTER TABLE atala_objects - -- Set received_at column mandatory - ALTER COLUMN received_at SET NOT NULL; - -CREATE INDEX atala_objects_received_at on atala_objects USING BTREE(received_at); diff --git a/node/src/main/resources/db/migration/V22__alter_type_key_usage.sql b/node/src/main/resources/db/migration/V22__alter_type_key_usage.sql deleted file mode 100644 index cc6b3f4c92..0000000000 --- a/node/src/main/resources/db/migration/V22__alter_type_key_usage.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TYPE KEY_USAGE ADD VALUE 'REVOCATION_KEY'; diff --git a/node/src/main/resources/db/migration/V23__add_atala_object_status.sql b/node/src/main/resources/db/migration/V23__add_atala_object_status.sql deleted file mode 100644 index 086434e52b..0000000000 --- a/node/src/main/resources/db/migration/V23__add_atala_object_status.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TYPE ATALA_OBJECT_STATUS AS ENUM('PENDING', 'MERGED', 'PROCESSED'); - -ALTER TABLE atala_objects - ADD COLUMN atala_object_status ATALA_OBJECT_STATUS DEFAULT 'PENDING'; - -UPDATE atala_objects - SET atala_object_status = 'PROCESSED' - WHERE processed = true; - -ALTER TABLE atala_objects DROP COLUMN processed; diff --git a/node/src/main/resources/db/migration/V24__add_atala_object_id_indexes.sql b/node/src/main/resources/db/migration/V24__add_atala_object_id_indexes.sql deleted file mode 100644 index 5f4e1b0b27..0000000000 --- a/node/src/main/resources/db/migration/V24__add_atala_object_id_indexes.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE INDEX atala_objects_atala_object_status_index ON atala_objects USING BTREE (atala_object_status); - -CREATE INDEX atala_object_tx_submissions_atala_object_id_index ON atala_object_tx_submissions USING HASH (atala_object_id); -CREATE INDEX atala_object_txs_atala_object_id_index ON atala_object_txs USING HASH (atala_object_id); diff --git a/node/src/main/resources/db/migration/V25__add_protocol_versions_table.sql b/node/src/main/resources/db/migration/V25__add_protocol_versions_table.sql deleted file mode 100644 index e62a200cf6..0000000000 --- a/node/src/main/resources/db/migration/V25__add_protocol_versions_table.sql +++ /dev/null @@ -1,16 +0,0 @@ -CREATE DOMAIN BLOCK_NO AS INT -CHECK ( - VALUE >= 0 -); - -create table protocol_versions( - major_version non_negative_int_type not null, - minor_version non_negative_int_type not null, - version_name varchar(256) null, - effective_since BLOCK_NO not null, - published_in transaction_id not null, - is_effective bool not null, - proposer_did id_type not null, - - CONSTRAINT protocol_version_pk PRIMARY KEY (major_version, minor_version) -); diff --git a/node/src/main/resources/db/migration/V26__add_trusted_proposers.sql b/node/src/main/resources/db/migration/V26__add_trusted_proposers.sql deleted file mode 100644 index 509df7b891..0000000000 --- a/node/src/main/resources/db/migration/V26__add_trusted_proposers.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE trusted_proposers( - did_suffix id_type, - - CONSTRAINT trusted_proposers_pk PRIMARY KEY (did_suffix) -); - -ALTER TABLE protocol_versions - ADD CONSTRAINT proposer_fk - FOREIGN KEY (proposer_did) - REFERENCES trusted_proposers (did_suffix); diff --git a/node/src/main/resources/db/migration/V27__atala_operation_status_description.sql b/node/src/main/resources/db/migration/V27__atala_operation_status_description.sql deleted file mode 100644 index 8ab2ff5aea..0000000000 --- a/node/src/main/resources/db/migration/V27__atala_operation_status_description.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE atala_operations ADD COLUMN status_details VARCHAR(256) DEFAULT ''; diff --git a/node/src/main/resources/db/migration/V28__atala_object_status_add_scheduled_status.sql b/node/src/main/resources/db/migration/V28__atala_object_status_add_scheduled_status.sql deleted file mode 100644 index 29dc2d3cbf..0000000000 --- a/node/src/main/resources/db/migration/V28__atala_object_status_add_scheduled_status.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TYPE ATALA_OBJECT_STATUS ADD VALUE 'SCHEDULED' BEFORE 'PENDING'; \ No newline at end of file diff --git a/node/src/main/resources/db/migration/V29__drop_trusted_proposers.sql b/node/src/main/resources/db/migration/V29__drop_trusted_proposers.sql deleted file mode 100644 index d59a0ef77a..0000000000 --- a/node/src/main/resources/db/migration/V29__drop_trusted_proposers.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE protocol_versions - DROP CONSTRAINT proposer_fk; - -DROP TABLE trusted_proposers; diff --git a/node/src/main/resources/db/migration/V2__atala_object.sql b/node/src/main/resources/db/migration/V2__atala_object.sql deleted file mode 100644 index e7d642b620..0000000000 --- a/node/src/main/resources/db/migration/V2__atala_object.sql +++ /dev/null @@ -1,24 +0,0 @@ -CREATE DOMAIN ATALA_OBJECT_ID AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE DOMAIN BLOCK_HASH_TYPE AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE atala_objects( - atala_object_id ATALA_OBJECT_ID NOT NULL, - sequence_number INTEGER NOT NULL, - object_timestamp TIMESTAMPTZ NOT NULL, - atala_block_hash BLOCK_HASH_TYPE NULL DEFAULT NULL, - object_content BYTEA NULL DEFAULT NULL, - processed BOOLEAN NOT NULL DEFAULT FALSE, - -- constraints - CONSTRAINT atala_objects_pk PRIMARY KEY (atala_object_id), - CONSTRAINT atala_objects_sequence_number_unique UNIQUE (sequence_number), - CONSTRAINT atala_objects_sequence_number_positive CHECK (sequence_number > 0) -); - -CREATE INDEX atala_objects_sequence_number_index on atala_objects USING BTREE(sequence_number); diff --git a/node/src/main/resources/db/migration/V30__add_metrics_counters_db.sql b/node/src/main/resources/db/migration/V30__add_metrics_counters_db.sql deleted file mode 100644 index 8219f3eef2..0000000000 --- a/node/src/main/resources/db/migration/V30__add_metrics_counters_db.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE metrics_counters( - counter_name VARCHAR(256) PRIMARY KEY NOT NULL, - counter_value NON_NEGATIVE_INT_TYPE NOT NULL DEFAULT 0 -); diff --git a/node/src/main/resources/db/migration/V31__add_did_request_nonces.sql b/node/src/main/resources/db/migration/V31__add_did_request_nonces.sql deleted file mode 100644 index 8101dc5417..0000000000 --- a/node/src/main/resources/db/migration/V31__add_did_request_nonces.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE DOMAIN DID AS TEXT CHECK( - VALUE ~ '^did:[a-z0-9]+:[a-zA-Z0-9._-]*(:[a-zA-Z0-9._-]*)*$' -); - -CREATE TABLE did_request_nonces ( - request_nonce BYTEA NOT NULL, - did DID NOT NULL, - CONSTRAINT did_request_nonces_pk PRIMARY KEY (request_nonce, did) -); diff --git a/node/src/main/resources/db/migration/V32__add_services_and_service_endpoints_table.sql b/node/src/main/resources/db/migration/V32__add_services_and_service_endpoints_table.sql deleted file mode 100644 index ac45e91396..0000000000 --- a/node/src/main/resources/db/migration/V32__add_services_and_service_endpoints_table.sql +++ /dev/null @@ -1,41 +0,0 @@ -CREATE TABLE services -( - service_id ID_TYPE PRIMARY KEY NOT NULL, - id TEXT NOT NULl, - did_suffix ID_TYPE NOT NULL, - type TEXT NOT NULL, - - added_on_transaction_id TRANSACTION_ID NOT NULL, - added_on TIMESTAMP WITH TIME ZONE NOT NULL, - added_on_absn INTEGER NOT NULL, - --^ Atala Block Sequence Number (absn) of the operation that added the service - added_on_osn INTEGER NOT NULL, - --^ Operation Sequence Number (osn) of the operation that added the service - - revoked_on_transaction_id TRANSACTION_ID NULL, - revoked_on TIMESTAMP WITH TIME ZONE NULL, - revoked_on_absn INTEGER NULL, - revoked_on_osn INTEGER NULL, - - ledger VARCHAR(32) NOT NULL, - - CONSTRAINT services_did_suffix_fk - FOREIGN KEY (did_suffix) REFERENCES did_data (did_suffix) - -); - -CREATE UNIQUE INDEX unique_did_suffix_and_id_on_non_revoked - ON services (did_suffix, id) WHERE (revoked_on is NULL); - - -CREATE TABLE service_endpoints -( - service_endpoint_id ID_TYPE PRIMARY KEY NOT NULL, - url_index INTEGER NOT NULL, - service_id ID_TYPE NOT NULL, - url TEXT NOT NULL, - - CONSTRAINT service_endpoints_service_id_fk - FOREIGN KEY (service_id) REFERENCES services (service_id) - -); diff --git a/node/src/main/resources/db/migration/V33__alter_type_key_usage.sql b/node/src/main/resources/db/migration/V33__alter_type_key_usage.sql deleted file mode 100644 index 899e79005c..0000000000 --- a/node/src/main/resources/db/migration/V33__alter_type_key_usage.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TYPE key_usage RENAME VALUE 'COMMUNICATION_KEY' to 'KEY_AGREEMENT_KEY'; - -ALTER TYPE key_usage ADD VALUE 'CAPABILITY_INVOCATION_KEY'; -ALTER TYPE key_usage ADD VALUE 'CAPABILITY_DELEGATION_KEY'; diff --git a/node/src/main/resources/db/migration/V34__drop_service_endpoints_and_add_it_to_services.sql b/node/src/main/resources/db/migration/V34__drop_service_endpoints_and_add_it_to_services.sql deleted file mode 100644 index 1f35108396..0000000000 --- a/node/src/main/resources/db/migration/V34__drop_service_endpoints_and_add_it_to_services.sql +++ /dev/null @@ -1,10 +0,0 @@ - --- This migration assumes that tables services and services_endpoints are empty -DROP TABLE service_endpoints; - -ALTER TABLE services - ADD COLUMN service_endpoints TEXT NOT NULL default ''; - -ALTER TABLE services - ALTER COLUMN service_endpoints DROP DEFAULT; - diff --git a/node/src/main/resources/db/migration/V35__add_contexts_table.sql b/node/src/main/resources/db/migration/V35__add_contexts_table.sql deleted file mode 100644 index cdaca0681e..0000000000 --- a/node/src/main/resources/db/migration/V35__add_contexts_table.sql +++ /dev/null @@ -1,20 +0,0 @@ -CREATE TABLE contexts -( - context_id ID_TYPE PRIMARY KEY NOT NULL, - did_suffix ID_TYPE NOT NULL, - context TEXT NOT NULL, - added_on_transaction_id TRANSACTION_ID NOT NULL, - added_on TIMESTAMP WITH TIME ZONE NOT NULL, - added_on_absn INTEGER NOT NULL, - --^ Atala Block Sequence Number (absn) of the operation that added the context string - added_on_osn INTEGER NOT NULL, - --^ Operation Sequence Number (osn) of the operation that added the context string - - revoked_on_transaction_id TRANSACTION_ID NULL, - revoked_on TIMESTAMP WITH TIME ZONE NULL, - revoked_on_absn INTEGER NULL, - revoked_on_osn INTEGER NULL -); - -CREATE UNIQUE INDEX unique_did_suffix_and_context_string_on_non_revoked - ON contexts (did_suffix, context) WHERE (revoked_on is NULL); \ No newline at end of file diff --git a/node/src/main/resources/db/migration/V3__did_tables.sql b/node/src/main/resources/db/migration/V3__did_tables.sql deleted file mode 100644 index 9309f97126..0000000000 --- a/node/src/main/resources/db/migration/V3__did_tables.sql +++ /dev/null @@ -1,39 +0,0 @@ -CREATE TYPE KEY_USAGE AS ENUM('MASTER_KEY', 'ISSUING_KEY' ,'COMMUNICATION_KEY', 'AUTHENTICATION_KEY'); - -CREATE DOMAIN ID_TYPE AS TEXT CHECK( - VALUE ~ '^[0-9a-f]{64}$' -); - -CREATE DOMAIN OPERATION_HASH AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE did_data( - did_suffix ID_TYPE NOT NULL, - last_operation OPERATION_HASH NOT NULL, - CONSTRAINT did_data_pk PRIMARY KEY (did_suffix) -); - -CREATE TABLE public_keys( - did_suffix ID_TYPE NOT NULL, - key_id TEXT NOT NULL, - key_usage KEY_USAGE NOT NULL, - curve TEXT NOT NULL, - x BYTEA NOT NULL, - y BYTEA NOT NULL, - added_on TIMESTAMPTZ NOT NULL, - added_on_absn INTEGER NOT NULL, - --^ Atala Block Sequence Number (absn) of the operation that added the key - added_on_osn INTEGER NOT NULL, - --^ Operation Sequence Number (osn) of the operation that added the key - - revoked_on TIMESTAMPTZ NULL DEFAULT NULL, - revoked_on_absn INTEGER NULL DEFAULT NULL, - --^ Atala Block Sequence Number (absn) of the operation that revoked the key - revoked_on_osn INTEGER NULL DEFAULT NULL, - --^ Operation Sequence Number (osn) of the operation that revoked the key - - CONSTRAINT public_keys_pk PRIMARY KEY (did_suffix, key_id) - -- add constraints about congruent addition of sequence_numbers -); diff --git a/node/src/main/resources/db/migration/V4__credentials_table.sql b/node/src/main/resources/db/migration/V4__credentials_table.sql deleted file mode 100644 index f877b59908..0000000000 --- a/node/src/main/resources/db/migration/V4__credentials_table.sql +++ /dev/null @@ -1,27 +0,0 @@ -CREATE DOMAIN CONTENT_HASH AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE credentials( - credential_id ID_TYPE NOT NULL, - last_operation OPERATION_HASH NOT NULL, - issuer ID_TYPE NOT NULL, - content_hash CONTENT_HASH NOT NULL, - issued_on TIMESTAMPTZ NOT NULL, - issued_on_absn INTEGER NOT NULL, - --^ Atala Block Sequence Number (absn) of the operation that issued the credential - issued_on_osn INTEGER NOT NULL, - --^ Operation Sequence Number (osn) of the operation that issued the credential - revoked_on TIMESTAMPTZ NULL DEFAULT NULL, - revoked_on_absn INTEGER NULL DEFAULT NULL, - --^ Atala Block Sequence Number (absn) of the operation that revoked the credential - revoked_on_osn INTEGER NULL DEFAULT NULL, - --^ Operation Sequence Number (osn) of the operation that revoked the credential - - CONSTRAINT credentials_pk PRIMARY KEY (credential_id), - CONSTRAINT credentials_issuer_fk FOREIGN KEY (issuer) REFERENCES did_data (did_suffix) - -- Add constraint so that revoked_on and revoke_on_sequence_number match in terms on not being null -); - -CREATE INDEX credentials_issuer_index ON credentials USING BTREE (issuer); diff --git a/node/src/main/resources/db/migration/V5__key_values_table.sql b/node/src/main/resources/db/migration/V5__key_values_table.sql deleted file mode 100644 index 24d725f06c..0000000000 --- a/node/src/main/resources/db/migration/V5__key_values_table.sql +++ /dev/null @@ -1,5 +0,0 @@ --- General purpose key-value pairs -CREATE TABLE key_values( - key VARCHAR(64) PRIMARY KEY, - value TEXT -); diff --git a/node/src/main/resources/db/migration/V6__atala_objects_add_tx_info.sql b/node/src/main/resources/db/migration/V6__atala_objects_add_tx_info.sql deleted file mode 100644 index 87ca33d29e..0000000000 --- a/node/src/main/resources/db/migration/V6__atala_objects_add_tx_info.sql +++ /dev/null @@ -1,19 +0,0 @@ -CREATE DOMAIN TRANSACTION_ID AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - --- Add optional columns to the table -ALTER TABLE atala_objects - ADD COLUMN transaction_id TRANSACTION_ID NULL, - ADD COLUMN ledger VARCHAR(32) NULL; - --- Back-fill new columns for the existing rows -UPDATE atala_objects - SET transaction_id = atala_object_id, - ledger = 'InMemory'; - --- Make new columns no longer optional -ALTER TABLE atala_objects - ALTER COLUMN transaction_id SET NOT NULL, - ALTER COLUMN ledger SET NOT NULL; diff --git a/node/src/main/resources/db/migration/V7__atala_objects_drop_sequence_number_unique.sql b/node/src/main/resources/db/migration/V7__atala_objects_drop_sequence_number_unique.sql deleted file mode 100644 index 72cb638fea..0000000000 --- a/node/src/main/resources/db/migration/V7__atala_objects_drop_sequence_number_unique.sql +++ /dev/null @@ -1,7 +0,0 @@ --- atala_objects.sequence_number is not constrained anymore -ALTER TABLE atala_objects - DROP CONSTRAINT atala_objects_sequence_number_unique, - DROP CONSTRAINT atala_objects_sequence_number_positive; - --- It also does not need to be queried directly anymore -DROP INDEX atala_objects_sequence_number_index; diff --git a/node/src/main/resources/db/migration/V8__atala_object_tx.sql b/node/src/main/resources/db/migration/V8__atala_object_tx.sql deleted file mode 100644 index 1a08031c8f..0000000000 --- a/node/src/main/resources/db/migration/V8__atala_object_tx.sql +++ /dev/null @@ -1,31 +0,0 @@ --- Create table to hold atala_objects' transaction info -CREATE TABLE atala_object_txs ( - atala_object_id ATALA_OBJECT_ID NOT NULL, - ledger VARCHAR(32) NOT NULL, - block_number INT NOT NULL, - block_timestamp TIMESTAMPTZ NOT NULL, - block_index INTEGER NOT NULL, - transaction_id TRANSACTION_ID NOT NULL, - - CONSTRAINT atala_object_txs_pk PRIMARY KEY (atala_object_id), - CONSTRAINT atala_object_txs_atala_object_id_fk - FOREIGN KEY (atala_object_id) - REFERENCES atala_objects (atala_object_id) -); - --- Migrate existing data (set a hard-coded block_number of 1) -INSERT INTO atala_object_txs - SELECT atala_object_id, - ledger, - 1 as block_number, - object_timestamp AS block_timestamp, - sequence_number AS block_index, - transaction_id - FROM atala_objects; - --- Drop old columns -ALTER TABLE atala_objects - DROP COLUMN sequence_number, - DROP COLUMN object_timestamp, - DROP COLUMN transaction_id, - DROP COLUMN ledger; diff --git a/node/src/main/resources/db/migration/V9__credential_batches_table.sql b/node/src/main/resources/db/migration/V9__credential_batches_table.sql deleted file mode 100644 index b24fb905ea..0000000000 --- a/node/src/main/resources/db/migration/V9__credential_batches_table.sql +++ /dev/null @@ -1,31 +0,0 @@ -CREATE DOMAIN MERKLE_ROOT AS BYTEA -CHECK ( - LENGTH(VALUE) = 32 -); - -CREATE TABLE credential_batches( - batch_id ID_TYPE NOT NULL, - last_operation OPERATION_HASH NOT NULL, - issuer_did_suffix ID_TYPE NOT NULL, - merkle_root MERKLE_ROOT NOT NULL, - issued_on TIMESTAMPTZ NOT NULL, - -- Atala Block Sequence Number (absn) of the operation that issued the batch - issued_on_absn INTEGER NOT NULL, - -- Operation Sequence Number (osn) of the operation that issued the batch - issued_on_osn INTEGER NOT NULL, - revoked_on TIMESTAMPTZ NULL DEFAULT NULL, - -- Atala Block Sequence Number (absn) of the operation that revoked the batch - revoked_on_absn INTEGER NULL DEFAULT NULL, - -- Operation Sequence Number (osn) of the operation that revoked the batch - revoked_on_osn INTEGER NULL DEFAULT NULL, - - CONSTRAINT credential_batches_pk PRIMARY KEY (batch_id), - CONSTRAINT credential_batches_issuer_did_suffix_fk FOREIGN KEY (issuer_did_suffix) REFERENCES did_data (did_suffix), - CONSTRAINT revoke_on_check CHECK ( - (revoked_on IS NULL AND revoked_on_absn IS NULL AND revoked_on_osn IS NULL) - OR - (revoked_on IS NOT NULL AND revoked_on_absn IS NOT NULL AND revoked_on_osn IS NOT NULL) - ) -); - -CREATE INDEX credential_batches_issuer_did_suffix_index ON credential_batches USING BTREE (issuer_did_suffix); diff --git a/node/src/main/scala/db/migration/.gitkeep b/node/src/main/scala/db/migration/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/node/src/main/scala/db/migration/V19__public_keys.scala b/node/src/main/scala/db/migration/V19__public_keys.scala deleted file mode 100644 index a05652ef11..0000000000 --- a/node/src/main/scala/db/migration/V19__public_keys.scala +++ /dev/null @@ -1,56 +0,0 @@ -package db.migration - -import io.iohk.atala.prism.crypto.EC.{INSTANCE => EC} -import org.flywaydb.core.api.migration.{BaseJavaMigration, Context} - -import java.sql.ResultSet -import scala.util.{Failure, Success, Try, Using} - -class V19__public_keys extends BaseJavaMigration { - - override def migrate(context: Context): Unit = { - Try { - val rows = context.getConnection.createStatement - .executeQuery( - "SELECT did_suffix, key_id, x, y FROM public_keys WHERE xCompressed is NULL" - ) - if (rows.next()) - loop(rows, context) - } match { - case Failure(exception) => - exception.printStackTrace() - throw new Exception("V19__public_keys migration failed") - case Success(_) => println("V19__public_keys migration succeed") - } - } - - def loop(row: ResultSet, context: Context): Unit = { - - val did_suffix = row.getString("did_suffix") - val key_id = row.getString("key_id") - - val x = row.getBytes("x") - val y = row.getBytes("y") - - val compressedX: Array[Byte] = - EC.toPublicKeyFromByteCoordinates(x, y).getEncodedCompressed - - Using( - context.getConnection - .prepareStatement( - "UPDATE public_keys SET xCompressed = ? WHERE did_suffix = ? AND key_id = ?" - ) - ) { update => - update.setBytes(1, compressedX) - update.setString(2, did_suffix) - update.setObject(3, key_id) - update.execute() - } - - if (row.next()) - loop(row, context) - else () - - } - -} diff --git a/node/src/test/scala/io/iohk/atala/prism/node/migrations/.gitkeep b/node/src/test/scala/io/iohk/atala/prism/node/migrations/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/node/src/test/scala/io/iohk/atala/prism/node/migrations/V19MigrationSpec.scala b/node/src/test/scala/io/iohk/atala/prism/node/migrations/V19MigrationSpec.scala deleted file mode 100644 index 14d2180e0f..0000000000 --- a/node/src/test/scala/io/iohk/atala/prism/node/migrations/V19MigrationSpec.scala +++ /dev/null @@ -1,82 +0,0 @@ -package io.iohk.atala.prism.node.migrations - -import doobie.implicits._ -import io.iohk.atala.prism.crypto.EC.{INSTANCE => EC} -import io.iohk.atala.prism.crypto.ECConfig.{INSTANCE => ECConfig} -import io.iohk.atala.prism.daos.BaseDAO -import io.iohk.atala.prism.models.{DidSuffix, Ledger, TransactionId} -import io.iohk.atala.prism.node.models.nodeState.LedgerData -import io.iohk.atala.prism.node.models.{DIDPublicKey, KeyUsage} -import io.iohk.atala.prism.repositories.PostgresMigrationSpec -import io.iohk.atala.prism.node.repositories.daos._ -import io.iohk.atala.prism.repositories.ops.SqlTestOps.Implicits -import doobie.implicits.legacy.instant._ -import io.iohk.atala.prism.crypto.Sha256 -import io.iohk.atala.prism.protos.models.TimestampInfo - -import java.time.Instant - -class V19MigrationSpec extends PostgresMigrationSpec("db.migration.V19") with BaseDAO { - - private val dummyTimestampInfo = - new TimestampInfo(Instant.ofEpochMilli(0).toEpochMilli, 1, 0) - private val dummyLedgerData = LedgerData( - TransactionId - .from(Array.fill[Byte](TransactionId.config.size.toBytes.toInt)(0)) - .get, - Ledger.InMemory, - dummyTimestampInfo - ) - val didDigest = Sha256.compute("test".getBytes()) - val didSuffix = DidSuffix(didDigest.getHexValue) - val didPublicKey: DIDPublicKey = - DIDPublicKey( - didSuffix, - "master", - KeyUsage.MasterKey, - EC.generateKeyPair().getPublicKey - ) - - private def insertPublicKey(key: DIDPublicKey, ledgerData: LedgerData) = { - val curveName = ECConfig.getCURVE_NAME - val point = key.key.getCurvePoint - - val xBytes = point.getX.bytes() - val yBytes = point.getY.bytes() - - val addedOn = ledgerData.timestampInfo - sql""" - |INSERT INTO public_keys (did_suffix, key_id, key_usage, curve, x, y, - | added_on, added_on_absn, added_on_osn, - | added_on_transaction_id, ledger) - |VALUES (${key.didSuffix}, ${key.keyId}, ${key.keyUsage}, $curveName, $xBytes, $yBytes, - | ${Instant - .ofEpochMilli( - addedOn.getAtalaBlockTimestamp - )}, ${addedOn.getAtalaBlockSequenceNumber}, ${addedOn.getOperationSequenceNumber}, - | ${ledgerData.transactionId}, ${ledgerData.ledger}) - """.stripMargin.runUpdate() - } - - private def selectPublicKeyCompressed(key: DIDPublicKey) = { - sql"SELECT xCompressed FROM public_keys WHERE did_suffix = ${key.didSuffix} AND key_id = ${key.keyId}" - .runUnique[Array[Byte]]() - } - - test( - beforeApply = { - insertPublicKey(didPublicKey, dummyLedgerData) - }, - afterApplied = { - val inDB = selectPublicKeyCompressed(didPublicKey) - val expected = EC - .toPublicKeyFromByteCoordinates( - didPublicKey.key.getCurvePoint.getX.bytes(), - didPublicKey.key.getCurvePoint.getY.bytes() - ) - .getEncodedCompressed - inDB mustBe expected - inDB.length mustBe 33 - } - ) -} diff --git a/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V6MigrationSpec.scala b/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V6MigrationSpec.scala deleted file mode 100644 index 5559dfc11c..0000000000 --- a/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V6MigrationSpec.scala +++ /dev/null @@ -1,45 +0,0 @@ -package io.iohk.atala.prism.node.repositories.migrations - -import java.time.Instant -import doobie.implicits._ -import doobie.implicits.legacy.instant._ -import io.iohk.atala.prism.crypto.Sha256 -import io.iohk.atala.prism.repositories.PostgresMigrationSpec -import io.iohk.atala.prism.repositories.ops.SqlTestOps.Implicits - -class V6MigrationSpec extends PostgresMigrationSpec("V6") { - private val objectId = Sha256.compute("objectId".getBytes).getValue - private val sequenceNumber = 1337 - private val objectTimestamp = Instant.now() - - private case class TestAtalaObject( - atalaObjectId: Array[Byte], - sequenceNumber: Int, - objectTimestamp: Instant, - transactionId: Array[Byte], - ledger: String - ) - - test( - beforeApply = { - sql""" - |INSERT INTO atala_objects (atala_object_id, sequence_number, object_timestamp) - |VALUES($objectId, $sequenceNumber, $objectTimestamp)""".stripMargin - .runUpdate() - }, - afterApplied = { - val data = sql""" - |SELECT atala_object_id, sequence_number, object_timestamp, transaction_id, ledger - |FROM atala_objects""".stripMargin - .runUnique[TestAtalaObject]() - - // Verify old data is the same - data.atalaObjectId mustBe objectId - data.sequenceNumber mustBe sequenceNumber - data.objectTimestamp mustBe objectTimestamp - // Verify new data was properly set - data.transactionId mustBe objectId - data.ledger mustBe "InMemory" - } - ) -} diff --git a/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V8MigrationSpec.scala b/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V8MigrationSpec.scala deleted file mode 100644 index 02abdb10b2..0000000000 --- a/node/src/test/scala/io/iohk/atala/prism/node/repositories/migrations/V8MigrationSpec.scala +++ /dev/null @@ -1,62 +0,0 @@ -package io.iohk.atala.prism.node.repositories.migrations - -import java.time.Instant -import doobie.implicits._ -import doobie.implicits.legacy.instant._ -import io.iohk.atala.prism.crypto.Sha256 -import io.iohk.atala.prism.repositories.PostgresMigrationSpec -import io.iohk.atala.prism.repositories.ops.SqlTestOps.Implicits - -class V8MigrationSpec extends PostgresMigrationSpec("V8") { - private val objectId = Sha256.compute("objectId".getBytes).getValue - private val objectContent = "objectContent".getBytes - private val sequenceNumber = 1337 - private val objectTimestamp = Instant.now() - private val transactionId = Sha256.compute("transactionId".getBytes).getValue - private val ledger = "SomeLedger" - - private case class TestAtalaObject( - atalaObjectId: Array[Byte], - objectContent: Array[Byte] - ) - - private case class TestAtalaObjectTx( - atalaObjectId: Array[Byte], - ledger: String, - blockNumber: Int, - blockTimestamp: Instant, - blockIndex: Int, - transactionId: Array[Byte] - ) - - test( - beforeApply = { - sql""" - |INSERT INTO atala_objects - | (atala_object_id, object_content, sequence_number, object_timestamp, transaction_id, ledger) - |VALUES ($objectId, $objectContent, $sequenceNumber, $objectTimestamp, $transactionId, $ledger) - """.stripMargin.runUpdate() - }, - afterApplied = { - val atalaObject = sql""" - |SELECT atala_object_id, object_content - |FROM atala_objects - """.stripMargin.runUnique[TestAtalaObject]() - val atalaObjectTx = sql""" - |SELECT atala_object_id, ledger, block_number, block_timestamp, block_index, transaction_id - |FROM atala_object_txs - """.stripMargin.runUnique[TestAtalaObjectTx]() - - // Verify old data is the same - atalaObject.atalaObjectId mustBe objectId - atalaObject.objectContent mustBe objectContent - // Verify new data was properly set - atalaObjectTx.atalaObjectId mustBe objectId - atalaObjectTx.ledger mustBe ledger - atalaObjectTx.blockNumber mustBe 1 - atalaObjectTx.blockTimestamp mustBe objectTimestamp - atalaObjectTx.blockIndex mustBe sequenceNumber - atalaObjectTx.transactionId mustBe transactionId - } - ) -} From 25d1faee13e4ab6fa8eb3c5a639c3a2173f7a790 Mon Sep 17 00:00:00 2001 From: shotexa Date: Sat, 13 Apr 2024 01:46:25 +0400 Subject: [PATCH 2/4] refactor(node): remove legacy BE files (#832) * Start cleaning up docs Signed-off-by: Shota Jolbordi * Remove more files Signed-off-by: Shota Jolbordi * Fix compilation issue Signed-off-by: Shota Jolbordi * Trim docs Signed-off-by: Shota Jolbordi * Fix compilation errors Signed-off-by: Shota Jolbordi * Remove some bitcoin test resources and old docs Signed-off-by: Shota Jolbordi * Lint Signed-off-by: Shota Jolbordi * Fix tests Signed-off-by: Shota Jolbordi --------- Signed-off-by: Shota Jolbordi --- build.sbt | 141 ++-- .../src/main/protobuf/endorsements_api.proto | 65 -- .../auth/AuthAndMiddlewareSupportF.scala | 231 ------ .../prism/auth/errors/AuthErrorSupport.scala | 11 - .../atala/prism/auth/errors/package.scala | 68 -- .../auth/grpc/AuthorizationInterceptor.scala | 47 -- .../grpc/ClientTraceReadInterceptor.scala | 32 - .../atala/prism/config/ConnectorConfig.scala | 20 - .../atala/prism/errors/ErrorSupport.scala | 113 --- .../atala/prism/errors/LoggingContext.scala | 13 - .../atala/prism/grpc/ProtoConverter.scala | 18 - .../interop/CredentialContentConverter.scala | 22 - .../interop/KotlinFunctionConverters.scala | 15 - .../atala/prism/models/ConnectionToken.scala | 3 - .../iohk/atala/prism/utils/StringUtils.scala | 26 - .../io/iohk/atala/prism/utils/UriUtils.scala | 135 --- .../V1__create_connector_message_offset.sql | 6 - .../common/db/migration/V2__create_config.sql | 5 - .../migration/V3__create_processing_tasks.sql | 9 - .../V4__processing_tasks_owner_to_string.sql | 2 - .../grpc/AuthorizationInterceptorSpec.scala | 91 -- .../atala/prism/utils/StringUtilsSpec.scala | 36 - docs/README.md | 78 -- docs/bitcoin/README.md | 109 --- docs/bitcoin/bitcoind.md | 317 ------- docs/bitcoin/diagrams/architecture.png | Bin 66863 -> 0 bytes docs/bitcoin/diagrams/architecture.puml | 70 -- docs/bitcoin/diagrams/issue-credential.png | Bin 33326 -> 0 bytes docs/bitcoin/diagrams/issue-credential.puml | 22 - docs/bitcoin/diagrams/onboarding.png | Bin 48747 -> 0 bytes docs/bitcoin/diagrams/onboarding.puml | 26 - docs/bitcoin/diagrams/student-recovery.png | Bin 44747 -> 0 bytes docs/bitcoin/diagrams/student-recovery.puml | 24 - .../diagrams/student-wallet-preparation.png | Bin 15917 -> 0 bytes .../diagrams/student-wallet-preparation.puml | 11 - .../university-wallet-preparation.png | Bin 64529 -> 0 bytes .../university-wallet-preparation.puml | 29 - docs/bitcoin/diagrams/verify-credential.png | Bin 65125 -> 0 bytes docs/bitcoin/diagrams/verify-credential.puml | 39 - docs/cardano/README.md | 13 +- docs/cardano/cardano-in-atala-prism.md | 127 +-- docs/cardano/cardano-rollback.md | 74 -- docs/cardano/docker/.gitignore | 2 - docs/cardano/docker/docker-compose.yml | 107 --- docs/cardano/docker/secrets/postgres_db | 1 - docs/cardano/docker/secrets/postgres_password | 1 - docs/cardano/docker/secrets/postgres_user | 1 - docs/cardano/integration.md | 67 -- docs/cardano/metadata-schema-fee.md | 126 --- docs/cardano/metadata-schema.md | 59 -- docs/cardano/run-cardano.md | 234 ------ docs/cardano/scripts/fee_estimation.py | 120 --- docs/cardano/use-cardano.md | 54 -- docs/cli-settings.md | 61 -- docs/connector/README.md | 174 ---- docs/connector/e2e-encryption.md | 194 ----- docs/data-vault/README.md | 87 -- .../MoE-controls-master-keys-proposal.md | 244 ------ docs/endorsements/endorsements.md | 503 ----------- docs/grpc/streaming.md | 110 --- docs/indy/README.md | 104 --- docs/indy/diagrams/architecture.png | Bin 48519 -> 0 bytes docs/indy/diagrams/architecture.puml | 50 -- docs/indy/diagrams/issue-credential.png | Bin 27170 -> 0 bytes docs/indy/diagrams/issue-credential.puml | 20 - docs/indy/diagrams/onboarding.png | Bin 51512 -> 0 bytes docs/indy/diagrams/onboarding.puml | 29 - .../diagrams/student-wallet-preparation.png | Bin 15685 -> 0 bytes .../diagrams/student-wallet-preparation.puml | 12 - .../university-wallet-preparation.png | Bin 45046 -> 0 bytes .../university-wallet-preparation.puml | 35 - docs/indy/diagrams/verify-credential.png | Bin 18464 -> 0 bytes docs/indy/diagrams/verify-credential.puml | 15 - docs/mirror/tasks-and-leases.md | 83 -- docs/misc/README.md | 14 - docs/misc/common/C4_header.puml | 13 - docs/misc/deloitte/supply-chain.png | Bin 131033 -> 0 bytes docs/misc/deloitte/supply-chain.puml | 51 -- docs/misc/wmc/prism_architecture.png | Bin 84635 -> 0 bytes docs/misc/wmc/prism_architecture.puml | 69 -- docs/moe/full-offline-mode.md | 324 -------- docs/moe/offline-mode.md | 59 -- docs/monitoring/logging/README.md | 5 +- docs/monitoring/metrics/README.md | 8 +- docs/new-diagrams/01-issuer-registration.png | Bin 29549 -> 0 bytes docs/new-diagrams/01-issuer-registration.puml | 20 - docs/new-diagrams/02-login.png | Bin 22302 -> 0 bytes docs/new-diagrams/02-login.puml | 17 - docs/new-diagrams/03-onboarding-persons.png | Bin 40048 -> 0 bytes docs/new-diagrams/03-onboarding-persons.puml | 31 - .../04-create-credential-group.png | Bin 33793 -> 0 bytes .../04-create-credential-group.puml | 22 - docs/new-diagrams/05-issue-credential.png | Bin 32238 -> 0 bytes docs/new-diagrams/05-issue-credential.puml | 22 - .../06-share-credential-with-holder.png | Bin 30766 -> 0 bytes .../06-share-credential-with-holder.puml | 22 - .../07-share-credential-to-verify.png | Bin 24560 -> 0 bytes .../07-share-credential-to-verify.puml | 20 - .../08-verify-credential-steps.png | Bin 45445 -> 0 bytes .../08-verify-credential-steps.puml | 32 - docs/new-diagrams/09-revoke-credential.png | Bin 33462 -> 0 bytes docs/new-diagrams/09-revoke-credential.puml | 23 - docs/new-diagrams/README.md | 40 - docs/new-diagrams/architecture.png | Bin 71912 -> 0 bytes docs/new-diagrams/architecture.puml | 70 -- docs/new-diagrams/new-group-flow.png | Bin 74063 -> 0 bytes docs/new-diagrams/new-group-flow.puml | 42 - docs/node/SubscriptionMechanism.md | 234 ------ .../operaions-lifecycle-in-node-service.md | 6 +- docs/node/operations-ordering-submission.md | 133 --- docs/node/rate-limiting.md | 79 -- docs/on-premise-deployments/README.md | 116 --- .../diagrams/monitoring-deployment.png | Bin 33483 -> 0 bytes .../diagrams/monitoring-deployment.puml | 32 - .../diagrams/nomad-deployment.png | Bin 75703 -> 0 bytes .../diagrams/nomad-deployment.puml | 53 -- .../diagrams/prism-deployment.png | Bin 129752 -> 0 bytes .../diagrams/prism-deployment.puml | 82 -- docs/payments/README.md | 90 -- .../payments/diagrams/manual-payment-flow.png | Bin 32459 -> 0 bytes .../diagrams/manual-payment-flow.puml | 27 - .../diagrams/payment-request-flow.png | Bin 40189 -> 0 bytes .../diagrams/payment-request-flow.puml | 32 - docs/protocol/.gitignore | 2 - docs/protocol/Dockerfile | 18 - docs/protocol/README.md | 3 - docs/protocol/biblio.bib | 0 docs/protocol/canonicalization.md | 351 -------- docs/protocol/intro.md | 26 - .../key-derivation-and-unpublished-dids.md | 99 --- .../protocol/key-derivation-test-vectors.json | 159 ---- docs/protocol/key-derivation.md | 445 ---------- docs/protocol/late-publish.md | 292 ------- docs/protocol/make.sh | 41 - docs/protocol/protocol-other-ideas.md | 106 --- docs/protocol/protocol-v0.1.md | 375 --------- docs/protocol/protocol-v0.2.md | 606 -------------- docs/protocol/protocol-v0.3.md | 784 ------------------ .../selective-disclosure-merkle-trees.md | 98 --- docs/protocol/subject-did-on-credentials.md | 58 -- docs/protocol/unpublished-dids.md | 181 ---- docs/protocol/updates.md | 76 -- docs/public-docs/.gitignore | 1 - docs/public-docs/Makefile | 6 - docs/public-docs/README.md | 21 - docs/public-docs/article.tex | 266 ------ docs/research/Makefile | 8 - docs/research/README.md | 21 - docs/research/article.bib | 55 -- docs/research/article.tex | 458 ---------- .../figures/connector-noninjective.png | Bin 55829 -> 0 bytes docs/research/figures/connector.png | Bin 55138 -> 0 bytes docs/research/formalizations/README.md | 9 - .../formalizations/connector-ets.spthy | 300 ------- .../formalizations/connector-flaw.spthy | 299 ------- .../formalizations/connector-sae.spthy | 299 ------- docs/research/formalizations/connector.spthy | 308 ------- docs/sdk/README.md | 64 -- docs/sdk/diagrams/verify-credential.puml | 67 -- docs/sdk/versioning-example.md | 41 - docs/sdk/versioning.md | 60 -- docs/signing.md | 39 - docs/wallet-backend/motivation.md | 26 - .../charts/node/templates/stringsecret.yaml | 0 node/src/main/resources/application.conf | 43 +- .../io/iohk/atala/prism/node/NodeApp.scala | 29 +- .../io/iohk/atala/prism/node/NodeConfig.scala | 2 +- .../node/NodeExplorerAuthenticator.scala | 4 +- .../node/NodeExplorerGrpcServiceImpl.scala | 18 +- .../prism/node/NodeGrpcServiceImpl.scala | 12 +- .../atala/prism/node/UnderlyingLedger.scala | 2 +- .../atala/prism/node}/auth/AuthHelper.scala | 6 +- .../prism/node}/auth/AuthenticatorF.scala | 8 +- .../prism/node}/auth/AuthenticatorFLogs.scala | 6 +- .../prism/node/auth/errors/package.scala | 36 + .../auth/grpc/GrpcAuthenticationContext.scala | 7 +- .../auth/grpc/GrpcAuthenticationHeader.scala | 4 +- .../grpc/GrpcAuthenticationHeaderParser.scala | 4 +- .../grpc/GrpcAuthenticatorInterceptor.scala | 2 +- .../auth/grpc/GrpcMetadataContextKeys.scala | 2 +- .../auth/grpc/TraceExposeInterceptor.scala | 2 +- .../auth/grpc/TraceReadInterceptor.scala | 2 +- .../prism/node}/auth/model/package.scala | 2 +- .../prism/node}/auth/utils/DIDUtils.scala | 10 +- .../node}/auth/utils/DidWhitelistLoader.scala | 2 +- .../prism/node/cardano/CardanoClient.scala | 6 +- .../cardano/dbsync/CardanoDbSyncClient.scala | 4 +- .../repositories/CardanoBlockRepository.scala | 4 +- .../dbsync/repositories/daos/package.scala | 4 +- .../CardanoBlockRepositoryMetrics.scala | 4 +- .../node/cardano/logs/CardanoClientLogs.scala | 2 +- .../cardano/models/AtalaObjectMetadata.scala | 2 +- .../prism/node/cardano/models/BlockHash.scala | 2 +- .../node/cardano/models/Transaction.scala | 2 +- .../prism/node/cardano/models/WalletId.scala | 2 +- .../wallet/CardanoWalletApiClient.scala | 4 +- .../node/cardano/wallet/api/ApiClient.scala | 2 +- .../node/cardano/wallet/api/ApiRequest.scala | 2 +- .../node/cardano/wallet/api/JsonCodecs.scala | 3 +- .../logs/CardanoWalletApiClientLogs.scala | 2 +- .../CardanoWalletApiClientMetrics.scala | 6 +- .../atala/prism/node}/config/NodeConfig.scala | 2 +- .../node}/db/DbNotificationStreamer.scala | 2 +- .../node}/db/TransactorForStreaming.scala | 2 +- .../atala/prism/node}/errors/PrismError.scala | 11 +- .../atala/prism/node/errors/package.scala | 2 +- .../atala/prism/node/grpc/ProtoCodecs.scala | 4 +- .../atala/prism/node}/interop/implicits.scala | 6 +- .../prism/node}/interop/toScalaProtos.scala | 3 +- .../logging/GeneralLoggableInstances.scala | 4 +- .../atala/prism/node}/logging/TraceId.scala | 2 +- .../prism/node/metrics/NodeReporter.scala | 4 +- .../node}/metrics/RequestMeasureUtil.scala | 2 +- .../prism/node}/metrics/TimeMeasureUtil.scala | 11 +- .../prism/node}/metrics/UptimeReporter.scala | 2 +- .../prism/node/models/AtalaObjectId.scala | 2 +- .../prism/node/models/AtalaObjectInfo.scala | 2 +- .../AtalaObjectTransactionSubmission.scala | 2 +- .../prism/node}/models/AtalaOperationId.scala | 4 +- .../atala/prism/node}/models/BlockInfo.scala | 6 +- .../atala/prism/node}/models/DidSuffix.scala | 4 +- .../atala/prism/node}/models/HashValue.scala | 7 +- .../atala/prism/node}/models/IdType.scala | 2 +- .../atala/prism/node}/models/Ledger.scala | 4 +- .../node}/models/TransactionDetails.scala | 2 +- .../prism/node}/models/TransactionId.scala | 2 +- .../prism/node}/models/TransactionInfo.scala | 4 +- .../node}/models/TransactionStatus.scala | 2 +- .../atala/prism/node}/models/UUIDValue.scala | 2 +- .../atala/prism/node/models/package.scala | 1 - .../prism/node}/nonce/ClientHelper.scala | 6 +- .../node}/nonce/RequestAuthenticator.scala | 6 +- .../node/operations/CreateDIDOperation.scala | 2 +- .../operations/DeactivateDIDOperation.scala | 2 +- .../IssueCredentialBatchOperation.scala | 2 +- .../prism/node/operations/ParsingUtils.scala | 4 +- .../ProtocolVersionUpdateOperation.scala | 2 +- .../RevokeCredentialsOperation.scala | 2 +- .../node/operations/UpdateDIDOperation.scala | 2 +- .../atala/prism/node/operations/package.scala | 2 +- .../AtalaObjectsTransactionsRepository.scala | 6 +- .../AtalaOperationsRepository.scala | 6 +- .../ConnectionIOErrorHandlers.scala | 2 +- .../CredentialBatchesRepository.scala | 4 +- .../node/repositories/DIDDataRepository.scala | 6 +- .../repositories/KeyValuesRepository.scala | 4 +- .../MetricsCountersRepository.scala | 4 +- .../ProtocolVersionRepository.scala | 4 +- .../RequestNoncesRepository.scala | 4 +- .../node}/repositories/SchemaMigrations.scala | 2 +- .../repositories/TransactorFactory.scala | 3 +- ...AtalaObjectTransactionSubmissionsDAO.scala | 4 +- .../repositories/daos/AtalaObjectsDAO.scala | 3 +- .../daos/AtalaOperationsDAO.scala | 2 +- .../node/repositories}/daos/BaseDAO.scala | 4 +- .../node/repositories/daos/ContextDAO.scala | 4 +- .../daos/CredentialBatchesDAO.scala | 8 +- .../node/repositories/daos/DIDDataDAO.scala | 4 +- .../daos/ProtocolVersionsDAO.scala | 2 +- .../repositories/daos/PublicKeysDAO.scala | 4 +- .../repositories/daos/RequestNoncesDAO.scala | 2 +- .../node/repositories/daos/ServicesDAO.scala | 5 +- .../node/repositories/daos/package.scala | 4 +- ...alaObjectsTransactionsRepositoryLogs.scala | 9 +- .../logs/AtalaOperationsRepositoryLogs.scala | 2 +- .../CredentialBatchesRepositoryLogs.scala | 2 +- .../logs/RequestNoncesRepositoryLogs.scala | 2 +- ...ObjectsTransactionsRepositoryMetrics.scala | 6 +- .../AtalaOperationsRepositoryMetrics.scala | 6 +- .../CredentialBatchesRepositoryMetrics.scala | 4 +- .../metrics/DIDDataRepositoryMetrics.scala | 4 +- .../metrics/KeyValuesRepositoryMetrics.scala | 4 +- .../MetricsCountersRepositoryMetrics.scala | 4 +- .../ProtocolVersionRepositoryMetrics.scala | 4 +- .../services/BlockProcessingService.scala | 2 +- .../node/services/CardanoLedgerService.scala | 2 +- .../node/services/InMemoryLedgerService.scala | 2 +- .../node/services/NodeExplorerService.scala | 2 +- .../prism/node/services/NodeService.scala | 2 +- .../services/ObjectManagementService.scala | 23 +- .../SubmissionSchedulingService.scala | 4 +- .../node/services/SubmissionService.scala | 2 +- .../logs/NodeExplorerServiceLogs.scala | 2 +- .../services/logs/NodeServiceLogging.scala | 2 +- .../logs/ObjectManagementServiceLogs.scala | 1 - .../services/logs/UnderlyingLedgerLogs.scala | 2 +- .../prism/node/services/models/package.scala | 2 +- .../atala/prism/node}/tracing/Tracing.scala | 6 +- .../iohk/atala/prism/node}/utils/Base64.scala | 3 +- .../atala/prism/node}/utils/BytesOps.scala | 2 +- .../prism/node}/utils/DoobieImplicits.scala | 2 +- .../prism/node}/utils/FutureEither.scala | 2 +- .../atala/prism/node}/utils/GrpcUtils.scala | 2 +- .../atala/prism/node}/utils/IOUtils.scala | 3 +- .../atala/prism/node/utils/UriUtils.scala | 42 + .../iohk/atala/prism/node}/utils/syntax.scala | 12 +- .../src/test/resources/application.conf | 9 +- ...ad466f1ec11582d95d7dba44fe069ca66c9f330464 | 24 - ...ad466f1ec11582d95d7dba44fe069ca66c9f330464 | 164 ---- .../db/testmigration/V2__create_config.sql | 5 + .../prism/node}/AtalaWithPostgresSpec.scala | 9 +- .../io/iohk/atala/prism/node}/DIDUtil.scala | 4 +- .../atala/prism/node/DataPreparation.scala | 5 +- .../prism/node/NodeExplorerServiceSpec.scala | 14 +- .../atala/prism/node/NodeServiceSpec.scala | 12 +- .../iohk/atala/prism/node}/RpcSpecBase.scala | 11 +- .../atala/prism/node}/TestConstants.scala | 4 +- .../prism/node}/auth/SignedRpcRequest.scala | 4 +- .../prism/node}/auth/utils/DIDUtilsSpec.scala | 4 +- .../auth/utils/DidWhitelistLoaderSpec.scala | 4 +- .../CardanoBlockRepositorySpec.scala | 2 +- .../testing/TestCardanoBlockRepository.scala | 4 +- .../wallet/CardanoWalletApiClientSpec.scala | 2 +- .../node}/db/DbNotificationStreamerSpec.scala | 6 +- .../node/models/AtalaObjectInfoSpec.scala | 2 +- .../atala/prism/node}/models/KeyData.scala | 2 +- .../prism/node}/nonce/ClientHelperSpec.scala | 6 +- .../nonce/RequestAuthenticatorSpecBase.scala | 2 +- .../operations/CreateDIDOperationSpec.scala | 3 +- .../DeactivateDIDOperationSpec.scala | 5 +- .../IssueCredentialBatchOperationSpec.scala | 3 +- .../operations/ProtoParsingTestHelpers.scala | 2 +- .../ProtocolVersionUpdateOperationSpec.scala | 9 +- .../RevokeCredentialsOperationSpec.scala | 4 +- .../operations/UpdateDIDOperationSpec.scala | 3 +- .../prism/node/poc/CredVerification.scala | 2 +- .../atala/prism/node/poc/EncodedSizes.scala | 2 +- .../node/poc/GenericCredentialsSDK.scala | 2 +- .../io/iohk/atala/prism/node/poc/Wallet.scala | 2 +- .../atala/prism/node/poc/batch/FlowPoC.scala | 11 +- .../endorsements/EndorsementsFlowPoC.scala | 402 --------- .../endorsements/EndorsementsService.scala | 247 ------ .../poc/estimations/CardanoFeeEstimator.scala | 17 +- ...alaObjectsTransactionsRepositorySpec.scala | 6 +- .../CredentialBatchesRepositorySpec.scala | 6 +- .../repositories/DIDDataRepositorySpec.scala | 5 +- .../repositories/DockerPostgresService.scala | 5 +- .../KeyValuesRepositorySpec.scala | 2 +- .../repositories/PostgresMigrationSpec.scala | 17 +- .../repositories/PostgresRepositorySpec.scala | 6 +- ...aObjectTransactionSubmissionsDAOSpec.scala | 7 +- .../daos/AtalaObjectsDAOSpec.scala | 4 +- .../daos/AtalaOperationsDAOSpec.scala | 4 +- .../repositories/daos/ContextDAOSpec.scala | 5 +- .../node/repositories}/daos/DbConfigDao.scala | 2 +- .../repositories}/daos/DbConfigDaoSpec.scala | 7 +- .../daos/MetricsCountersDAOSpec.scala | 3 +- .../daos/ProtocolVersionsDAOSpec.scala | 2 +- .../repositories/daos/PublicKeysDAOSpec.scala | 5 +- .../repositories/daos/ServicesDAOSpec.scala | 5 +- .../node}/repositories/ops/SqlTestOps.scala | 2 +- .../prism/node/repositories/package.scala | 2 +- .../services/BlockProcessingServiceSpec.scala | 5 +- .../CardanoLedgerServiceIntegrationSpec.scala | 8 +- .../services/CardanoLedgerServiceSpec.scala | 13 +- .../ObjectManagementServiceSpec.scala | 9 +- .../node/services/SubmissionServiceSpec.scala | 10 +- .../atala/prism/node}/utils/Base64Spec.scala | 2 +- .../prism/node}/utils/BytesOpsSpec.scala | 2 +- .../prism/node}/utils/GrpcUtilsSpec.scala | 2 +- .../prism/node}/utils/NodeClientUtils.scala | 2 +- .../atala/prism/node}/utils/UtilsSpec.scala | 4 +- 362 files changed, 585 insertions(+), 13624 deletions(-) delete mode 100644 common/src/main/protobuf/endorsements_api.proto delete mode 100644 common/src/main/scala/io/iohk/atala/prism/auth/AuthAndMiddlewareSupportF.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/auth/errors/AuthErrorSupport.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/auth/errors/package.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptor.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/auth/grpc/ClientTraceReadInterceptor.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/config/ConnectorConfig.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/errors/ErrorSupport.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/errors/LoggingContext.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/grpc/ProtoConverter.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/interop/CredentialContentConverter.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/interop/KotlinFunctionConverters.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/models/ConnectionToken.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/utils/StringUtils.scala delete mode 100644 common/src/main/scala/io/iohk/atala/prism/utils/UriUtils.scala delete mode 100644 common/src/test/resources/common/db/migration/V1__create_connector_message_offset.sql delete mode 100644 common/src/test/resources/common/db/migration/V2__create_config.sql delete mode 100644 common/src/test/resources/common/db/migration/V3__create_processing_tasks.sql delete mode 100644 common/src/test/resources/common/db/migration/V4__processing_tasks_owner_to_string.sql delete mode 100644 common/src/test/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptorSpec.scala delete mode 100644 common/src/test/scala/io/iohk/atala/prism/utils/StringUtilsSpec.scala delete mode 100644 docs/README.md delete mode 100644 docs/bitcoin/README.md delete mode 100644 docs/bitcoin/bitcoind.md delete mode 100644 docs/bitcoin/diagrams/architecture.png delete mode 100644 docs/bitcoin/diagrams/architecture.puml delete mode 100644 docs/bitcoin/diagrams/issue-credential.png delete mode 100644 docs/bitcoin/diagrams/issue-credential.puml delete mode 100644 docs/bitcoin/diagrams/onboarding.png delete mode 100644 docs/bitcoin/diagrams/onboarding.puml delete mode 100644 docs/bitcoin/diagrams/student-recovery.png delete mode 100644 docs/bitcoin/diagrams/student-recovery.puml delete mode 100644 docs/bitcoin/diagrams/student-wallet-preparation.png delete mode 100644 docs/bitcoin/diagrams/student-wallet-preparation.puml delete mode 100644 docs/bitcoin/diagrams/university-wallet-preparation.png delete mode 100644 docs/bitcoin/diagrams/university-wallet-preparation.puml delete mode 100644 docs/bitcoin/diagrams/verify-credential.png delete mode 100644 docs/bitcoin/diagrams/verify-credential.puml delete mode 100644 docs/cardano/cardano-rollback.md delete mode 100644 docs/cardano/docker/.gitignore delete mode 100644 docs/cardano/docker/docker-compose.yml delete mode 100644 docs/cardano/docker/secrets/postgres_db delete mode 100644 docs/cardano/docker/secrets/postgres_password delete mode 100644 docs/cardano/docker/secrets/postgres_user delete mode 100644 docs/cardano/integration.md delete mode 100644 docs/cardano/metadata-schema-fee.md delete mode 100644 docs/cardano/metadata-schema.md delete mode 100644 docs/cardano/run-cardano.md delete mode 100755 docs/cardano/scripts/fee_estimation.py delete mode 100644 docs/cardano/use-cardano.md delete mode 100644 docs/cli-settings.md delete mode 100644 docs/connector/README.md delete mode 100644 docs/connector/e2e-encryption.md delete mode 100644 docs/data-vault/README.md delete mode 100644 docs/endorsements/MoE-controls-master-keys-proposal.md delete mode 100644 docs/endorsements/endorsements.md delete mode 100644 docs/grpc/streaming.md delete mode 100644 docs/indy/README.md delete mode 100644 docs/indy/diagrams/architecture.png delete mode 100644 docs/indy/diagrams/architecture.puml delete mode 100644 docs/indy/diagrams/issue-credential.png delete mode 100644 docs/indy/diagrams/issue-credential.puml delete mode 100644 docs/indy/diagrams/onboarding.png delete mode 100644 docs/indy/diagrams/onboarding.puml delete mode 100644 docs/indy/diagrams/student-wallet-preparation.png delete mode 100644 docs/indy/diagrams/student-wallet-preparation.puml delete mode 100644 docs/indy/diagrams/university-wallet-preparation.png delete mode 100644 docs/indy/diagrams/university-wallet-preparation.puml delete mode 100644 docs/indy/diagrams/verify-credential.png delete mode 100644 docs/indy/diagrams/verify-credential.puml delete mode 100644 docs/mirror/tasks-and-leases.md delete mode 100644 docs/misc/README.md delete mode 100644 docs/misc/common/C4_header.puml delete mode 100644 docs/misc/deloitte/supply-chain.png delete mode 100644 docs/misc/deloitte/supply-chain.puml delete mode 100644 docs/misc/wmc/prism_architecture.png delete mode 100644 docs/misc/wmc/prism_architecture.puml delete mode 100644 docs/moe/full-offline-mode.md delete mode 100644 docs/moe/offline-mode.md delete mode 100644 docs/new-diagrams/01-issuer-registration.png delete mode 100644 docs/new-diagrams/01-issuer-registration.puml delete mode 100644 docs/new-diagrams/02-login.png delete mode 100644 docs/new-diagrams/02-login.puml delete mode 100644 docs/new-diagrams/03-onboarding-persons.png delete mode 100644 docs/new-diagrams/03-onboarding-persons.puml delete mode 100644 docs/new-diagrams/04-create-credential-group.png delete mode 100644 docs/new-diagrams/04-create-credential-group.puml delete mode 100644 docs/new-diagrams/05-issue-credential.png delete mode 100644 docs/new-diagrams/05-issue-credential.puml delete mode 100644 docs/new-diagrams/06-share-credential-with-holder.png delete mode 100644 docs/new-diagrams/06-share-credential-with-holder.puml delete mode 100644 docs/new-diagrams/07-share-credential-to-verify.png delete mode 100644 docs/new-diagrams/07-share-credential-to-verify.puml delete mode 100644 docs/new-diagrams/08-verify-credential-steps.png delete mode 100644 docs/new-diagrams/08-verify-credential-steps.puml delete mode 100644 docs/new-diagrams/09-revoke-credential.png delete mode 100644 docs/new-diagrams/09-revoke-credential.puml delete mode 100644 docs/new-diagrams/README.md delete mode 100644 docs/new-diagrams/architecture.png delete mode 100644 docs/new-diagrams/architecture.puml delete mode 100644 docs/new-diagrams/new-group-flow.png delete mode 100644 docs/new-diagrams/new-group-flow.puml delete mode 100644 docs/node/SubscriptionMechanism.md delete mode 100644 docs/node/operations-ordering-submission.md delete mode 100644 docs/node/rate-limiting.md delete mode 100644 docs/on-premise-deployments/README.md delete mode 100644 docs/on-premise-deployments/diagrams/monitoring-deployment.png delete mode 100644 docs/on-premise-deployments/diagrams/monitoring-deployment.puml delete mode 100644 docs/on-premise-deployments/diagrams/nomad-deployment.png delete mode 100644 docs/on-premise-deployments/diagrams/nomad-deployment.puml delete mode 100644 docs/on-premise-deployments/diagrams/prism-deployment.png delete mode 100644 docs/on-premise-deployments/diagrams/prism-deployment.puml delete mode 100644 docs/payments/README.md delete mode 100644 docs/payments/diagrams/manual-payment-flow.png delete mode 100644 docs/payments/diagrams/manual-payment-flow.puml delete mode 100644 docs/payments/diagrams/payment-request-flow.png delete mode 100644 docs/payments/diagrams/payment-request-flow.puml delete mode 100644 docs/protocol/.gitignore delete mode 100644 docs/protocol/Dockerfile delete mode 100644 docs/protocol/README.md delete mode 100644 docs/protocol/biblio.bib delete mode 100644 docs/protocol/canonicalization.md delete mode 100644 docs/protocol/intro.md delete mode 100644 docs/protocol/key-derivation-and-unpublished-dids.md delete mode 100644 docs/protocol/key-derivation-test-vectors.json delete mode 100644 docs/protocol/key-derivation.md delete mode 100644 docs/protocol/late-publish.md delete mode 100755 docs/protocol/make.sh delete mode 100644 docs/protocol/protocol-other-ideas.md delete mode 100644 docs/protocol/protocol-v0.1.md delete mode 100644 docs/protocol/protocol-v0.2.md delete mode 100644 docs/protocol/protocol-v0.3.md delete mode 100644 docs/protocol/selective-disclosure-merkle-trees.md delete mode 100644 docs/protocol/subject-did-on-credentials.md delete mode 100644 docs/protocol/unpublished-dids.md delete mode 100644 docs/protocol/updates.md delete mode 100644 docs/public-docs/.gitignore delete mode 100644 docs/public-docs/Makefile delete mode 100644 docs/public-docs/README.md delete mode 100644 docs/public-docs/article.tex delete mode 100644 docs/research/Makefile delete mode 100644 docs/research/README.md delete mode 100644 docs/research/article.bib delete mode 100644 docs/research/article.tex delete mode 100644 docs/research/figures/connector-noninjective.png delete mode 100644 docs/research/figures/connector.png delete mode 100644 docs/research/formalizations/README.md delete mode 100644 docs/research/formalizations/connector-ets.spthy delete mode 100644 docs/research/formalizations/connector-flaw.spthy delete mode 100644 docs/research/formalizations/connector-sae.spthy delete mode 100644 docs/research/formalizations/connector.spthy delete mode 100644 docs/sdk/README.md delete mode 100644 docs/sdk/diagrams/verify-credential.puml delete mode 100644 docs/sdk/versioning-example.md delete mode 100644 docs/sdk/versioning.md delete mode 100644 docs/signing.md delete mode 100644 docs/wallet-backend/motivation.md rename {prism-backend/node => node}/infrastructure/charts/node/templates/stringsecret.yaml (100%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/AuthHelper.scala (84%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/AuthenticatorF.scala (98%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/AuthenticatorFLogs.scala (94%) create mode 100644 node/src/main/scala/io/iohk/atala/prism/node/auth/errors/package.scala rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/GrpcAuthenticationContext.scala (97%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/GrpcAuthenticationHeader.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/GrpcAuthenticationHeaderParser.scala (88%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/GrpcAuthenticatorInterceptor.scala (93%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/GrpcMetadataContextKeys.scala (92%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/TraceExposeInterceptor.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/grpc/TraceReadInterceptor.scala (91%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/model/package.scala (91%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/utils/DIDUtils.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/auth/utils/DidWhitelistLoader.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/config/NodeConfig.scala (89%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/db/DbNotificationStreamer.scala (98%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/db/TransactorForStreaming.scala (85%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/errors/PrismError.scala (69%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/interop/implicits.scala (92%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/interop/toScalaProtos.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/logging/GeneralLoggableInstances.scala (96%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/logging/TraceId.scala (96%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/metrics/RequestMeasureUtil.scala (98%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/metrics/TimeMeasureUtil.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/metrics/UptimeReporter.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/AtalaOperationId.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/BlockInfo.scala (93%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/DidSuffix.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/HashValue.scala (92%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/IdType.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/Ledger.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/TransactionDetails.scala (79%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/TransactionId.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/TransactionInfo.scala (92%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/TransactionStatus.scala (92%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/models/UUIDValue.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/nonce/ClientHelper.scala (82%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/nonce/RequestAuthenticator.scala (83%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/repositories/ConnectionIOErrorHandlers.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/repositories/SchemaMigrations.scala (91%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/repositories/TransactorFactory.scala (98%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node/repositories}/daos/BaseDAO.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/tracing/Tracing.scala (61%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/Base64.scala (91%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/BytesOps.scala (94%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/DoobieImplicits.scala (95%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/FutureEither.scala (99%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/GrpcUtils.scala (98%) rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/IOUtils.scala (70%) create mode 100644 node/src/main/scala/io/iohk/atala/prism/node/utils/UriUtils.scala rename {common/src/main/scala/io/iohk/atala/prism => node/src/main/scala/io/iohk/atala/prism/node}/utils/syntax.scala (84%) rename {common => node}/src/test/resources/application.conf (62%) delete mode 100644 node/src/test/resources/bitcoin/blocks/2dc74e01317c32509dd530ad466f1ec11582d95d7dba44fe069ca66c9f330464 delete mode 100644 node/src/test/resources/bitcoin/full-blocks/2dc74e01317c32509dd530ad466f1ec11582d95d7dba44fe069ca66c9f330464 create mode 100644 node/src/test/resources/db/testmigration/V2__create_config.sql rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/AtalaWithPostgresSpec.scala (72%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/DIDUtil.scala (97%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/RpcSpecBase.scala (94%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/TestConstants.scala (66%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/auth/SignedRpcRequest.scala (93%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/auth/utils/DIDUtilsSpec.scala (96%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/auth/utils/DidWhitelistLoaderSpec.scala (84%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/db/DbNotificationStreamerSpec.scala (95%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/models/KeyData.scala (84%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/nonce/ClientHelperSpec.scala (90%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/nonce/RequestAuthenticatorSpecBase.scala (97%) delete mode 100644 node/src/test/scala/io/iohk/atala/prism/node/poc/endorsements/EndorsementsFlowPoC.scala delete mode 100644 node/src/test/scala/io/iohk/atala/prism/node/poc/endorsements/EndorsementsService.scala rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/repositories/DockerPostgresService.scala (98%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/repositories/PostgresMigrationSpec.scala (97%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/repositories/PostgresRepositorySpec.scala (96%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node/repositories}/daos/DbConfigDao.scala (94%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node/repositories}/daos/DbConfigDaoSpec.scala (89%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/repositories/ops/SqlTestOps.scala (94%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/utils/Base64Spec.scala (95%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/utils/BytesOpsSpec.scala (95%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/utils/GrpcUtilsSpec.scala (97%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/utils/NodeClientUtils.scala (97%) rename {common/src/test/scala/io/iohk/atala/prism => node/src/test/scala/io/iohk/atala/prism/node}/utils/UtilsSpec.scala (88%) diff --git a/build.sbt b/build.sbt index 872fd3c571..ea61acbfd5 100644 --- a/build.sbt +++ b/build.sbt @@ -50,7 +50,8 @@ lazy val versions = new { val typesafeConfig = "1.4.2" val fs2 = "3.2.5" val scalaUri = "4.0.0" - val prismSdk = "v1.4.1-snapshot-1688975371-7541fd2" // deployed to github packages from sdk branch "node-1.4-extension-sdk" + val prismSdk = + "v1.4.1-snapshot-1688975371-7541fd2" // deployed to github packages from sdk branch "node-1.4-extension-sdk" val vaultSdk = "0.1.0-build-2-96cc137d" } @@ -108,9 +109,9 @@ lazy val Dependencies = new { // We have to exclude bouncycastle since for some reason bitcoinj depends on bouncycastle jdk15to18 // (i.e. JDK 1.5 to 1.8), but we are using JDK 11 val prismCredentials = - "io.iohk.atala" % "prism-credentials-jvm" % versions.prismSdk excludeAll ExclusionRule( - organization = "org.bouncycastle" - ) + "io.iohk.atala" % "prism-credentials-jvm" % versions.prismSdk excludeAll ExclusionRule( + organization = "org.bouncycastle" + ) val prismProtos = "io.iohk.atala" % "prism-protos-jvm" % versions.prismSdk % "protobuf-src" intransitive () val vaultProtos = @@ -190,7 +191,7 @@ lazy val commonSettings = Seq( "-Ywarn-dead-code" ) ) - ), + ), scalacOptions += "-Ymacro-annotations", javacOptions ++= Seq("-source", "1.11", "-target", "1.11"), githubTokenSource := TokenSource.Environment("GITHUB_TOKEN"), @@ -243,43 +244,43 @@ lazy val commonSettings = Seq( } ) -lazy val common = project - .in(file("common")) - .settings( - commonSettings, - // Make ScalaPB compile protos relative to `protobuf_external_src/protos` directory. - // Otherwise, it will assume that `protobuf_external_src` is the root directory for proto files. - Compile / PB.protoSources := (Compile / PB.protoSources).value.map { - case externalSrc if externalSrc.toPath.endsWith("protobuf_external_src") => - externalSrc / "proto" - case other => other - }, - resolvers += Resolver.mavenLocal, - resolvers += Resolver.jcenterRepo, - resolvers += Resolver.mavenCentral, - libraryDependencies ++= - Dependencies.doobieDependencies ++ - Dependencies.dockerDependencies ++ - Dependencies.bouncyDependencies ++ - Dependencies.grpcDependencies ++ - Dependencies.mockitoDependencies ++ - Dependencies.kamonDependencies ++ - Dependencies.circeDependencies ++ - Dependencies.enumeratumDependencies ++ - Dependencies.tofuDependencies ++ - Seq( - Dependencies.diffx, - Dependencies.flyway, - Dependencies.typesafeConfig, - Dependencies.fs2, - Dependencies.scalaUri - ) ++ - Dependencies.prismDependencies ++ - Dependencies.scalapbDependencies, - Compile / PB.targets := Seq( - scalapb.gen() -> (Compile / sourceManaged).value / "proto" - ) - ) +//lazy val common = project +// .in(file("common")) +// .settings( +// commonSettings, +// // Make ScalaPB compile protos relative to `protobuf_external_src/protos` directory. +// // Otherwise, it will assume that `protobuf_external_src` is the root directory for proto files. +// Compile / PB.protoSources := (Compile / PB.protoSources).value.map { +// case externalSrc if externalSrc.toPath.endsWith("protobuf_external_src") => +// externalSrc / "proto" +// case other => other +// }, +// resolvers += Resolver.mavenLocal, +// resolvers += Resolver.jcenterRepo, +// resolvers += Resolver.mavenCentral, +// libraryDependencies ++= +// Dependencies.doobieDependencies ++ +// Dependencies.dockerDependencies ++ +// Dependencies.bouncyDependencies ++ +// Dependencies.grpcDependencies ++ +// Dependencies.mockitoDependencies ++ +// Dependencies.kamonDependencies ++ +// Dependencies.circeDependencies ++ +// Dependencies.enumeratumDependencies ++ +// Dependencies.tofuDependencies ++ +// Seq( +// Dependencies.diffx, +// Dependencies.flyway, +// Dependencies.typesafeConfig, +// Dependencies.fs2, +// Dependencies.scalaUri +// ) ++ +// Dependencies.prismDependencies ++ +// Dependencies.scalapbDependencies, +// Compile / PB.targets := Seq( +// scalapb.gen() -> (Compile / sourceManaged).value / "proto" +// ) +// ) lazy val node = project @@ -288,32 +289,58 @@ lazy val node = commonSettings, name := "node", Compile / mainClass := Some("io.iohk.atala.prism.node.NodeApp"), + // Make ScalaPB compile protos relative to `protobuf_external_src/protos` directory. + // Otherwise, it will assume that `protobuf_external_src` is the root directory for proto files. + Compile / PB.protoSources := (Compile / PB.protoSources).value.map { + case externalSrc if externalSrc.toPath.endsWith("protobuf_external_src") => + externalSrc / "proto" + case other => other + }, + Compile / PB.targets := Seq( + scalapb.gen() -> (Compile / sourceManaged).value / "proto" + ), + resolvers += Resolver.mavenLocal, + resolvers += Resolver.jcenterRepo, + resolvers += Resolver.mavenCentral, Docker / maintainer := "atala-coredid@iohk.io", Docker / dockerUsername := Some("input-output-hk"), Docker / dockerRepository := Some("ghcr.io"), Docker / packageName := "prism-node", dockerExposedPorts := Seq(5432), dockerBaseImage := "openjdk:11", - libraryDependencies ++= Dependencies.circeDependencies ++ Dependencies.enumeratumDependencies ++ Dependencies.doobieDependencies ++ - Dependencies.grpcDependencies ++ Dependencies.logbackDependencies ++ - Dependencies.sttpDependencies ++ - Dependencies.prismDependencies ++ - Dependencies.mockitoDependencies ++ - Seq( - Dependencies.chimney, - Dependencies.flyway, - Dependencies.postgresql, - Dependencies.scalapbRuntimeGrpc, - Dependencies.slf4j, - Dependencies.typesafeConfig - ) + libraryDependencies + ++= Dependencies.circeDependencies + ++ Dependencies.tofuDependencies + ++ Dependencies.kamonDependencies + ++ Dependencies.dockerDependencies + ++ Dependencies.bouncyDependencies + ++ Dependencies.enumeratumDependencies + ++ Dependencies.doobieDependencies + ++ Dependencies.grpcDependencies + ++ Dependencies.logbackDependencies + ++ Dependencies.sttpDependencies + ++ Dependencies.prismDependencies + ++ Dependencies.mockitoDependencies + ++ Dependencies.prismDependencies + ++ Dependencies.scalapbDependencies + ++ Seq( + Dependencies.chimney, + Dependencies.diffx, + Dependencies.flyway, + Dependencies.typesafeConfig, + Dependencies.postgresql, + Dependencies.scalapbRuntimeGrpc, + Dependencies.slf4j, + Dependencies.typesafeConfig, + Dependencies.fs2, + Dependencies.scalaUri + ) ) .enablePlugins(BuildInfoPlugin, JavaAppPackaging, DockerPlugin) - .dependsOn(common % "compile->compile;test->test") lazy val root = project .in(file(".")) - .aggregate(common, node) + .aggregate(node) Global / onChangedBuildSource := ReloadOnSourceChanges diff --git a/common/src/main/protobuf/endorsements_api.proto b/common/src/main/protobuf/endorsements_api.proto deleted file mode 100644 index 4f671dc160..0000000000 --- a/common/src/main/protobuf/endorsements_api.proto +++ /dev/null @@ -1,65 +0,0 @@ -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "io.iohk.atala.prism.protos"; - -package io.iohk.atala.prism.protos; - -import "google/protobuf/timestamp.proto"; - -import "node_models.proto"; - -service EndorsementsService { - // requests a fresh master key to be used, and associates its requester to the key - // - Only keys without an associated DID will be returned - // - No key will be returned twice - rpc getFreshMasterKey(GetFreshMasterKeyRequest) returns (GetFreshMasterKeyResponse) {} - - // requests to add en endorsement to a DID - rpc endorseInstitution(EndorseInstitutionRequest) returns (EndorseInstitutionResponse) {} - - // requests information about the endorsements associated to a DID - rpc getEndorsements(GetEndorsementsRequest) returns (GetEndorsementsResponse) {} - - // request to remove an existing endorsement - rpc revokeEndorsement(RevokeEndorsementRequest) returns (RevokeEndorsementResponse) {} -} - -message GetFreshMasterKeyRequest { - string endorserDID = 1; -} -message GetFreshMasterKeyResponse { - ECKeyData key = 1; // fresh key - bytes signature = 2; // the signature of the key generated with the MoE key - string signingKeyId = 3; // the key id of the MoE's key used to sign keys -} - -message EndorseInstitutionRequest { - string parentDID = 1; // DID of the endorser - string childDID = 2; // DID that will be endorsed - SignedAtalaOperation issueBatch = 3; // batch containing the endorsement credential - string credential = 4; // the actual endorsement credential - string encodedMerkleProof = 5; // the encoded merkle proof of the endorsement credential -} -message EndorseInstitutionResponse {} - -message GetEndorsementsRequest { - string did = 1; -} -message GetEndorsementsResponse { - repeated ValidityInterval intervals = 1; -} - -message ValidityInterval { - google.protobuf.Timestamp from = 1; - google.protobuf.Timestamp to = 2; - string credential = 3; - string encodedMerkleProof = 4; -} - -message RevokeEndorsementRequest { - string parentDID = 1; // the DID of the entity that performs the revocation - string childDID = 2; // the DID of the institution whose endorsement will be revoked - SignedAtalaOperation revokeBatch = 3; // the revoke operation that revokes the associated endorsement credential -} -message RevokeEndorsementResponse {} \ No newline at end of file diff --git a/common/src/main/scala/io/iohk/atala/prism/auth/AuthAndMiddlewareSupportF.scala b/common/src/main/scala/io/iohk/atala/prism/auth/AuthAndMiddlewareSupportF.scala deleted file mode 100644 index a3eddaecef..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/auth/AuthAndMiddlewareSupportF.scala +++ /dev/null @@ -1,231 +0,0 @@ -package io.iohk.atala.prism.auth - -import cats.effect.unsafe.IORuntime -import io.iohk.atala.prism.auth.grpc.GrpcAuthenticationHeader -import io.iohk.atala.prism.auth.grpc.GrpcAuthenticationHeaderParser.grpcHeader -import io.iohk.atala.prism.errors.{ErrorSupport, LoggingContext, PrismError} -import io.iohk.atala.prism.grpc.ProtoConverter -import io.iohk.atala.prism.logging.TraceId -import io.iohk.atala.prism.logging.TraceId.IOWithTraceIdContext -import io.iohk.atala.prism.metrics.RequestMeasureUtil.measureRequestFuture -import io.iohk.atala.prism.tracing.Tracing.trace -import io.iohk.atala.prism.utils.FutureEither -import io.iohk.atala.prism.utils.FutureEither.{FutureEitherFOps, FutureEitherOps} -import scalapb.GeneratedMessage -import shapeless.Coproduct -import shapeless.ops.coproduct.Unifier - -import scala.concurrent.{ExecutionContext, Future} -import scala.util.{Failure, Success, Try} - -trait AuthAndMiddlewareSupportF[Err <: PrismError, Id] { - self: ErrorSupport[Err] => - - import AuthAndMiddlewareSupport._ - - protected val authenticator: AuthenticatorF[Id, IOWithTraceIdContext] - protected val serviceName: String - protected val IOruntime: IORuntime - - final class AuthPartiallyApplied[Query <: Product] { - def apply[Proto <: GeneratedMessage, Result]( - methodName: String, - request: Proto - )(f: (Id, Query, TraceId) => FutureEither[Err, Result])(implicit - ec: ExecutionContext, - protoConverter: ProtoConverter[Proto, Query] - ): Future[Result] = trace { traceId => - grpcHeader { header => - { - for { - participantId <- authenticator - .authenticated(methodName, request, header) - .run(traceId) - .unsafeToFuture()(IOruntime) - .toFutureEither - res <- convertFromRequest[Proto, Result, Query](request, methodName, header).flatMap { query => - implicit val lc: LoggingContext = LoggingContext( - (0 until query.productArity) - .map(i => - query - .productElementName(i) -> query.productElement(i).toString - ) - .toMap + ("participantId" -> participantId.toString) - ) - measureRequestFuture(serviceName, methodName)( - f(participantId, query, traceId) - .wrapAndRegisterExceptions(serviceName, methodName) - .value - ) - }.toFutureEither - } yield res - }.flatten - } - } - } - - final class AuthCoproductPartiallyApplied[Query <: Product] { - def apply[C <: Coproduct, Proto <: GeneratedMessage, Result]( - methodName: String, - request: Proto - )(f: (Id, Query, TraceId) => FutureEither[C, Result])(implicit - ec: ExecutionContext, - protoConverter: ProtoConverter[Proto, Query], - unifier: Unifier.Aux[C, Err] - ): Future[Result] = trace { traceId => - grpcHeader { header => - { - for { - participantId <- authenticator - .authenticated(methodName, request, header) - .run(traceId) - .unsafeToFuture()(IOruntime) - .toFutureEither - result <- convertFromRequest[Proto, Result, Query](request, methodName, header).flatMap { query => - implicit val lc: LoggingContext = LoggingContext( - (0 until query.productArity) - .map(i => - query - .productElementName(i) -> query.productElement(i).toString - ) - .toMap + ("participantId" -> participantId.toString) - ) - measureRequestFuture(serviceName, methodName)( - f(participantId, query, traceId) - .mapLeft(_.unify) - .wrapAndRegisterExceptions(serviceName, methodName) - .value - ) - }.toFutureEither - } yield result - }.flatten - } - } - } - - final class WithoutAuthPartiallyApplied[Query <: Product] { - def apply[Proto <: GeneratedMessage, Result]( - methodName: String, - request: Proto - )(f: (Query, TraceId) => FutureEither[Err, Result])(implicit - ec: ExecutionContext, - protoConverter: ProtoConverter[Proto, Query] - ): Future[Result] = trace { traceId => - grpcHeader { header => - { - for { - _ <- authenticator.public(methodName, request).run(traceId).unsafeToFuture()(IOruntime).lift[Err] - result <- convertFromRequest[Proto, Result, Query](request, methodName, header).flatMap { query => - // Assemble LoggingContext out of the case class fields - implicit val lc: LoggingContext = LoggingContext( - (0 until query.productArity) - .map(i => - query - .productElementName(i) -> query.productElement(i).toString - ) - .toMap - ) - measureRequestFuture(serviceName, methodName)( - f(query, traceId) - .wrapAndRegisterExceptions(serviceName, methodName) - .value - ) - }.toFutureEither - } yield result - }.flatten - } - } - } - - final class WithoutAuthCoproductPartiallyApplied[Query <: Product] { - def apply[C <: Coproduct, Proto <: GeneratedMessage, Result]( - methodName: String, - request: Proto - )(f: (Query, TraceId) => FutureEither[C, Result])(implicit - ec: ExecutionContext, - protoConverter: ProtoConverter[Proto, Query], - unifier: Unifier.Aux[C, Err] - ): Future[Result] = trace { traceId => - grpcHeader { header => - { - for { - _ <- authenticator.public(methodName, request).run(traceId).unsafeToFuture()(IOruntime).lift[Err] - result <- convertFromRequest[Proto, Result, Query](request, methodName, header).flatMap { query => - // Assemble LoggingContext out of the case class fields - implicit val lc: LoggingContext = LoggingContext( - (0 until query.productArity) - .map(i => - query - .productElementName(i) -> query.productElement(i).toString - ) - .toMap - ) - measureRequestFuture(serviceName, methodName)( - f(query, traceId) - .mapLeft(_.unify) - .wrapAndRegisterExceptions(serviceName, methodName) - .value - ) - }.toFutureEither - } yield result - }.flatten - } - } - } - - // Just converts query from proto in our representation, on failure, responds with a thrown error - private def convertFromRequest[ - Proto <: GeneratedMessage, - Result, - Query <: Product - ]( - request: Proto, - methodName: String, - header: Option[GrpcAuthenticationHeader] - )(implicit - ec: ExecutionContext, - protoConverter: ProtoConverter[Proto, Query] - ): Future[Query] = { - protoConverter.fromProto(request, header) match { - case Failure(exception) => - val response = invalidRequest(exception.getMessage) - respondWith(request, response, serviceName, methodName) - case Success(query) => - Future.successful(query) - } - } - - // Query needs to be a Product (which all case class instances are) for easy access to its fields. - // Partial application helps with Scala type inference. You can specify just a single type - // parameter Query and all other type parameters can usually be inferred by Scala. - def auth[Query <: Product]: AuthPartiallyApplied[Query] = - new AuthPartiallyApplied[Query]() - - def authCo[Query <: Product]: AuthCoproductPartiallyApplied[Query] = - new AuthCoproductPartiallyApplied[Query]() - - // Query needs to be a Product (which all case class instances are) for easy access to its fields. - // Partial application helps with Scala type inference. You can specify just a single type - // parameter Query and all other type parameters can usually be inferred by Scala. - def public[Query <: Product]: WithoutAuthPartiallyApplied[Query] = - new WithoutAuthPartiallyApplied[Query]() - - def publicCo[Query <: Product]: WithoutAuthCoproductPartiallyApplied[Query] = - new WithoutAuthCoproductPartiallyApplied[Query]() - - def unitAuth: AuthPartiallyApplied[EmptyQuery.type] = auth[EmptyQuery.type] - - def unitPublic: WithoutAuthPartiallyApplied[EmptyQuery.type] = - public[EmptyQuery.type] - -} - -object AuthAndMiddlewareSupport { - // Sometimes we need to authenticate a request that requires no arguments, as the interface requires - // a Product, we can't use the Unit type but an empty case-class. - final case object EmptyQuery - - implicit def emptyQueryProtoConverter[T <: scalapb.GeneratedMessage]: ProtoConverter[T, EmptyQuery.type] = { (_, _) => - Try(EmptyQuery) - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/auth/errors/AuthErrorSupport.scala b/common/src/main/scala/io/iohk/atala/prism/auth/errors/AuthErrorSupport.scala deleted file mode 100644 index 48d2a63ad3..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/auth/errors/AuthErrorSupport.scala +++ /dev/null @@ -1,11 +0,0 @@ -package io.iohk.atala.prism.auth.errors - -import io.iohk.atala.prism.errors.ErrorSupport - -trait AuthErrorSupport extends ErrorSupport[AuthError] { - override def wrapAsServerError(cause: Throwable): InternalServerError = - InternalServerError(cause) - - override def invalidRequest(message: String): AuthError = - InvalidRequest(message) -} diff --git a/common/src/main/scala/io/iohk/atala/prism/auth/errors/package.scala b/common/src/main/scala/io/iohk/atala/prism/auth/errors/package.scala deleted file mode 100644 index 79c10bbccf..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/auth/errors/package.scala +++ /dev/null @@ -1,68 +0,0 @@ -package io.iohk.atala.prism.auth - -import derevo.derive -import io.grpc.Status -import io.iohk.atala.prism.errors.{PrismError, PrismServerError} -import tofu.logging.derivation.loggable -import io.iohk.atala.prism.logging.GeneralLoggableInstances._ - -package object errors { - @derive(loggable) - sealed trait AuthError extends PrismError - - final case class SignatureVerificationError() extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription("Signature Invalid") - } - } - - final case class UnknownPublicKeyId() extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription("Unknown public key id") - } - } - - case object CanonicalSuffixMatchStateError extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription( - "PrismDid canonical suffix does not match the state content" - ) - } - } - - case object InvalidAtalaOperationError extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription("Invalid encoded Atala operation") - } - } - - case object NoCreateDidOperationError extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription( - "Encoded operation does not create a fresh PrismDid" - ) - } - } - - final case class UnsupportedAuthMethod() extends AuthError { - override def toStatus: Status = { - Status.UNAUTHENTICATED.withDescription("Unsupported auth method") - } - } - - final case class UnexpectedError(status: Status) extends AuthError { - override def toStatus: Status = status - } - - final case class InvalidRequest(reason: String) extends AuthError { - def toStatus: Status = Status.INVALID_ARGUMENT.withDescription(reason) - } - - final case class InternalServerError(cause: Throwable) extends AuthError with PrismServerError { - override def toStatus: Status = { - Status.INTERNAL.withDescription( - s"Internal server error, cause: ${cause.getMessage}. Please contact administrator." - ) - } - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptor.scala b/common/src/main/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptor.scala deleted file mode 100644 index fbe8e847e4..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptor.scala +++ /dev/null @@ -1,47 +0,0 @@ -package io.iohk.atala.prism.auth.grpc - -import com.typesafe.config.Config -import io.grpc._ -import io.iohk.atala.prism.auth.model.AuthToken -import org.slf4j.{Logger, LoggerFactory} -import scala.jdk.CollectionConverters._ - -class AuthorizationInterceptor(globalConfig: Config) extends ServerInterceptor { - import GrpcAuthenticationContext._ - private val logger: Logger = LoggerFactory.getLogger(getClass) - - private val authEnabled: Boolean = globalConfig.getBoolean("api.authEnabled") - private val authTokens: Set[AuthToken] = loadAuthTokens(globalConfig: Config) - - override def interceptCall[ReqT, RespT]( - call: ServerCall[ReqT, RespT], - headers: Metadata, - next: ServerCallHandler[ReqT, RespT] - ): ServerCall.Listener[ReqT] = { - if (authEnabled) { - val mayBeAuthToken = getAuthTokenFromMetadata(headers) - if (mayBeAuthToken.exists(authTokens.contains)) { - Contexts.interceptCall(Context.current(), call, headers, next) - } else { - call.close( - io.grpc.Status.UNAUTHENTICATED.withDescription( - "The 'prism-auth-token' is missing from headers / The provided `prism-auth-token` is invalid" - ), - headers - ) - new ServerCall.Listener[ReqT] {} // noop - } - } else { - Contexts.interceptCall(Context.current(), call, headers, next) - } - } - - private def loadAuthTokens(globalConfig: Config): Set[AuthToken] = { - logger.info("Loading AuthTokens") - val authConfig = globalConfig.getConfig("api") - logger.info(s"AuthTokens enable $authEnabled") - if (authEnabled) { - authConfig.getStringList("authTokens").asScala.map(AuthToken).toSet - } else Set.empty[AuthToken] - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/auth/grpc/ClientTraceReadInterceptor.scala b/common/src/main/scala/io/iohk/atala/prism/auth/grpc/ClientTraceReadInterceptor.scala deleted file mode 100644 index 8c2edde597..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/auth/grpc/ClientTraceReadInterceptor.scala +++ /dev/null @@ -1,32 +0,0 @@ -package io.iohk.atala.prism.auth.grpc - -import io.grpc.ClientCall.Listener -import io.grpc.ForwardingClientCall.SimpleForwardingClientCall -import io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener -import io.grpc.{CallOptions, Channel, ClientCall, ClientInterceptor, Context, Metadata, MethodDescriptor} -import io.iohk.atala.prism.auth.grpc.GrpcAuthenticationContext._ - -class ClientTraceReadInterceptor extends ClientInterceptor { - override def interceptCall[ReqT, RespT]( - method: MethodDescriptor[ReqT, RespT], - callOptions: CallOptions, - next: Channel - ): ClientCall[ReqT, RespT] = { - - new SimpleForwardingClientCall[ReqT, RespT](next.newCall(method, callOptions)) { - override def start(responseListener: Listener[RespT], headers: Metadata): Unit = { - val traceId = getTraceIdFromContext(Context.current()) - headers.put(TraceIdKeys.metadata, traceId.traceId) - - super.start( - new SimpleForwardingClientCallListener[RespT](responseListener) { - override def onHeaders(headers: Metadata): Unit = { - super.onHeaders(headers) - } - }, - headers - ) - } - } - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/config/ConnectorConfig.scala b/common/src/main/scala/io/iohk/atala/prism/config/ConnectorConfig.scala deleted file mode 100644 index 130e9c90fd..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/config/ConnectorConfig.scala +++ /dev/null @@ -1,20 +0,0 @@ -package io.iohk.atala.prism.config - -import com.typesafe.config.Config - -case class ConnectorConfig(host: String, port: Int) - -object ConnectorConfig { - - def apply(globalConfig: Config): ConnectorConfig = { - val config = globalConfig.getConfig("connector") - - val host = config.getString("host") - val port = config.getInt("port") - - ConnectorConfig( - host = host, - port = port - ) - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/errors/ErrorSupport.scala b/common/src/main/scala/io/iohk/atala/prism/errors/ErrorSupport.scala deleted file mode 100644 index 5387b5f1f3..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/errors/ErrorSupport.scala +++ /dev/null @@ -1,113 +0,0 @@ -package io.iohk.atala.prism.errors - -import io.iohk.atala.prism.metrics.RequestMeasureUtil -import io.iohk.atala.prism.utils.FutureEither -import io.iohk.atala.prism.utils.FutureEither.FutureEitherOps -import org.slf4j.Logger -import cats.syntax.either._ - -import scala.concurrent.{ExecutionContext, Future} - -trait ErrorSupport[E <: PrismError] { - def logger: Logger - - def wrapAsServerError(cause: Throwable): E - - def invalidRequest(message: String): E - - protected def respondWith[T]( - request: scalapb.GeneratedMessage, - error: E, - serviceName: String, - methodName: String - )(implicit - ec: ExecutionContext - ): Future[T] = { - implicit val loggingContext: LoggingContext = LoggingContext( - "request" -> request - ) - Future - .successful(Left(error)) - .toFutureEither - .wrapAndRegisterExceptions(serviceName, methodName) - .flatten - } - - implicit class ErrorLoggingOps(error: E) { - def logWarn(implicit lc: LoggingContext): E = { - val status = error.toStatus - logger.warn( - s"Issuing ${error.getClass.getSimpleName}: ${status.getCode} ${status.getDescription} ($lc)" - ) - error - } - } - - implicit class InternalServerErrorLoggingOps[T <: PrismServerError]( - error: T - ) { - def logErr(implicit lc: LoggingContext): T = { - logger.error( - s"Issuing ${error.getClass.getSimpleName} ($lc)", - error.cause - ) - error - } - } - - implicit class FutureEitherErrorOps[T](v: FutureEither[PrismError, T]) { - def wrapAndRegisterExceptions(serviceName: String, methodName: String)(implicit - ec: ExecutionContext, - lc: LoggingContext - ): FutureEither[PrismError, T] = { - def logAndRegisterIfPrismServerError(error: PrismError): PrismError = { - error match { - case serverError: PrismServerError => - serverError.logErr - RequestMeasureUtil.increaseErrorCounter( - serviceName, - methodName, - error.toStatus.getCode.value() - ) - error - case _ => error - } - } - - v.value - .recover { case ex => wrapAsServerError(ex).asLeft } - .toFutureEither - .mapLeft(logAndRegisterIfPrismServerError) - } - - def successMap[U](f: T => U)(implicit ec: ExecutionContext): Future[U] = { - v.value.flatMap { - case Left(err) => Future.failed(err.toStatus.asRuntimeException()) - case Right(vv) => Future.successful(f(vv)) - } - } - - def successMapWithErrorCounter[R]( - serviceName: String, - methodName: String, - f: T => R - )(implicit - ec: ExecutionContext - ): Future[R] = { - v.value.flatMap { - case Left(err) => - val statusError = err.toStatus - RequestMeasureUtil.increaseErrorCounter( - serviceName, - methodName, - statusError.getCode.value() - ) - Future.failed(statusError.asRuntimeException()) - case Right(vv) => - Future.successful(f(vv)) - } - } - - def flatten(implicit ec: ExecutionContext): Future[T] = successMap(identity) - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/errors/LoggingContext.scala b/common/src/main/scala/io/iohk/atala/prism/errors/LoggingContext.scala deleted file mode 100644 index e18ae75003..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/errors/LoggingContext.scala +++ /dev/null @@ -1,13 +0,0 @@ -package io.iohk.atala.prism.errors - -case class LoggingContext(context: Map[String, String]) extends AnyVal { - override def toString: String = { - context.toList.sorted.map { case (k, v) => s"$k: $v" }.mkString(", ") - } -} - -object LoggingContext { - def apply(pairs: (String, Any)*): LoggingContext = { - LoggingContext(pairs.map { case (k, v) => (k, v.toString) }.toMap) - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/grpc/ProtoConverter.scala b/common/src/main/scala/io/iohk/atala/prism/grpc/ProtoConverter.scala deleted file mode 100644 index 2e1e09999f..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/grpc/ProtoConverter.scala +++ /dev/null @@ -1,18 +0,0 @@ -package io.iohk.atala.prism.grpc - -import io.iohk.atala.prism.auth.grpc.GrpcAuthenticationHeader -import scalapb.GeneratedMessage - -import scala.util.Try - -trait ProtoConverter[P <: GeneratedMessage, T] { - def fromProto(proto: P, grpcHeader: Option[GrpcAuthenticationHeader]): Try[T] -} - -object ProtoConverter { - implicit def anyToUnitConverter[T <: GeneratedMessage]: ProtoConverter[T, Unit] = (_, _) => Try(()) - - def apply[P <: GeneratedMessage, T](implicit - pc: ProtoConverter[P, T] - ): ProtoConverter[P, T] = pc -} diff --git a/common/src/main/scala/io/iohk/atala/prism/interop/CredentialContentConverter.scala b/common/src/main/scala/io/iohk/atala/prism/interop/CredentialContentConverter.scala deleted file mode 100644 index 16ffbb361e..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/interop/CredentialContentConverter.scala +++ /dev/null @@ -1,22 +0,0 @@ -package io.iohk.atala.prism.interop - -import io.iohk.atala.prism.credentials.content.CredentialContent -import scala.jdk.CollectionConverters._ -import io.circe.syntax.EncoderOps - -object CredentialContentConverter { - - implicit class JsonElementConv(val v: CredentialContent) extends AnyVal { - def asString: String = { - val map: Map[String, String] = - v.getFields.getKeys.asScala - .zip( - v.getFields.getValues.asScala.map(_.toString.drop(1).dropRight(1)) - ) - .toMap - - map.asJson.spaces2 - } - } - -} diff --git a/common/src/main/scala/io/iohk/atala/prism/interop/KotlinFunctionConverters.scala b/common/src/main/scala/io/iohk/atala/prism/interop/KotlinFunctionConverters.scala deleted file mode 100644 index 05e99519f5..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/interop/KotlinFunctionConverters.scala +++ /dev/null @@ -1,15 +0,0 @@ -package io.iohk.atala.prism.interop - -object KotlinFunctionConverters { - class RichFunction1AsKotlinFunction[A, B]( - private val underlying: scala.Function1[A, B] - ) extends AnyVal { - @inline def asKotlin: kotlin.jvm.functions.Function1[A, B] = - (p1: A) => underlying(p1) - } - - implicit def enrichAsKotlinFunction[A, B]( - sf: scala.Function1[A, B] - ): RichFunction1AsKotlinFunction[A, B] = - new RichFunction1AsKotlinFunction(sf) -} diff --git a/common/src/main/scala/io/iohk/atala/prism/models/ConnectionToken.scala b/common/src/main/scala/io/iohk/atala/prism/models/ConnectionToken.scala deleted file mode 100644 index 1f79fabda5..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/models/ConnectionToken.scala +++ /dev/null @@ -1,3 +0,0 @@ -package io.iohk.atala.prism.models - -case class ConnectionToken(token: String) extends AnyVal diff --git a/common/src/main/scala/io/iohk/atala/prism/utils/StringUtils.scala b/common/src/main/scala/io/iohk/atala/prism/utils/StringUtils.scala deleted file mode 100644 index 18ce794ddc..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/utils/StringUtils.scala +++ /dev/null @@ -1,26 +0,0 @@ -package io.iohk.atala.prism.utils - -/** Helper functions to deal with strings. - * - * NOTE: This isn't called StringOps to prevent name clashes with the stdlib. - */ -object StringUtils { - - /** Masks a string, usually used to print secrets in logs. - * - * The masking is done by taking the 2 characters from the prefix, and 2 from the suffix, the rest gets changed to - * asterisks (*). When there aren't enough characters, everything is masked. - * - * For example: - * - masked("abcdef") == "ab**ef" - * - masked("abcd") == "****" - */ - def masked(string: String): String = { - if (string.length <= 4) { - "*" * string.length - } else { - val mask = "*" * (string.length - 4) - s"${string.take(2)}$mask${string.takeRight(2)}" - } - } -} diff --git a/common/src/main/scala/io/iohk/atala/prism/utils/UriUtils.scala b/common/src/main/scala/io/iohk/atala/prism/utils/UriUtils.scala deleted file mode 100644 index 30ca69f749..0000000000 --- a/common/src/main/scala/io/iohk/atala/prism/utils/UriUtils.scala +++ /dev/null @@ -1,135 +0,0 @@ -package io.iohk.atala.prism.utils - -import io.lemonlabs.uri.config.UriConfig -import io.lemonlabs.uri.decoding.UriDecodeException -import io.lemonlabs.uri.encoding.PercentEncoder -import io.lemonlabs.uri.{QueryString, Uri, Url, Urn} - -object UriUtils { - - private implicit val uriConfig: UriConfig = UriConfig.default.copy(queryEncoder = PercentEncoder()) - - /** Normalized URI according to RFC 3986, section-6 - * - * @param uri - * @return - * (uri) - normalized uri, if it is a valid uri string, or None - */ - def normalizeUri(uriStr: String): Option[String] = { - - /* - * List of normalizations performed: - * percent encoding normalization - * decode unreserved characters - * case normalization - * scheme and host to lowercase - * all percent encoded triplets use uppercase hexadecimal chars - * path segment normalization - * remove "." and ".." segments from path - * remove duplicate forward slashes (//) from path - * scheme specific normalization (http, https) since it is likely to be often used type of URL - * remove default port - * sort query parameters by key alphabetically - * remove duplicates (by name/key) - * encode special characters that are disallowed in path and query - * decode the ones that are allowed if encoded - * - * for URN: - * convert to lowercase - * decode all percent encoded triplets (including unreserved) - * encode any that need to be encoded - * - * URL without a scheme is treated as invalid - */ - - try { - // parsing decodes the percent encoded triplets, including unreserved chars - val parsed = Uri.parse(uriStr) - parsed match { - case url: Url => - if (url.schemeOption.isEmpty) throw new UriDecodeException("Scheme is empty") - // lowercase schema - val schemeNormalized = url.schemeOption.map(_.toLowerCase()) - - // lowercase host if not IP - val hostNormalized = url.hostOption.map(_.normalize) - - // removes dot segments and extra // - val pathNormalized = url.path.normalize(removeEmptyParts = true) - - // remove unneeded ports - val portNormalized = url.port.flatMap { port: Int => - schemeNormalized match { - case Some(scheme) => - scheme match { - case "http" => if (port == 80) None else Some(port) - case "https" => if (port == 443) None else Some(port) - case "ftp" => if (port == 21) None else Some(port) - case "ws" | "wss" => if (port == 80) None else Some(port) - case _ => Some(port) - } - case None => Some(port) - } - } - - val queryNormalized = { - // filter duplicate keys (last one stays) and sort alphabetically (by key) - val filtered = url.query.params.toMap.toVector.sortBy(_._1) - QueryString(filtered) - } - - // construction of the instance encodes all special characters that are disallowed in path and query - val urlNormalized = Url( - scheme = schemeNormalized.orNull, - user = url.user.orNull, - password = url.password.orNull, - host = hostNormalized.map(_.toString).orNull, - port = portNormalized.getOrElse(-1), - path = pathNormalized.toString, - query = queryNormalized, - fragment = url.fragment.orNull - ) - - Some(urlNormalized.toString) - - case urn: Urn => - Some(urn.toString.toLowerCase) - } - } catch { - case _: Exception => None - } - } - - def isValidUriString(str: String): Boolean = { - - try { - Uri.parse(str) match { - case url: Url => url.schemeOption.nonEmpty - case Urn(_) => true - } - } catch { - case _: Exception => false - } - } - - /** Checks if a string is a valid URI fragment according to RFC 3986 section-3.5 - * - * @param str - * @return - * true if str is a valid URI fragment, otherwise false - */ - def isValidUriFragment(str: String): Boolean = { - - /* - * Alphanumeric characters (A-Z, a-z, 0-9) - * Some special characters: -._~!$&'()*+,;=:@ - * Percent-encoded characters, which are represented by the pattern %[0-9A-Fa-f]{2} - */ - val uriFragmentRegex = "^([A-Za-z0-9\\-._~!$&'()*+,;=:@/?]|%[0-9A-Fa-f]{2})*$".r - - // In general, empty URI fragment is a valid fragment, but for our use-case it would be pointless - str.nonEmpty && uriFragmentRegex.matches(str) - } -} diff --git a/common/src/test/resources/common/db/migration/V1__create_connector_message_offset.sql b/common/src/test/resources/common/db/migration/V1__create_connector_message_offset.sql deleted file mode 100644 index ed16348643..0000000000 --- a/common/src/test/resources/common/db/migration/V1__create_connector_message_offset.sql +++ /dev/null @@ -1,6 +0,0 @@ - -CREATE TABLE connector_message_offset( - id INT NOT NULL PRIMARY KEY, - message_id TEXT NOT NULL, - CONSTRAINT connector_message_offset_one_row CHECK (id = 1) -); diff --git a/common/src/test/resources/common/db/migration/V2__create_config.sql b/common/src/test/resources/common/db/migration/V2__create_config.sql deleted file mode 100644 index fccca0b815..0000000000 --- a/common/src/test/resources/common/db/migration/V2__create_config.sql +++ /dev/null @@ -1,5 +0,0 @@ - -CREATE TABLE config( - key TEXT NOT NULL PRIMARY KEY, - value TEXT NOT NULL -); diff --git a/common/src/test/resources/common/db/migration/V3__create_processing_tasks.sql b/common/src/test/resources/common/db/migration/V3__create_processing_tasks.sql deleted file mode 100644 index 923d658c1a..0000000000 --- a/common/src/test/resources/common/db/migration/V3__create_processing_tasks.sql +++ /dev/null @@ -1,9 +0,0 @@ -CREATE TABLE processing_tasks( - id UUID NOT NULL PRIMARY KEY, - state TEXT NOT NULL, - owner UUID NULL, - last_change TIMESTAMPTZ NOT NULL, - last_action TIMESTAMPTZ NOT NULL, - next_action TIMESTAMPTZ NOT NULL, - data JSONB -); diff --git a/common/src/test/resources/common/db/migration/V4__processing_tasks_owner_to_string.sql b/common/src/test/resources/common/db/migration/V4__processing_tasks_owner_to_string.sql deleted file mode 100644 index 108e2c194d..0000000000 --- a/common/src/test/resources/common/db/migration/V4__processing_tasks_owner_to_string.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE processing_tasks DROP COLUMN owner; -ALTER TABLE processing_tasks ADD COLUMN owner TEXT NULL; diff --git a/common/src/test/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptorSpec.scala b/common/src/test/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptorSpec.scala deleted file mode 100644 index cd61c948f0..0000000000 --- a/common/src/test/scala/io/iohk/atala/prism/auth/grpc/AuthorizationInterceptorSpec.scala +++ /dev/null @@ -1,91 +0,0 @@ -package io.iohk.atala.prism.auth.grpc - -import com.typesafe.config.ConfigFactory -import io.grpc.ServerCall.Listener -import io.grpc._ -import io.iohk.atala.prism.auth.grpc.GrpcAuthenticationContext.AuthTokenKeys -import org.mockito.ArgumentMatchers.{any, eq => mockEq} -import org.mockito.ArgumentMatchers.argThat -import org.mockito.Mockito.{mock, never, times, verify, when} -import org.scalatest.matchers.must.Matchers -import org.scalatest.wordspec.AnyWordSpec - -class AuthorizationInterceptorSpec extends AnyWordSpec with Matchers { - "AuthorizationInterceptor" should { - "intercept nothing when authEnabled is false" in { - val globalConfig = ConfigFactory.load() - val authorizationInterceptor = new AuthorizationInterceptor(globalConfig) - val headers = new Metadata() - val serverCall = mock(classOf[ServerCall[Int, Int]]) - val delegate = mock(classOf[Listener[Int]]) - val next = mock(classOf[ServerCallHandler[Int, Int]]) - when(next.startCall(any(classOf[ServerCall[Int, Int]]), mockEq(headers))) - .thenReturn(delegate) - - val listener = authorizationInterceptor.interceptCall(serverCall, headers, next) - listener.onReady() - verify(next, times(1)).startCall(mockEq(serverCall), mockEq(headers)) - - } - - "intercept allow when supplied prism auth token matches and authEnable is true" in { - val configOveride = """api { - | authTokens = [ - | "ShVvJ11AlVhLYv7OBO9sY9AOz8D5FoWo" - | ] - | authEnabled = true - |}""".stripMargin - val globalConfig = ConfigFactory.parseString(configOveride).withFallback(ConfigFactory.load()) - - val authorizationInterceptor = new AuthorizationInterceptor(globalConfig) - val headers = new Metadata() - headers.put(AuthTokenKeys.metadata, "ShVvJ11AlVhLYv7OBO9sY9AOz8D5FoWo") - val serverCall = mock(classOf[ServerCall[Int, Int]]) - val delegate = mock(classOf[Listener[Int]]) - val next = mock(classOf[ServerCallHandler[Int, Int]]) - when(next.startCall(any(classOf[ServerCall[Int, Int]]), mockEq(headers))) - .thenReturn(delegate) - - val listener = authorizationInterceptor.interceptCall(serverCall, headers, next) - listener.onReady() - verify(next, times(1)).startCall(mockEq(serverCall), mockEq(headers)) - - } - - "intercept fail Unauthenticated when supplied prism auth token doesn't matched and authEnable is true" in { - val configOveride = """api { - | authTokens = [ - | "YYVvJ11AlVhLYv7OBO9sY9AOz8D5FoWo" - | ] - | authEnabled = true - |}""".stripMargin - val globalConfig = ConfigFactory.parseString(configOveride).withFallback(ConfigFactory.load()) - - val authorizationInterceptor = new AuthorizationInterceptor(globalConfig) - val headers = new Metadata() - headers.put(AuthTokenKeys.metadata, "ShVvJ11AlVhLYv7OBO9sY9AOz8D5FoWo") - val serverCall = mock(classOf[ServerCall[Int, Int]]) - val delegate = mock(classOf[Listener[Int]]) - val next = mock(classOf[ServerCallHandler[Int, Int]]) - when(next.startCall(any(classOf[ServerCall[Int, Int]]), mockEq(headers))) - .thenReturn(delegate) - - val listener = authorizationInterceptor.interceptCall(serverCall, headers, next) - listener.onReady() - listener.onMessage(1) - listener.onComplete() - listener.onCancel() - verify(next, times(0)).startCall(mockEq(serverCall), mockEq(headers)) - verify(serverCall, times(1)).close( - argThat[Status](s => - (s.getCode eq Status.UNAUTHENTICATED.getCode) && s.getDescription.equals( - "The 'prism-auth-token' is missing from headers / The provided `prism-auth-token` is invalid" - ) - ), - any(classOf[Metadata]) - ) - verify(next, never()).startCall(any(classOf[ServerCall[Int, Int]]), any(classOf[Metadata])) - - } - } -} diff --git a/common/src/test/scala/io/iohk/atala/prism/utils/StringUtilsSpec.scala b/common/src/test/scala/io/iohk/atala/prism/utils/StringUtilsSpec.scala deleted file mode 100644 index f822466e17..0000000000 --- a/common/src/test/scala/io/iohk/atala/prism/utils/StringUtilsSpec.scala +++ /dev/null @@ -1,36 +0,0 @@ -package io.iohk.atala.prism.utils - -import org.scalatest.matchers.must.Matchers._ -import org.scalatest.wordspec.AnyWordSpec - -class StringUtilsSpec extends AnyWordSpec { - "mask" should { - "mask the whole string when there are less than 4 characters" in { - val cases = List( - "", - "a", - "ab", - "abc", - "abcd" - ) - - cases.foreach { input => - val result = StringUtils.masked(input) - result.length must be(input.length) - result.forall(_ == '*') must be(true) - } - } - - "longer words get a prefix/suffix unmasked" in { - val cases = List( - "abcde" -> "ab*de", - "abcdef" -> "ab**ef", - "abcdefg" -> "ab***fg" - ) - cases.foreach { case (input, expected) => - val result = StringUtils.masked(input) - result must be(expected) - } - } - } -} diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 7f461cafa5..0000000000 --- a/docs/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Documents - -Here you can find the project documentation. - -- [PRISM protocol (short version)](./article.pdf) -
Compact description of the protocol behind PRISM. -
Note **this document is public.** -- [PRISM protocol](./protocol.pdf) `.PDF` version -
[PRISM protocol](./protocol.docx) `.DOCX` version - Microsoft Word documents) -
Description of the PRISM's protocol -- [SDK](./sdk/README.md) -
This small doc aims to specify the approach we plan to take to build a decent one. - -- Diagrams - - [List of Diagrams](./new-diagrams/README.md) - - [Miscallaneous diagrams](./misc/README.md) - - [Payment flow](./payments/README.md) - -- PRISM Node: - - [Operations Lifecycle](./node/operaions-lifecycle-in-node-service.md) - - [The life cycle of an AtalaOperation](./node/operations-ordering-submission.md) - - [Rate limiting requests](./node/rate-limiting.md) - - [Subscriptions and their use cases](./node/SubscriptionMechanism.md) -- PRISM components: - - [Cardano - Integration](./cardano/README.md) - - [Connector - End to End Encryption](./connector/e2e-encryption.md) - - [PRISM gRPC Streaming](./grpc/streaming.md) - - [Encrypted Data Vault](./data-vault/README.md) - - [Wallet Backend Motivation](./wallet-backend/motivation.md) -- Monitoring: - - [Logging](./monitoring/logging/README.md) - - [Metrics](./monitoring/metrics/README.md) -- Offline Mode: - - [PRISM while Cardano is offline](./moe/full-offline-mode.md) - - [PRISM Offline Mode](./moe/offline-mode.md) -- [Atala PRISM on-premise deployments](./on-premise-deployments/README.md) -- [Tasks and Leases](./mirror/tasks-and-leases.md) -- [Bitcoin - Atala Prism](./bitcoin/README.md) - -- Endorsements & Proposals: - - [Endorsements](./endorsements/endorsements.md) - - [GEUD Proposal - Connector](./connector/README.md) - - [Proposal: MoE controls all master keys](./endorsements/MoE-controls-master-keys-proposal.md) - - [GEUD Proposal - Indy](./indy/README.md) - -- [Problems with signing structured data](./signing.md) - -## Compiling diagrams - -There are some requirements to compile the diagrams: - -- Install graphviz, on ubuntu-based systems should be as simple as running `apt-get install graphviz`, verify the installation by running `dot -v`. -- Download the plantuml jar file from the [official site](http://plantuml.com/starting). - -Then, open a terminal on the directory with the `*.puml` files, and run the following command after replacing the location for your `plantuml.jar` file: - -- `for file in *.puml; do java -jar ~/Downloads/plantuml.jar "$file"; done` - -It is useful to see the diagram changes as you edit the sources, there is a [plantuml plugin for IntelliJ](https://plugins.jetbrains.com/plugin/7017-plantuml-integration/) which can help. - -## Add new Documents - -When creating a new document, choose the best tool for the job. -We recommend using: - -- Markdown format for quick documentation; -- Latex format for a more formal document; -- [Mermaid format](https://mermaid-js.github.io/mermaid/#/) (inside a Markdown file) for flowcharts or Sequence diagrams. (Since is already supported by github) - -After creating the document upload this index file. -
Also, you will probably need to update the Github Action [`Generate_Documentation`](/.github/workflows/gh-pages-documentation-website.yml) to build your new document. - -## Update Documents - -Most pdf documents should be updated/refreshed automatically when changed. - -For the components that have diagrams generated by plantuml be sure to compile them each time they are updated. -We intend to automate this in the future. diff --git a/docs/bitcoin/README.md b/docs/bitcoin/README.md deleted file mode 100644 index eb0fd97958..0000000000 --- a/docs/bitcoin/README.md +++ /dev/null @@ -1,109 +0,0 @@ -# Atala Prism - Bitcoin - -This document has the high-level view of the Atala Prism project on top of Bitcoin. - -Each participant will be responsible for managing and storing their secret keys securely, this includes issuers (like universities) and verifiers (employers). - -Related to payments, the approach assumes we'll bill per connection, which indirectly correlates to issuing and verifying a credential, the drawback is that an issuer could issue several credentials to the same person but that shouldn't be a problem. - -**NOTE [2019-09-02]**: We decided to follow this approach, so it is not a proposal anymore. - -**NOTE [2020-11-03]**: You may also want to check some [newer](../new-diagrams/README.md) [diagrams](../misc/wmc/prism_architecture.png). - -## Definitions -- **GEUD**: The Georgia University Degrees project. -- **Issuer**: The actor that is interested in issuing credentials to holders (like an university). -- **Holder**: The actor who receives and holds credentials (like a student). -- **Verifier**: The actor who is interested in verifying credentials from holders (like an employer). - -- **Credential**: Formatted data holding some claims of certain holder, with cryptographic proofs from the issuer (like a university degree). - -- **Issuer Computer**: The computer that the issuer uses to perform operations related to credentials, like issuing or revoking credentials. -- **Issuer Wallet**: A local application installed on the issuer computer which is in charge of storing securely the issuer private keys, as well as performing the cryptographic operations with those keys. -- **Issuer Web Application**: The web application that the issuer use to interact with the credentials. - -- **Verifier Computer**: The computer that the verifier uses to verify credentials. -- **Verifier Wallet**: The local application installed on the verifier computer which stores the verifier private keys securely, as well as performing the cryptographic operations with those keys. -- **Verifier Web Application**: The web applications that allows the verifier to connect to credential holders as well as to validate those credentials. - -- **Holder Phone**: The mobile phone used by the certificate holders to use the Holder Wallet. -- **Holder Wallet**: The mobile wallet (Android, iOS) used to store and share their credentials securely. - -- **Frontend**: The server that can be reached from the internet, it's the entry point to the system. -- **Reverse Proxy**: A middleware that proxies HTTP connections from clients to the internal servers. -- **Web Application**: An application downloaded from the frontend that runs locally on the computers. - -- **IOHK Cloud**: The IOHK infrastructure which runs all the services and servers, controller by IOHk. -- **Node**: The component that acts as a 2nd layer node on top of a ledger. -- **ATALA Node**: The 2nd layer node working on top of Bitcoin. It understands DIDs and credentials, any interested party can run this node to get the Prism blockchain details, but is not a requirement, the data will be safe even with a single node running. -- **ATALA Database**: The centralized database used by the ATALA Node to index information. -- **Bitcoin**: A full Bitcoin node that keeps the blockchain available to let us retrieve the ATALA-specific transactions. - -- **Connector**: As there are mobile phones involved, the task of communicating with them starts to get complicated, this component solves that problem, it allows to open bidirectional communication channels from the issuers/verifiers to the holders wallet, the connector also servers as a mailbox to deliver messages to the holder wallet once it gets online. -- **Connector Server**: The server providing the connector API. -- **Connector Database**: The database used by the connector server. - -- **Credentials Manager**: The university will need a way to store historical records, like all the issued credentials, this service is the one allowing the university to perform CRUD operations on such records. -- **Credentials Manager Server**: The server providing the credentials manager API. -- **Credentials Manager Database**: The database used by the credentials manager server. - - -## General overview -This diagram shows all the components: -![architecture](diagrams/architecture.png) - -**NOTE**: At Nov/29 the Credentials Manager has been merged into the Connector, the [PR](https://github.com/input-output-hk/atala/pull/477) has more details. - -### Preparation steps - -As IOHK will run all the infrastructure for providing the credentials verification product and services, IOHK needs a way to onboard the issuers into the system. - -**IOHK holds the relationships between issuers and their public DID, onboarding an issuer means that IOHK adds a new relationship**. - -The issuer needs to do some preparation steps before being able to issue credentials: -![university-wallet-preparation](diagrams/university-wallet-preparation.png) - - -The holder also needs to do some preparation steps before being able to receive credentials, please note that these steps may be done on the onboarding process: - -![student-wallet-preparation](diagrams/student-wallet-preparation.png) - -Completing the preparation steps means that: -- The issuer has everything ready to issue credentials. -- IOHK knows about the issuer and can allow it to connect to holders, this also implies that the issuer has registered a payment method with IOHK. -- The issuer has its private key stored securely (ideally, in cold storage). -- The holder has already created a wallet. - - -### Onboarding the holder -The onboarding process involves getting the issuer and the holder connected on the system, which will allow them to exchange messages. - -For this process to work, the issuer must have a secure way to share a QR code with the holder. - -![onboarding](diagrams/onboarding.png) - - -### Issuing a credential -The issuer will likely get the issuing private key unlocked from cold storage, issue a batch of credentials, and move the private key back to the cold storage. IOHK will serve as a mailbox to store the encrypted credential for each holder, and share them with the holders once their wallets them get connected to the internet. - -![issue-credential](diagrams/issue-credential.png) - -### Verifying a credential -A verifier will need to verify a credential from a holder. - -In order to validate the credential, it needs to be shared to the verifier, the holder and the verifier can follow a similar onboarding process in order to get them connected, then, the holder shares the credential with the verifier by using that connection. - -The verifier interacts with the node in order to verify the credential validity. - -![verify-credential](diagrams/verify-credential.png) - -**NOTE**: Exporting the credential is not supported on purpose, that forces the holder to go to our connection channels which is the only way we could charge for certain operations, the issuer should be able to export credentials. - -### Holder recovering data -As the holder's wallet generates a recovery seed when creating it, the same recovery seed could be used after installing the mobile app on a different phone to recover its data. The recovery seed only allows to recover the private DIDs, the certificates need to be sent again from the issuer, which can be done by reusing the connection that was used to issue the certificates. - -The manual process for recovering the certificates prevent unintended access to people that got access to the holder's recovery seed. - -![student-recovery](diagrams/student-recovery.png) - -**NOTE**: For a future version, we may want to support recovering the holder's data automatically, which can be restored if we kept encrypted backups on the cloud but we need to take into consideration that compromising the recovery seed could compromise all the holder's data. diff --git a/docs/bitcoin/bitcoind.md b/docs/bitcoin/bitcoind.md deleted file mode 100644 index 1296cc87fb..0000000000 --- a/docs/bitcoin/bitcoind.md +++ /dev/null @@ -1,317 +0,0 @@ -# Running a development instance of bitcoind - -**NOTE:** The examples in this document have been tested using bitcoind version 0.18.1 - -## Setup - -This documents describes how to setup a locally running bitcoin testnet, operating in 'regtest' mode. - -Once you have installed bitcoind/bitcoin-cli following the needs of your system, you need to follow this steps: - -1. Create a configuration file at `~/.bitcoin/bitcoin.conf` - -```properties -rpcuser=bitcoin -rpcpassword=bitcoin -regtest=1 -rpcport=8332 -rpcallowip=127.0.0.1 -rpcconnect=127.0.0.1 -txindex=1 -``` - -2. Start the bitcoind regtest - -You have two options to start the regtest network: - -a) Running it in the 'foreground' - -You simply run this command: -```bash -> bitcoind -``` - -and the full output will appear in your terminal. You can stop it by pressing `ctrl-c` - -b) Running it as a daemon (in the 'background') - -Run this command to start the regtest: -```bash -> bitcoind -daemon -``` - -To stop the daemon: -```bash -> bitcoin-cli stop -``` - -3. Create some initial content in the regtest, so that the other operations can work - -With the regtest running, execute the following command: - -```bash -> bitcoin-cli generatetoaddress 101 `bitcoin-cli getnewaddress` -[ - "750633052a6d213cc6df5aec6ac51395550e7673c03a244609a1339d6aebb8d3", - [...] - "468456e9b3250355c1434d5f75baac9484b9b879e49bc250ad5b78a236b380be" -] -``` - -## Operations - -* To create a new address: -```bash -> SAMPLE_ADDRESS=`bitcoin-cli getnewaddress` -``` - -* To send 10 bitcoins to the sample address: -```bash -> bitcoin-cli sendtoaddress $SAMPLE_ADDRESS 10.00 -a71d95ad59a532d791eed60ca8bf844c2c0aa23427f730c6a7904041cae0d4d5 -``` - -This bitcoins we have just sent to the sample address will be unconfirmed - -* To check the balance in the address we have just created: -```bash -> bitcoin-cli getreceivedbyaddress $SAMPLE_ADDRESS -0.00000000 -``` - -You will see it stills says that the address has no bitcoins. - -We can check, instead, the unconfirmed balance we have: -```bash -> bitcoin-cli getreceivedbyaddress $SAMPLE_ADDRESS 0 -10.00000000 -``` - -To confirm this new balance, we need to mint some new blocks: -```bash -> bitcoin-cli generatetoaddress 101 `bitcoin-cli getnewaddress` -[ - "750633052a6d213cc6df5aec6ac51395550e7673c03a244609a1339d6aebb8d3", - [...] - "468456e9b3250355c1434d5f75baac9484b9b879e49bc250ad5b78a236b380be" -] -``` - -If we check the balance again, we should now have the bitcons confirmed - -* To generate a single block for the new address: -```bash -> bitcoin-cli generatetoaddress 1 $SAMPLE_ADDRESS -[ - "750633052a6d213cc6df5aec6ac51395550e7673c03a244609a1339d6aebb8d3" -] -``` - -* To get an overview of the content of the local wallet: -```bash -> bitcoin-cli getwalletinfo -{ - "walletname": "", - "walletversion": 169900, - "balance": 49.99996680, - "unconfirmed_balance": 0.00000000, - "immature_balance": 5000.00000000, - "txcount": 102, - "keypoololdest": 1569434507, - "keypoolsize": 1000, - "keypoolsize_hd_internal": 1000, - "paytxfee": 0.00000000, - "hdseedid": "e621598e36410078dc98ae7d48a62e052c5f8664", - "private_keys_enabled": true -} -``` - -* To see a list of addresses and what each has: -```bash -> bitcoin-cli listreceivedbyaddress -[ - { - "address": "2NF6Uy27XhF5PXtDmQj8GGTYr89BMsC3U4D", - "amount": 20.00000000, - "confirmations": 101, - "label": "", - "txids": [ - "a71d95ad59a532d791eed60ca8bf844c2c0aa23427f730c6a7904041cae0d4d5", - "0487ac8ee4d94aed5462c14fc273fd578ccbf4bc0d8bcd2749ef63d61bc5d7e6" - ] - } -] -``` - -## Create an OP_RETURN transaction - -Supposing we have a `SAMPLE_ADDRESS` with some bitcoins in it. - -We can list all the unspent transaction outputs for that address with this command: -```bash -> bitcoin-cli listunspent 1 9999999 "[\"$SAMPLE_ADDRESS\"]" -[ - { - "txid": "d0c209bfb1ca2d3aad9ac7ba7000cbe9cfd07b3da17a28cc5bf068a44009a55c", - "vout": 1, - "address": "2NGPcR7WuaGETYEkGYgzNmyRX2CNovLg1Jo", - "label": "", - "redeemScript": "00141f96f4d65ee6cb402a8415c27a5d4e26f454a3e3", - "scriptPubKey": "a914fde0f157e8f0343209c65acfcea387ae7fb872f887", - "amount": 10.00000000, - "confirmations": 101, - "spendable": true, - "solvable": true, - "desc": "sh(wpkh([bdd88235/0'/0'/3']02bcff851013f595d355c0b81498c48a8975458a2f63be4555d6b6b8278c41e5d0))#p2wmdzng", - "safe": true - } -] -``` - -We can then, prepare some other environment variables that are to be used to create the OP_RETURN transaction: -```bash -> utxo_txid=$(bitcoin-cli listunspent 1 9999999 "[\"$SAMPLE_ADDRESS\"]" | jq -r '.[0] | .txid') -> utxo_vout=$(bitcoin-cli listunspent 1 9999999 "[\"$SAMPLE_ADDRESS\"]" | jq -r '.[0] | .vout') -> utxo_amount=$(bitcoin-cli listunspent 1 9999999 "[\"$SAMPLE_ADDRESS\"]" | jq -r '.[0] | .amount') -> changeaddress=$(bitcoin-cli getrawchangeaddress) -> change=`echo "$utxo_amount - 0.0005" | bc` -``` - -Then, we will create an environment variable containing the data we want to store in the OP_RETURN: -```bash -> op_return_data_raw="foo" -> op_return_data=$(hexdump -e '"%064X"' <<< "$op_return_data_raw") -``` - -Next, we can get the content of the transaction we are going to send: -```bash -> rawtxhex=$(bitcoin-cli -named createrawtransaction inputs='''[ { "txid": "'$utxo_txid'", "vout": '$utxo_vout' } ]''' outputs='''{ "data": "'$op_return_data'", "'$changeaddress'": '$change' }''') -``` - -This is how the transaction looks like: -```bash -> bitcoin-cli -named decoderawtransaction hexstring=$rawtxhex -{ - "txid": "695f7e30ca3f3c16446d20185c105b579e4da698df9919f69810a77209dee2fe", - "hash": "695f7e30ca3f3c16446d20185c105b579e4da698df9919f69810a77209dee2fe", - "version": 2, - "size": 126, - "vsize": 126, - "weight": 504, - "locktime": 0, - "vin": [ - { - "txid": "d0c209bfb1ca2d3aad9ac7ba7000cbe9cfd07b3da17a28cc5bf068a44009a55c", - "vout": 1, - "scriptSig": { - "asm": "", - "hex": "" - }, - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 0.00000000, - "n": 0, - "scriptPubKey": { - "asm": "OP_RETURN 000000000000000000000000000000000000000000000000000000000a6f6f66", - "hex": "6a20000000000000000000000000000000000000000000000000000000000a6f6f66", - "type": "nulldata" - } - }, - { - "value": 9.99950000, - "n": 1, - "scriptPubKey": { - "asm": "OP_HASH160 812153a0ee767b52aa7bc37fc1d7be1f9d0a5d72 OP_EQUAL", - "hex": "a914812153a0ee767b52aa7bc37fc1d7be1f9d0a5d7287", - "reqSigs": 1, - "type": "scripthash", - "addresses": [ - "2N5215cDb1rpYXTqvBgLW9A2CJMuB2UMFkn" - ] - } - } - ] -} -``` - -We can then, sign the transaction: -```bash -> signed_transaction=`bitcoin-cli signrawtransactionwithwallet $rawtxhex | jq -r '.hex'` -``` - -And finally, send the transaction: -```bash -> txid=`bitcoin-cli sendrawtransaction "$signed_transaction"` -``` - -We can now mine some blocks to move things forward: -```bash -> bitcoin-cli generatetoaddress 101 `bitcoin-cli getnewaddress` -[ - "750633052a6d213cc6df5aec6ac51395550e7673c03a244609a1339d6aebb8d3", - [...] - "468456e9b3250355c1434d5f75baac9484b9b879e49bc250ad5b78a236b380be" -] -``` - -And finally, we can check our transaction in the blockchain: -```bash -> bitcoin-cli getrawtransaction "$txid" 1 -{ - "txid": "a68d5afa0b22a30311177a6fdab0deb6b523d3e31d1174519be85d7c2f38b0cb", - "hash": "9ed7d64f45b17e87d4c61c9efa9cf2369fd62991bbb5b72210242657d2ec95c6", - "version": 2, - "size": 258, - "vsize": 177, - "weight": 705, - "locktime": 0, - "vin": [ - { - "txid": "462c578f08c54fab79a7bf16a91d6122586c9dc00955aff9ae29c4d13777776e", - "vout": 1, - "scriptSig": { - "asm": "0014c0942005e8eaa6ac62a674382c70acaa63dd6531", - "hex": "160014c0942005e8eaa6ac62a674382c70acaa63dd6531" - }, - "txinwitness": [ - "30440220108a32a0cb7079553e7f10e3990630572363ceb64002e2d1dbbac58e53406e94022015895cc794047b444ee354c94836c5195e0f75846395236e2c56ff0c08894ae801", - "037fa4455b18b1c477d5327001744848a5ea11d206b684ac2d7edf6cfb891efd86" - ], - "sequence": 4294967295 - } - ], - "vout": [ - { - "value": 0.00000000, - "n": 0, - "scriptPubKey": { - "asm": "OP_RETURN 000000000000000000000000000000000000000000000000000000000a6f6f66", - "hex": "6a20000000000000000000000000000000000000000000000000000000000a6f6f66", - "type": "nulldata" - } - }, - { - "value": 9.99950000, - "n": 1, - "scriptPubKey": { - "asm": "OP_HASH160 ee98a500ba16a23041719faeb1bd66f6a85e5b11 OP_EQUAL", - "hex": "a914ee98a500ba16a23041719faeb1bd66f6a85e5b1187", - "reqSigs": 1, - "type": "scripthash", - "addresses": [ - "2NEzofsKJyGCdGYMFDUqtBfBgy9p8i3PoQW" - ] - } - } - ], - "hex": "020000000001016e777737d1c429aef9af5509c09d6c5822611da916bfa779ab4fc5088f572c460100000017160014c0942005e8eaa6ac62a674382c70acaa63dd6531ffffffff020000000000000000226a20000000000000000000000000000000000000000000000000000000000a6f6f66b0069a3b0000000017a914ee98a500ba16a23041719faeb1bd66f6a85e5b1187024730440220108a32a0cb7079553e7f10e3990630572363ceb64002e2d1dbbac58e53406e94022015895cc794047b444ee354c94836c5195e0f75846395236e2c56ff0c08894ae80121037fa4455b18b1c477d5327001744848a5ea11d206b684ac2d7edf6cfb891efd8600000000", - "blockhash": "3fdfc1b32df094b07b3cc983505794c1117000dcf141426686d2ffcbe9fe6bbf", - "confirmations": 101, - "time": 1569928842, - "blocktime": 1569928842 -} -``` - diff --git a/docs/bitcoin/diagrams/architecture.png b/docs/bitcoin/diagrams/architecture.png deleted file mode 100644 index c1769f74a1d41a5998c0b99a861310c6beae4187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66863 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

@?dL`ost+*w#8pv#dO=IX7wG(V_(uVWgOCd# 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 diff --git a/docs/bitcoin/diagrams/architecture.puml b/docs/bitcoin/diagrams/architecture.puml deleted file mode 100644 index 4a862d83a3..0000000000 --- a/docs/bitcoin/diagrams/architecture.puml +++ /dev/null @@ -1,70 +0,0 @@ -@startuml - -title GEUD - Architecture - -left to right direction - -skinparam { - ArrowColor Red - linetype ortho -} - -skinparam cloud { - BorderColor Black -} - -cloud "IOHK Cloud" as IOHKCloud { - rectangle Connector { - node "Connector Server" as ConnectorServer - database "Connector Database" as ConnectorDatabase - ConnectorServer --> ConnectorDatabase - } - - rectangle "Credentials Manager" as CredentialsManager { - node "Credentials Manager Server" as CredentialsManagerServer - database "Credentials Manager Database" as CredentialsManagerDatabase - CredentialsManagerServer --> CredentialsManagerDatabase - } - - rectangle Node { - node Bitcoin - node "ATALA Node" as AtalaNode - database "ATALA Database" as AtalaDatabase - AtalaNode --> AtalaDatabase - AtalaNode ---> Bitcoin - } - - rectangle Frontend { - node "Reverse Proxy" as ReverseProxy - node "Web Application" as WebApp - } - - ReverseProxy ---> ConnectorServer - ReverseProxy ---> CredentialsManagerServer - ReverseProxy ---> AtalaNode - CredentialsManagerServer -left-> ConnectorServer - CredentialsManagerServer --left--> AtalaNode -} - -rectangle "Issuer Computer" as IssuerComputer { - [Issuer Wallet] as IssuerWallet - [Issuer Web Application] as IssuerWebApp - IssuerWebApp -> IssuerWallet - IssuerWebApp -left-> ReverseProxy -} - -rectangle "Verifier Computer" as VerifierComputer { - [Verifier Wallet.] as VerifierWallet - [Verifier Web Application] as VerifierWebApp - VerifierWebApp -> VerifierWallet - VerifierWebApp --> ReverseProxy -} - -HolderPhone -[hidden]- IOHKCloud - -rectangle "Holder Phone" as HolderPhone { - [Holder Wallet] as HolderWallet - HolderWallet -> ReverseProxy -} - -@enduml \ No newline at end of file diff --git a/docs/bitcoin/diagrams/issue-credential.png b/docs/bitcoin/diagrams/issue-credential.png deleted file mode 100644 index d9512c56d3a0298b7b33f36ffb5208f49bf2989f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33326 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 diff --git a/docs/bitcoin/diagrams/issue-credential.puml b/docs/bitcoin/diagrams/issue-credential.puml deleted file mode 100644 index 1591af821d..0000000000 --- a/docs/bitcoin/diagrams/issue-credential.puml +++ /dev/null @@ -1,22 +0,0 @@ -@startuml -title Bitcoin - Issue credential - -participant "ATALA Node" as AtalaNode -actor Issuer -participant IOHK -actor Holder - -Issuer -> Issuer : Unlocks cold storage key -Issuer -> Issuer : Find holder's DID and personal details -Issuer -> Issuer : Issue and store the credential -Issuer -> AtalaNode : Store proof-of-existence -AtalaNode -> Issuer : Proof stored -Issuer -> IOHK : Share credential -IOHK -> IOHK : Verifies the issuer is\n connected to the holder -IOHK -> IOHK : Store the credential -IOHK -> Issuer : Ack -IOHK -> Holder : Share credential once it gets online -Holder -> IOHK : Ack -Holder -> Holder : Verify credential validity -Holder -> Holder : Store credential -@enduml \ No newline at end of file diff --git a/docs/bitcoin/diagrams/onboarding.png b/docs/bitcoin/diagrams/onboarding.png deleted file mode 100644 index 192e3b913090acad497182d91426fc7b4eaa3f66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48747 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�kzZ`m`Kp-}MF+ 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 IOHK : Ask for a connection code -IOHK -> IOHK : Verify Issuer identity -IOHK -> IOHK : Verify Issuer billing plan\n the Issuer may need to pay\n or the Holder may pay instead \n or it may be free -IOHK -> IOHK : Generate unique connection code -IOHK -> Issuer : Connection code generated - -Issuer -> Holder : Share the connection code as a QR code -Holder -> Holder : Scan Issuer QR code -Holder -> IOHK : Get Issuer from connection code -IOHK -> Holder : Issuer details retrieved -Holder -> Holder : Validate whether a payment is required -Holder -> Holder : Add Issuer connection\n attaching an optional proof of payment\n which depends on the previous details - -Holder -> Holder : Generate private DID -note over Holder : A private DID doesn't get published anywhere.\n It is known only by the owner and the entities chosen by then owner.\n Usually, a private DID is known by a single entity. -Holder -> IOHK : Accept connection (Issuer, DID) -IOHK -> Holder : Connection registered -IOHK -> Issuer : Holder connected -@enduml diff --git a/docs/bitcoin/diagrams/student-recovery.png b/docs/bitcoin/diagrams/student-recovery.png deleted file mode 100644 index 83b5d85a701186aca6596fe4a3f81d7d15876568..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44747 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 UO;_cj@W^Kyt3#IeFdo1D6Gptm5dZ)H diff --git a/docs/bitcoin/diagrams/student-recovery.puml b/docs/bitcoin/diagrams/student-recovery.puml deleted file mode 100644 index 4bff805e9b..0000000000 --- a/docs/bitcoin/diagrams/student-recovery.puml +++ /dev/null @@ -1,24 +0,0 @@ -@startuml -title Bitcoin - Holder recovering data - -actor Holder -participant "Holder Wallet" as HolderWallet -participant IOHK -actor Issuer - -Holder -> HolderWallet : Recover data -HolderWallet -> Holder : Ask for recovery seed -Holder -> HolderWallet : Enter recovery seed -HolderWallet -> HolderWallet : Deterministically generate private keys -HolderWallet -> IOHK : Look for existing connections -IOHK -> HolderWallet : Got existing connections - -Holder -> Issuer : Ask to resend existing certificates -note right of Holder : Holder goes to the Issuer offices, which prevents attackers\n to access holder credentials if they compromise the holder recovery seed -Issuer -> Issuer : Validate holder request and identity -Issuer -> IOHK : Submit certificates to the holder -note over Issuer : The same connection that was used while issuing\n the certificate is used again -IOHK -> HolderWallet : Existing certificates recovered -HolderWallet -> HolderWallet : Store recovered certificates -HolderWallet -> Holder : Display recovered data -@enduml \ No newline at end of file diff --git a/docs/bitcoin/diagrams/student-wallet-preparation.png b/docs/bitcoin/diagrams/student-wallet-preparation.png deleted file mode 100644 index 3f359cecb84e1f08f75bc65c2beeee2cb63a1f06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15917 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 HolderWallet : Create wallet -HolderWallet -> HolderWallet : Generate recovery seed -HolderWallet -> Holder : Recovery seed generated -Holder -> Holder : Backups the recovery seed -@enduml \ No newline at end of file diff --git a/docs/bitcoin/diagrams/university-wallet-preparation.png b/docs/bitcoin/diagrams/university-wallet-preparation.png deleted file mode 100644 index 012d2e351a26a25f97be65947c1ba88725ce99f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 64529 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 WebPortal : Register -WebPortal -> IssuerWallet : Create Wallet\n (requires password and organization) -IssuerWallet -> IssuerWallet : Generates wallet data\n (keys, DID, etc) -IssuerWallet -> IssuerWallet : Encrypts and stores wallet data -IssuerWallet -> WebPortal : Wallet Created -WebPortal -> IssuerWallet : Create DID registration request -IssuerWallet -> WebPortal : DID Registration Request -WebPortal -> Issuer : Export DID Registration Request as file -note over Issuer : At this point, the Issuer has created its identity\n but it needs to be reviewed by IOHK - -Issuer -> IOHK : Sends registration request file -note over IOHK : IOHK needs to validate the organization manually -IOHK -> AtalaNode : Publish Issuer DID -AtalaNode -> IOHK : DID published -IOHK -> IOHK : Update the database manually\n to add the issuer details -IOHK -> Issuer : Registration successful -note over Issuer : Now the Issuer can interact with our system -Issuer -> Issuer : Backups its wallet -note over Issuer : The Issuer will likely issue\n credentials in batches,\n possibly twice a year\n having the key in cold storage is\n a safe mechanism for protecting it\n to prevent getting it compromised -@enduml diff --git a/docs/bitcoin/diagrams/verify-credential.png b/docs/bitcoin/diagrams/verify-credential.png deleted file mode 100644 index 3c936fbfeab58215858cbb8d21a7b1c41b5e7bb9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65125 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