Skip to content

Commit

Permalink
Parse scope ownership changes
Browse files Browse the repository at this point in the history
* Added Encryption dependency for signature parsing
* Added migration to track ownership changes
* Updated OwnershipChanges.md doc

closes: #247
  • Loading branch information
Carolyn Russell committed Dec 9, 2021
1 parent 61c2145 commit 883b957
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 16 deletions.
3 changes: 2 additions & 1 deletion buildSrc/src/main/kotlin/Dependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ object Versions {
const val Protobuf = "3.19.1"
const val Grpc = "1.40.1"
const val KotlinGrpc = "1.2.0"
const val GrpcStarter = "4.5.6"
const val Postgres = "42.2.23"
const val Encryption = "0.4.0"

// Testing
const val Jupiter = "5.7.1"
Expand Down Expand Up @@ -94,6 +94,7 @@ object Libraries {
const val ApacheCommonsText = "org.apache.commons:commons-text:${Versions.ApacheCommonsText}"
const val Khttp = "khttp:khttp:${Versions.Khttp}"
const val KaseChange = "net.pearx.kasechange:kasechange:${Versions.KaseChange}"
const val Encryption = "io.provenance.scope:encryption:${Versions.Encryption}"

// Logging
const val LogbackCore = "ch.qos.logback.contrib:logback-json-core:${Versions.Logback}"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
SELECT 'Add nft_scope_value_owner' AS comment;
CREATE TABLE IF NOT EXISTS nft_scope_value_owner
(
id SERIAL PRIMARY KEY,
scope_id INT NOT NULL,
scope_addr VARCHAR(128) NOT NULL,
value_owner VARCHAR(256) NOT NULL,
tx_id INT NOT NULL,
block_height INT NOT NULL,
tx_hash VARCHAR(64) NOT NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS nft_scope_vo_scope_address_tx_idx
ON nft_scope_value_owner (scope_id, value_owner, tx_id);
CREATE INDEX IF NOT EXISTS nft_scope_vo_scope_id_idx ON nft_scope_value_owner (scope_id);
CREATE INDEX IF NOT EXISTS nft_scope_vo_scope_addr_idx ON nft_scope_value_owner (scope_addr);
CREATE INDEX IF NOT EXISTS nft_scope_vo_address_idx ON nft_scope_value_owner (value_owner);
CREATE INDEX IF NOT EXISTS nft_scope_vo_block_height_idx ON nft_scope_value_owner (block_height);


SELECT 'Add nft_scope_owner' AS comment;
CREATE TABLE IF NOT EXISTS nft_scope_owner
(
id SERIAL PRIMARY KEY,
scope_id INT NOT NULL,
scope_addr VARCHAR(128) NOT NULL,
owners_data JSONB NOT NULL,
owners_data_hash TEXT NOT NULL,
tx_id INT NOT NULL,
block_height INT NOT NULL,
tx_hash VARCHAR(64) NOT NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS nft_scope_owner_scope_owners_data_tx_idx
ON nft_scope_owner (scope_id, owners_data_hash, tx_id);
CREATE INDEX IF NOT EXISTS nft_scope_owner_scope_id_idx ON nft_scope_owner (scope_id);
CREATE INDEX IF NOT EXISTS nft_scope_owner_scope_addr_idx ON nft_scope_owner (scope_addr);
CREATE INDEX IF NOT EXISTS nft_scope_owner_block_height_idx ON nft_scope_owner (block_height);

SELECT 'Add nft_scope_data_access' AS comment;
CREATE TABLE IF NOT EXISTS nft_scope_data_access
(
id SERIAL PRIMARY KEY,
scope_id INT NOT NULL,
scope_addr VARCHAR(128) NOT NULL,
access_data JSONB NOT NULL,
access_data_hash TEXT NOT NULL,
tx_id INT NOT NULL,
block_height INT NOT NULL,
tx_hash VARCHAR(64) NOT NULL
);

CREATE UNIQUE INDEX IF NOT EXISTS nft_scope_data_access_scope_access_data_tx_idx
ON nft_scope_data_access (scope_id, access_data_hash, tx_id);
CREATE INDEX IF NOT EXISTS nft_scope_data_access_scope_id_idx ON nft_scope_data_access (scope_id);
CREATE INDEX IF NOT EXISTS nft_scope_data_access_scope_addr_idx ON nft_scope_data_access (scope_addr);
CREATE INDEX IF NOT EXISTS nft_scope_data_access_block_height_idx ON nft_scope_data_access (block_height);
111 changes: 110 additions & 1 deletion docs/nft/OwnerUpdates.md
Original file line number Diff line number Diff line change
@@ -1 +1,110 @@
Track when a scope owner/value owner/data access is initiated or updated.
# Owner / Valueowner / Data Access changes
* track when the values change
* use to count how many scopes the address owns / value owns

### Owner changes
* Can only be updated through a WriteScopeRequest or {Add|Delete}ScopeOwnerRequest
* can be 1 or more entries

### ValueOwner changes
* Can only be updated through a WriteScopeRequest
* only 1 entry

### Data Access changes
* Can be updated by P8eMemorializeContract - Adds only
* Can be updated through a WriteScopeRequest or {Add|Delete}ScopeDataAccess
* Can be 0 or more entries


## Owner Changes
* `nft_scope_owner`
* id SERIAL PRIMARY KEY,
* scope_id INT NOT NULL,
* scope_addr VARCHAR(128) NOT NULL,
* tx_id INT NOT NULL,
* block_height INT NOT NULL,
* tx_hash VARCHAR(64) NOT NULL,
* owners_data JSONB NOT NULL,
* owners_data_hash TEXT NOT NULL

* owners_data object
* list
* owner
* role - list

* on insert, check for latest data, and compare hashes
* to ensure compatibility, order owners alphabetically, then save/compare/hash

* on fetch, gather list of objects, sorted by height
* first record, all adds
* second record,
* if new address, add
* if address doesnt exist, removal


## Value Owner Changes
* `nft_scope_value_owner`
* id SERIAL PRIMARY KEY,
* scope_id INT NOT NULL,
* scope_addr VARCHAR(128) NOT NULL,
* tx_id INT NOT NULL,
* block_height INT NOT NULL,
* tx_hash VARCHAR(64) NOT NULL,
* value_owner VARCHAR(256) NOT NULL

* on insert, check for latest data, and compare value_owner

* on fetch, gather list of objects, sorted by height


## Data Access Changes
* `nft_scope_owner`
* id SERIAL PRIMARY KEY,
* scope_id INT NOT NULL,
* scope_addr VARCHAR(128) NOT NULL,
* tx_id INT NOT NULL,
* block_height INT NOT NULL,
* tx_hash VARCHAR(64) NOT NULL,
* access_data JSONB NOT NULL,
* access_data_hash TEXT NOT NULL

* access_data object
* address - list

* on insert, check for latest data, and compare hashes
* to ensure compatibility, order addresses alphabetically, then save/compare/hash

* on fetch, gather list of objects, sorted by height
* first record, all adds
* second record,
* if new address, add
* if address doesnt exist, removal


## Scraping
* ensure its a successful tx before writing records

* p8e memorialize
* will need to scrape for the fields
* will need to use the encryption stuff to decipher
```
p8EData.Scope.Owners = contractRecitalParties
p8EData.Scope.DataAccess = partyAddresses(contractRecitalParties)
p8EData.Scope.ValueOwnerAddress, err = getValueOwner(msg.Contract.Invoker, msg.Contract.Recitals)
if err != nil {
return p8EData, err
}
```

* Write Scope
* scrape for the fields

* {Add|Delete}Scope{Owner|DataAccess}
* scrape for fields
* take last set of data, update and insert into table

## API
* Fetch value owner changes
* Fetch owner changes
* Fetch data access changes

4 changes: 4 additions & 0 deletions service/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ dependencies {
api(Libraries.ApacheCommonsText)
api(Libraries.Khttp)
implementation(Libraries.KaseChange)
api(Libraries.Encryption) {
exclude("io.provenance.scope", "contract-proto")
exclude("io.provenance.protobuf", "pb-proto-java")
}

implementation(Libraries.GrpcNetty)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class AccountGrpcClient(channelUri: URI) {
it.usePlaintext()
}
}
.idleTimeout(5, TimeUnit.MINUTES)
.keepAliveTime(60, TimeUnit.SECONDS)
.keepAliveTimeout(20, TimeUnit.SECONDS)
.idleTimeout(60, TimeUnit.SECONDS)
.keepAliveTime(10, TimeUnit.SECONDS)
.keepAliveTimeout(10, TimeUnit.SECONDS)
.intercept(GrpcLoggingInterceptor())
.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ class MarkerGrpcClient(channelUri: URI, private val semaphore: Semaphore) {
it.usePlaintext()
}
}
.idleTimeout(5, TimeUnit.MINUTES)
.keepAliveTime(60, TimeUnit.SECONDS)
.keepAliveTimeout(20, TimeUnit.SECONDS)
.idleTimeout(60, TimeUnit.SECONDS)
.keepAliveTime(10, TimeUnit.SECONDS)
.keepAliveTimeout(10, TimeUnit.SECONDS)
.intercept(GrpcLoggingInterceptor())
.build()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -501,14 +501,6 @@ class AsyncCaching(
it.content.unpack(cosmwasm.wasm.v1.Proposal.StoreCodeProposal::class.java)
}
}
// translate content type
// store code -> hash wasm bytes
// -> add to retry table
// -> when future txs use same wasm bytes, link up records
// -> could also monitor proposals, if this proposal passes, check for next code id
// -> if bytes match proposal bytes, link up record as creation height

// How does a store code get created? Is it just an event? Is it tied to a block? Does a msg get dispatched?
}

fun saveSignaturesTx(tx: ServiceOuterClass.GetTxResponse) = transaction {
Expand Down

0 comments on commit 883b957

Please sign in to comment.