From a62a556ebc8562fd91b1b54961d735e1e80df14e Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 21 Nov 2019 15:47:57 +0800 Subject: [PATCH 01/21] update setting for cache port --- app/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/settings.py b/app/settings.py index 5098b7d..f1b04b2 100644 --- a/app/settings.py +++ b/app/settings.py @@ -40,7 +40,7 @@ 'default_list_cache_expiration_time': 6, 'default_detail_cache_expiration_time': 3600, 'host': os.environ.get("DOGPILE_CACHE_HOST", "redis"), - 'port': os.environ.get("DOGPILE_CACHE_HOST", 6379), + 'port': os.environ.get("DOGPILE_CACHE_PORT", 6379), 'db': os.environ.get("DOGPILE_CACHE_DB", 10) } From 2fa8298b6a2aaf668924bfffde5411aaa71e6983 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 5 Dec 2019 12:32:42 +0800 Subject: [PATCH 02/21] prochain.json --- app/type_registry/prochain.json | 100 ++++++++++++++++++++++++++++++++ start.sh | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 app/type_registry/prochain.json diff --git a/app/type_registry/prochain.json b/app/type_registry/prochain.json new file mode 100644 index 0000000..eb6c697 --- /dev/null +++ b/app/type_registry/prochain.json @@ -0,0 +1,100 @@ +{ + "default": { + "BlockNumber": "U32", + "ExternalAddress":{ + "type":"struct", + "type_mapping":[ + ["btc","Vec"], + ["eth","Vec"], + ["eos","Vec"] + ] + }, + "EventLogSource":{ + "type":"struct", + "type_mapping":[ + ["event_name","Vec"], + ["event_url","Vec"] + ] + }, + "LockedRecords":{ + "type":"struct", + "type_mapping":[ + ["locked_time", "Moment"], + ["locked_period", "Moment"], + ["locked_funds", "Balance"], + ["rewards_ratio", "u64"], + ["max_quota", "u64"] + ]}, + "UnlockRecords": { + "type":"struct", + "type_mapping": + [ + ["unlock_time", "Moment"], + ["unlock_funds", "Balance"] + ] + }, + "MetadataRecord" : { + "type":"struct", + "type_mapping": + [ + ["address", "AccountId"], + ["superior", "Hash"], + ["creator", "AccountId"], + ["did_ele", "Vec"], + ["locked_records", "Option>"], + ["unlock_records", "Option>"], + ["social_account", "Option"], + ["subordinate_count", "u64"], + ["group_name","Vec"], + ["external_address", "ExternalAddress"] + ] + }, + "Value": "u32", + "BTCValue" :{ + "type":"struct", + "type_mapping":[ + ["price","u32"], + ["block","u32"] + ] + }, + "AdsMetadata":{ + "type":"struct", + "type_mapping":[ + ["advertiser", "Vec"], + ["topic", "Vec"], + ["total_amount", "Balance"], + ["surplus", "Balance"], + ["gas_fee_used", "Balance"], + ["single_click_fee", "Balance"], + ["create_time", "Moment"], + ["period", "Moment"] + ] + }, + + "HTLC":{ + "type":"struct", + "type_mapping":[ + ["block_number","BlockNumber"], + ["out_amount","Balance"], + ["expire_height","BlockNumber"], + ["random_number_hash","Hash"], + ["swap_id","Hash"], + ["timestamp","Moment"], + ["sender_addr","Vec"], + ["sender_chain_type","u64"], + ["receiver_addr","AccountId"], + ["receiver_chain_type","u64"], + ["recipient_addr","Vec"] + ] + }, + "States" :{ + "type":"enum", + "value_list":[ + "INVALID", + "OPEN", + "COMPLETED", + "EXPIRED" + ] + } + } +} diff --git a/start.sh b/start.sh index 7df0100..6007b7d 100755 --- a/start.sh +++ b/start.sh @@ -14,7 +14,7 @@ if [ "$ENVIRONMENT" = "dev" ]; then # Expand path to local versions of packages export PYTHONPATH=$PYTHONPATH:./py-substrate-interface/:./py-scale-codec/ - gunicorn -b 0.0.0.0:8000 --workers=1 app.main:app --reload --timeout 600 + gunicorn -b 0.0.0.0:8001 --workers=1 app.main:app --reload --timeout 600 fi if [ "$ENVIRONMENT" = "prod" ]; then From 2e0f798019e89512fef35a468ed94c627896987a Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 12 Dec 2019 15:31:27 +0800 Subject: [PATCH 03/21] update --- .gitignore | 1 + app/type_registry/prochain.json | 43 +++++++++++++++++++++++++++++---- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index e671563..227cdfd 100644 --- a/.gitignore +++ b/.gitignore @@ -103,3 +103,4 @@ data/ # mypy .mypy_cache/ .idea +.history/ diff --git a/app/type_registry/prochain.json b/app/type_registry/prochain.json index eb6c697..b0f5893 100644 --- a/app/type_registry/prochain.json +++ b/app/type_registry/prochain.json @@ -1,5 +1,6 @@ { "default": { + "Keys": "SessionKeysPolkadot", "BlockNumber": "U32", "ExternalAddress":{ "type":"struct", @@ -45,7 +46,7 @@ ["unlock_records", "Option>"], ["social_account", "Option"], ["subordinate_count", "u64"], - ["group_name","Vec"], + ["group_name","Option>"], ["external_address", "ExternalAddress"] ] }, @@ -53,8 +54,8 @@ "BTCValue" :{ "type":"struct", "type_mapping":[ - ["price","u32"], - ["block","u32"] + ["block_number","BlockNumber"], + ["price","Value"] ] }, "AdsMetadata":{ @@ -70,7 +71,6 @@ ["period", "Moment"] ] }, - "HTLC":{ "type":"struct", "type_mapping":[ @@ -87,7 +87,26 @@ ["recipient_addr","Vec"] ] }, - "States" :{ + "EventHTLC":{ + "type":"struct", + "type_mapping":[ + ["eth_contract_addr","Vec"], + ["htlc_block_number","BlockNumber"], + ["event_block_number","BlockNumber"], + ["expire_height","u32"], + ["random_number_hash","Vec"], + ["swap_id","Hash"], + ["event_timestamp","u64"], + ["htlc_timestamp","u64"], + ["sender_addr","Vec"], + ["sender_chain_type","HTLCChain"], + ["receiver_addr","Vec"], + ["receiver_chain_type","HTLCChain"], + ["recipient_addr","Vec"], + ["out_amount","Balance"] + ] + }, + "HTLCStates" :{ "type":"enum", "value_list":[ "INVALID", @@ -95,6 +114,20 @@ "COMPLETED", "EXPIRED" ] + }, + "HTLCChain":{ + "type":"enum", + "value_list":[ + "ETHMain", + "PRA" + ] + }, + "ChainTypes":{ + "type":"enum", + "value_list":[ + "ETH", + "PRA" + ] } } } From 054a372209ba7aa277672a8c4bf9ac7975244489 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Fri, 13 Dec 2019 20:37:23 +0800 Subject: [PATCH 04/21] prochain --- app/type_registry/prochain.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/type_registry/prochain.json b/app/type_registry/prochain.json index b0f5893..7508e69 100644 --- a/app/type_registry/prochain.json +++ b/app/type_registry/prochain.json @@ -103,7 +103,8 @@ ["receiver_addr","Vec"], ["receiver_chain_type","HTLCChain"], ["recipient_addr","Vec"], - ["out_amount","Balance"] + ["out_amount","Balance"], + ["event_type","HTLCType"] ] }, "HTLCStates" :{ @@ -122,11 +123,12 @@ "PRA" ] }, - "ChainTypes":{ + "HTLCType":{ "type":"enum", "value_list":[ - "ETH", - "PRA" + "HTLC", + "Claimed", + "Refunded" ] } } From 2d17e7279aad6c9c9b19cbb660441c1e5d2ee9b4 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Mon, 16 Dec 2019 18:22:46 +0800 Subject: [PATCH 05/21] did transfer --- app/main.py | 1 + app/models/data.py | 21 ++++++ app/resources/base.py | 28 ++++++++ app/resources/polkascan.py | 77 ++++++++++++++++---- app/type_registry/alexander.json | 6 -- app/type_registry/darwinia.json | 112 ----------------------------- app/type_registry/edgeware.json | 114 ------------------------------ app/type_registry/joystream.json | 54 -------------- app/type_registry/kulupu.json | 5 -- app/type_registry/kusama-cc2.json | 15 ---- app/type_registry/kusama-cc3.json | 16 ----- app/type_registry/kusama.json | 16 ----- app/type_registry/plasm.json | 73 ------------------- app/type_registry/robonomics.json | 39 ---------- start.sh | 2 +- 15 files changed, 113 insertions(+), 466 deletions(-) delete mode 100644 app/type_registry/alexander.json delete mode 100644 app/type_registry/darwinia.json delete mode 100644 app/type_registry/edgeware.json delete mode 100644 app/type_registry/joystream.json delete mode 100644 app/type_registry/kulupu.json delete mode 100644 app/type_registry/kusama-cc2.json delete mode 100644 app/type_registry/kusama-cc3.json delete mode 100644 app/type_registry/kusama.json delete mode 100644 app/type_registry/plasm.json delete mode 100644 app/type_registry/robonomics.json diff --git a/app/main.py b/app/main.py index b01b9ec..9c7c7c6 100644 --- a/app/main.py +++ b/app/main.py @@ -79,6 +79,7 @@ app.add_route('/networkstats/{network_id}', polkascan.NetworkStatisticsResource()) app.add_route('/balances/transfer', polkascan.BalanceTransferListResource()) app.add_route('/balances/transfer/{item_id}', polkascan.BalanceTransferDetailResource()) +app.add_route('/transfer/{did}', polkascan.TransferListResource()) app.add_route('/account', polkascan.AccountResource()) app.add_route('/account/{item_id}', polkascan.AccountDetailResource()) app.add_route('/accountindex', polkascan.AccountIndexListResource()) diff --git a/app/models/data.py b/app/models/data.py index 4a5b38a..e3844e5 100644 --- a/app/models/data.py +++ b/app/models/data.py @@ -758,3 +758,24 @@ class RuntimeType(BaseModel): spec_version = sa.Column(sa.Integer(), nullable=False) type_string = sa.Column(sa.String(255)) decoder_class = sa.Column(sa.String(255), nullable=True) + +class Transfer(BaseModel): + __tablename__ = 'data_transfer' + + block_id = sa.Column(sa.Integer(), primary_key=True) + block = relationship(Block, foreign_keys=[block_id], primaryjoin=block_id == Block.id) + + event_idx = sa.Column(sa.Integer(), primary_key=True) + + extrinsic_idx = sa.Column(sa.Integer()) + from_did = sa.Column(sa.String(44),index = True) + from_account_id = sa.Column(sa.String(64),index=True) + to_did = sa.Column(sa.String(44),index = True) + to_account_id = sa.Column(sa.String(64),index=True) + balance = sa.Column(sa.Numeric(precision=65, scale=0), nullable=False) + fee = sa.Column(sa.Numeric(precision=18, scale=0), nullable=False) + datetime = sa.Column(sa.DateTime(timezone=True)) + + + def serialize_id(self): + return '{}-{}'.format(self.block_id, self.event_idx) \ No newline at end of file diff --git a/app/resources/base.py b/app/resources/base.py index 768572d..dd5a2ad 100644 --- a/app/resources/base.py +++ b/app/resources/base.py @@ -145,7 +145,35 @@ def process_get_response(self, req, resp, **kwargs): 'cacheable': True } +class JSONAPIListResource2(JSONAPIResource, ABC): + cache_expiration_time = DOGPILE_CACHE_SETTINGS['default_list_cache_expiration_time'] + + def get_item_url_name(self): + return 'item_id' + + @abstractmethod + def get_query(self,item_id): + raise NotImplementedError() + + def apply_paging(self, query, params): + page = int(params.get('page[number]', 1)) - 1 + page_size = min(int(params.get('page[size]', 25)), MAX_RESOURCE_PAGE_SIZE) + return query[page * page_size: page * page_size + page_size] + + def process_get_response(self, req, resp, **kwargs): + items = self.get_query(kwargs.get(self.get_item_url_name())) + items = self.apply_filters(items, req.params) + items = self.apply_paging(items, req.params) + + return { + 'status': falcon.HTTP_200, + 'media': self.get_jsonapi_response( + data=[self.serialize_item(item) for item in items], + meta=self.get_meta() + ), + 'cacheable': True + } class JSONAPIDetailResource(JSONAPIResource, ABC): cache_expiration_time = DOGPILE_CACHE_SETTINGS['default_detail_cache_expiration_time'] diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 89a7472..4703876 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -21,17 +21,20 @@ import falcon from dogpile.cache.api import NO_VALUE from sqlalchemy import func - +from sqlalchemy import or_ from app.models.data import Block, Extrinsic, Event, RuntimeCall, RuntimeEvent, Runtime, RuntimeModule, \ RuntimeCallParam, RuntimeEventAttribute, RuntimeType, RuntimeStorage, Account, Session, DemocracyProposal, Contract, \ BlockTotal, SessionValidator, Log, DemocracyReferendum, AccountIndex, RuntimeConstant, SessionNominator, \ - DemocracyVote -from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIDetailResource + DemocracyVote, Transfer +from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIDetailResource,JSONAPIListResource2 from app.settings import SUBSTRATE_RPC_URL, SUBSTRATE_METADATA_VERSION, SUBSTRATE_ADDRESS_TYPE, TYPE_REGISTRY from app.type_registry import load_type_registry from app.utils.ss58 import ss58_decode, ss58_encode from scalecodec.base import RuntimeConfiguration from substrateinterface import SubstrateInterface +import json +import decimal +import datetime class BlockDetailsResource(JSONAPIDetailResource): @@ -114,7 +117,8 @@ def apply_filters(self, query, params): if len(params.get('filter[address]')) == 64: account_id = params.get('filter[address]') else: - account_id = ss58_decode(params.get('filter[address]'), SUBSTRATE_ADDRESS_TYPE) + account_id = ss58_decode(params.get( + 'filter[address]'), SUBSTRATE_ADDRESS_TYPE) query = query.filter_by(address=account_id) @@ -129,7 +133,8 @@ def get_item_url_name(self): def get_item(self, item_id): if item_id[0:2] == '0x': - extrinsic = Extrinsic.query(self.session).filter_by(extrinsic_hash=item_id[2:]).first() + extrinsic = Extrinsic.query(self.session).filter_by( + extrinsic_hash=item_id[2:]).first() else: extrinsic = Extrinsic.query(self.session).get(item_id.split('-')) @@ -194,7 +199,8 @@ def on_get(self, req, resp, network_id=None): if response is NO_VALUE: - best_block = BlockTotal.query(self.session).filter_by(id=self.session.query(func.max(BlockTotal.id)).one()[0]).first() + best_block = BlockTotal.query(self.session).filter_by( + id=self.session.query(func.max(BlockTotal.id)).one()[0]).first() if best_block: response = self.get_jsonapi_response( data={ @@ -281,6 +287,39 @@ def serialize_item(self, item): } +class TransferListResource(JSONAPIListResource2): + + def get_item_url_name(self): + return 'did' + + def get_query(self,did): + return Transfer.query(self.session).filter(or_(Transfer.from_did == did,Transfer.to_did == did)).order_by(Transfer.block_id.desc()) + + def serialize_item(self, item): + return { + 'type': 'transfer', + 'id': '{}-{}'.format(item.block_id, item.event_idx), + 'attributes': { + 'block_id': item.block_id, + 'event_idx': item.event_idx, + 'extrinsic_idx': item.extrinsic_idx, + 'from_account_id': item.from_account_id, + 'from_address': ss58_encode(item.from_account_id, SUBSTRATE_ADDRESS_TYPE), + 'to_account_id': item.to_account_id, + 'to_address': ss58_encode(item.to_account_id, SUBSTRATE_ADDRESS_TYPE), + 'balance': float(item.balance), + 'from_did': item.from_did, + 'to_did': item.to_did, + 'fee': float(item.fee), + 'datetime': item.datetime.isoformat() + } + } + +def decimal_default_proc(obj): + if isinstance(obj, decimal.Decimal): + return float(obj) + raise TypeError + class AccountResource(JSONAPIListResource): def get_query(self): @@ -316,7 +355,8 @@ def get_relationships(self, include_list, item): return relationships def serialize_item(self, item): - substrate = SubstrateInterface(SUBSTRATE_RPC_URL, metadata_version=SUBSTRATE_METADATA_VERSION) + substrate = SubstrateInterface( + SUBSTRATE_RPC_URL, metadata_version=SUBSTRATE_METADATA_VERSION) data = item.serialize() storage_call = RuntimeStorage.query(self.session).filter_by( @@ -434,7 +474,8 @@ def apply_filters(self, query, params): if params.get('filter[latestSession]'): - session = Session.query(self.session).order_by(Session.id.desc()).first() + session = Session.query(self.session).order_by( + Session.id.desc()).first() query = query.filter_by(session_id=session.id) @@ -474,7 +515,8 @@ def apply_filters(self, query, params): if params.get('filter[latestSession]'): - session = Session.query(self.session).order_by(Session.id.desc()).first() + session = Session.query(self.session).order_by( + Session.id.desc()).first() query = query.filter_by(session_id=session.id) @@ -574,7 +616,8 @@ def apply_filters(self, query, params): if params.get('filter[latestRuntime]'): - latest_runtime = Runtime.query(self.session).order_by(Runtime.spec_version.desc()).first() + latest_runtime = Runtime.query(self.session).order_by( + Runtime.spec_version.desc()).first() query = query.filter_by(spec_version=latest_runtime.spec_version) @@ -625,7 +668,8 @@ def apply_filters(self, query, params): if params.get('filter[latestRuntime]'): - latest_runtime = Runtime.query(self.session).order_by(Runtime.spec_version.desc()).first() + latest_runtime = Runtime.query(self.session).order_by( + Runtime.spec_version.desc()).first() query = query.filter_by(spec_version=latest_runtime.spec_version) @@ -681,7 +725,8 @@ def apply_filters(self, query, params): if params.get('filter[latestRuntime]'): - latest_runtime = Runtime.query(self.session).order_by(Runtime.spec_version.desc()).first() + latest_runtime = Runtime.query(self.session).order_by( + Runtime.spec_version.desc()).first() query = query.filter_by(spec_version=latest_runtime.spec_version) @@ -701,7 +746,8 @@ def apply_filters(self, query, params): if params.get('filter[latestRuntime]'): - latest_runtime = Runtime.query(self.session).order_by(Runtime.spec_version.desc()).first() + latest_runtime = Runtime.query(self.session).order_by( + Runtime.spec_version.desc()).first() query = query.filter_by(spec_version=latest_runtime.spec_version) @@ -757,7 +803,8 @@ class RuntimeConstantListResource(JSONAPIListResource): def get_query(self): return RuntimeConstant.query(self.session).order_by( - RuntimeConstant.spec_version.desc(), RuntimeConstant.module_id.asc(), RuntimeConstant.name.asc() + RuntimeConstant.spec_version.desc( + ), RuntimeConstant.module_id.asc(), RuntimeConstant.name.asc() ) @@ -769,4 +816,4 @@ def get_item(self, item_id): spec_version=spec_version, module_id=module_id, name=name - ).first() + ).first() \ No newline at end of file diff --git a/app/type_registry/alexander.json b/app/type_registry/alexander.json deleted file mode 100644 index dbc09ad..0000000 --- a/app/type_registry/alexander.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "default": { - "ValidatorPrefs": "ValidatorPrefsLegacy", - "Index": "U64" - } -} diff --git a/app/type_registry/darwinia.json b/app/type_registry/darwinia.json deleted file mode 100644 index 86b40f6..0000000 --- a/app/type_registry/darwinia.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "default": { - "EpochDuration": "u64", - "EraIndex": "u32", - "Index": "U64", - "RingBalanceOf": "u128", - "KtonBalanceOf": "u128", - "ExtendedBalance": "u128", - "Keys": { - "type": "struct", - "type_mapping": [ - ["grandpa", "AccountId"], - ["babe", "AccountId"] - ] - }, - "ValidatorPrefs": "ValidatorPrefsLegacy", - "StakingBalance": { - "type": "enum", - "type_mapping": [ - ["Ring", "RingBalanceOf"], - ["Kton", "KtonBalanceOf"] - ] - }, - "TimeDepositItem": { - "type": "struct", - "type_mapping": [ - ["value", "Compact"], - ["start_time", "Compact"], - ["expire_time", "Compact"] - ] - }, - "UnlockChunk": { - "type": "struct", - "type_mapping": [ - ["value", "StakingBalance"], - ["era", "Compact"], - ["is_time_deposit", "bool"] - ] - }, - "StakingLedgers": { - "type": "struct", - "type_mapping": [ - ["stash", "AccountId"], - ["total_ring", "Compact"], - ["total_deposit_ring", "Compact"], - ["active_ring", "Compact"], - ["active_deposit_ring", "Compact"], - ["total_kton", "Compact"], - ["active_kton", "Compact"], - ["deposit_items", "Vec"], - ["unlocking", "Vec"] - ] - }, - "IndividualExpo": { - "type": "struct", - "type_mapping": [ - ["who", "AccountId"], - ["value", "ExtendedBalance"] - ] - }, - "Exposures": { - "type": "struct", - "type_mapping": [ - ["total", "ExtendedBalance"], - ["own", "ExtendedBalance"], - ["others", "Vec"] - ] - }, - "TokenBalance": "u128", - "Currency": "u128", - "CurrencyOf": "u128", - "Auction": { - "type": "struct", - "type_mapping": [ - ["seller", "AccountId"], - ["startAt", "Moment"], - ["duration", "u64"], - ["startingPrice", "TokenBalance"], - ["endingPrice", "TokenBalance"], - ["lastRecord", "TokenBalance"], - ["lastBidder", "AccountId"], - ["lastBidStartAt", "Moment"] - ] - }, - "DepositInfo": { - "type": "struct", - "type_mapping": [ - ["month", "Moment"], - ["start_at", "Moment"], - ["value", "CurrencyOf"], - ["unit_interest", "u64"], - ["claimed", "bool"] - ] - }, - "Deposit": { - "type": "struct", - "type_mapping": [ - ["total_deposit", "CurrencyOf"], - ["deposit_list", "Vec"] - ] - }, - "Revenue": { - "type": "struct", - "type_mapping": [ - ["team", "TokenBalance"], - ["contribution", "TokenBalance"], - ["ktoner", "TokenBalance"], - ["lottery", "TokenBalance"] - ] - } - } -} diff --git a/app/type_registry/edgeware.json b/app/type_registry/edgeware.json deleted file mode 100644 index 8413291..0000000 --- a/app/type_registry/edgeware.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "default": { - "Keys": "SessionKeysSubstrate", - "BlockNumber": "U32", - "SessionIndex": "U32", - "AuctionIndex": "U32", - "AuthIndex": "U32", - "BalanceUpload": "(AccountId, u64)", - "EgressQueueRoot": "(ParaId, Hash)", - "EventIndex": "u32", - "LeasePeriodOf": "LeasePeriod", - "LeasePeriod": "BlockNumber", - "MemberCount": "u32", - "MomentOf": "Moment", - "Offender": "(ValidatorId, Exposure)", - "ReportIdOf": "Hash", - "SubId": "u32", - "Weight": "u32", - "WeightMultiplier": "u64", - "WinningData": "Vec", - "Index": "U32", - "Kind": "[u8; 16]", - "OpaqueTimeSlot": "Bytes", - "::Signature": "AuthoritySignature", - "Box<>::Proposal>": "BoxProposal", - "Forcing": { - "type": "enum", - "value_list": [ - "NotForcing", - "ForceNew", - "ForceNone" - ] - }, - "VoteData": { - "type": "struct", - "type_mapping": [ - ["initiator", "AccountId"], - ["stage", "VoteStage"], - ["vote_type", "VoteType"], - ["tally_type", "TallyType"], - ["is_commit_reveal", "Bool"] - ] - }, - "VoteRecord": { - "type": "struct", - "type_mapping": [ - ["id", "u64"], - ["commitments", "Vec<(AccountId, VoteOutcome)>"], - ["reveals", "Vec<(AccountId, VoteOutcome)>"], - ["data", "VoteData"], - ["outcomes", "Vec<(VoteOutcome)>"] - ] - }, - "VoteType": { - "type": "enum", - "value_list": ["Binary", "MultiOption"] - }, - "IdentityStage": { - "type": "enum", - "value_list": ["Registered", "Attested", "Verified"] - }, - "IdentityRecord": { - "type": "struct", - "type_mapping": [ - ["account", "AccountId"], - ["identity_type", "String"], - ["identity", "Bytes"], - ["stage", "IdentityStage"], - ["expiration_time", "BlockNumber"], - ["proof", "Bytes"], - ["metadata", "Bytes"] - ] - }, - "MetadataRecord": { - "type": "struct", - "type_mapping": [ - ["avatar", "String"], - ["display_name", "String"], - ["tagline", "String"] - ] - }, - "ProposalCategory": { - "type": "enum", - "value_list": ["Signaling"] - }, - "ProposalStage": { - "type": "enum", - "value_list": ["PreVoting", "Voting", "Completed"] - }, - "ProposalRecord": { - "type": "struct", - "type_mapping": [ - ["index", "u32"], - ["author", "AccountId"], - ["stage", "ProposalStage"], - ["transition_time", "BlockNumber"], - ["category", "ProposalCategory"], - ["title", "Vec"], - ["contents", "Vec"], - ["vote_id", "u64"], - ["ProposalTitle", "Vec"], - ["ProposalContents", "Vec"] - ] - }, - "Balance2": "Balance", - "DispatchError": { - "type": "struct", - "type_mapping": [ - ["module", "Option"], - ["error", "u8"] - ] - } - } -} diff --git a/app/type_registry/joystream.json b/app/type_registry/joystream.json deleted file mode 100644 index 529dd14..0000000 --- a/app/type_registry/joystream.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "default": { - "ValidatorPrefs": "ValidatorPrefsLegacy", - "Index": "U64", - "::ContentId": "ContentId", - "RoleParameters": { - "type": "struct", - "type_mapping": [ - ["min_stake", "BalanceOf"], - ["min_actors", "u32"], - ["max_actors", "u32"], - ["reward", "BalanceOf"], - ["reward_period", "BlockNumber"], - ["bonding_period", "BlockNumber"], - ["unbonding_period", "BlockNumber"], - ["min_service_period", "BlockNumber"], - ["startup_grace_period", "BlockNumber"], - ["entry_request_fee", "BalanceOf"] - ] - }, - "Actor": { - "type": "struct", - "type_mapping": [ - ["member_id", "MemberId"], - ["role", "Role"], - ["account", "AccountId"], - ["joined_at", "BlockNumber"] - ] - }, - "DataObjectStorageRelationship": { - "type": "struct", - "type_mapping": [ - ["content_id", "ContentId"], - ["storage_provider", "AccountId"], - ["ready", "bool"] - ] - }, - "DataObjectType": { - "type": "struct", - "type_mapping": [ - ["description", "Vec"], - ["active", "bool"] - ] - }, - "UserInfo": { - "type": "struct", - "type_mapping": [ - ["handle", "Option>"], - ["avatar_uri", "Option>"], - ["about", "Option>"] - ] - } - } -} diff --git a/app/type_registry/kulupu.json b/app/type_registry/kulupu.json deleted file mode 100644 index abb881f..0000000 --- a/app/type_registry/kulupu.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "default": { - "Weight": "u16" - } -} diff --git a/app/type_registry/kusama-cc2.json b/app/type_registry/kusama-cc2.json deleted file mode 100644 index 10ba8d9..0000000 --- a/app/type_registry/kusama-cc2.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "default": { - "BlockNumber": "U32", - "SessionKeysPolkadot": { - "type": "struct", - "type_mapping": [ - ["grandpa", "AccountId"], - ["babe", "AccountId"], - ["im_online", "AccountId"], - ["parachains", "AccountId"] - ] - }, - "Keys": "SessionKeysPolkadot" - } -} diff --git a/app/type_registry/kusama-cc3.json b/app/type_registry/kusama-cc3.json deleted file mode 100644 index 4de213f..0000000 --- a/app/type_registry/kusama-cc3.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "default": { - "BlockNumber": "U32", - "SessionKeysPolkadot": { - "type": "struct", - "type_mapping": [ - ["grandpa", "AccountId"], - ["babe", "AccountId"], - ["im_online", "AccountId"], - ["authority_discovery", "AccountId"], - ["parachains", "AccountId"] - ] - }, - "Keys": "SessionKeysPolkadot" - } -} diff --git a/app/type_registry/kusama.json b/app/type_registry/kusama.json deleted file mode 100644 index 4de213f..0000000 --- a/app/type_registry/kusama.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "default": { - "BlockNumber": "U32", - "SessionKeysPolkadot": { - "type": "struct", - "type_mapping": [ - ["grandpa", "AccountId"], - ["babe", "AccountId"], - ["im_online", "AccountId"], - ["authority_discovery", "AccountId"], - ["parachains", "AccountId"] - ] - }, - "Keys": "SessionKeysPolkadot" - } -} diff --git a/app/type_registry/plasm.json b/app/type_registry/plasm.json deleted file mode 100644 index a99f49b..0000000 --- a/app/type_registry/plasm.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "default": { - "Keys": "SessionKeysSubstrate", - "Index": "U32", - "BlockNumber": "U32", - "Range": { - "type": "struct", - "type_mapping": [ - ["start", "u128"], - ["end", "u128"] - ] - }, - "StateObject": { - "type": "struct", - "type_mapping": [ - ["predicate", "AccountId"], - ["data", "Vec"] - ] - }, - "StateUpdate": { - "type": "struct", - "type_mapping": [ - ["range", "Range"], - ["state_object", "StateObject"], - ["plasma_block_number", "BlockNumber"] - ] - }, - "Checkpoint": { - "type": "struct", - "type_mapping": [ - ["state_update", "StateUpdate"], - ["sub_range", "Range"] - ] - }, - "Transaction": { - "type": "struct", - "type_mapping": [ - ["predicate", "AccountId"], - ["range", "Range"], - ["body", "Range"] - ] - }, - "TransactionBody": { - "type": "struct", - "type_mapping": [ - ["new_state", "StateObject"], - ["origin_block", "BlockNumber"], - ["max_block", "BlockNumber"] - ] - }, - "Challenge": { - "type": "struct", - "type_mapping": [ - ["challenged_checkpoint", "Checkpoint"], - ["challenging_checkpoint", "Checkpoint"] - ] - }, - "MerkleIntervalTreeInternalNode": { - "type": "struct", - "type_mapping": [ - ["index", "Index"], - ["hash", "Hash"] - ] - }, - "InclusionProof": { - "type": "struct", - "type_mapping": [ - ["proofs", "Vec"], - ["idx", "u128"] - ] - } - } -} diff --git a/app/type_registry/robonomics.json b/app/type_registry/robonomics.json deleted file mode 100644 index ae0c87e..0000000 --- a/app/type_registry/robonomics.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "default": { - "Keys": "SessionKeysSubstrate", - "Index": "U64", - "LiabilityIndex": "U64", - "Order": { - "type": "struct", - "type_mapping": [ - ["models", "Vec"], - ["objective", "Vec"], - ["cost", "Balance"], - ["custodian", "Option"] - ] - }, - "Offer": { - "type": "struct", - "type_mapping": [ - ["order", "Order"], - ["sender", "AccountId"] - ] - }, - "Demand": { - "type": "struct", - "type_mapping": [ - ["order", "Order"], - ["sender", "AccountId"] - ] - }, - "Liability": { - "type": "struct", - "type_mapping": [ - ["order", "Order"], - ["promisee", "AccountId"], - ["promisor", "AccountId"], - ["result", "Option>"] - ] - } - } -} diff --git a/start.sh b/start.sh index 6007b7d..dfb9c98 100755 --- a/start.sh +++ b/start.sh @@ -7,7 +7,7 @@ fi echo "===========================" echo "Environment: $ENVIRONMENT" echo "===========================" - +export PYTHONPATH=$PYTHONPATH:./py-substrate-interface/:./py-scale-codec/ echo "Running gunicorn..." if [ "$ENVIRONMENT" = "dev" ]; then From 35b7d197e8d453367c00727448048419d9101746 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Mon, 16 Dec 2019 18:27:17 +0800 Subject: [PATCH 06/21] sh --- start.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/start.sh b/start.sh index dfb9c98..a4790e0 100755 --- a/start.sh +++ b/start.sh @@ -12,9 +12,7 @@ echo "Running gunicorn..." if [ "$ENVIRONMENT" = "dev" ]; then # Expand path to local versions of packages - export PYTHONPATH=$PYTHONPATH:./py-substrate-interface/:./py-scale-codec/ - - gunicorn -b 0.0.0.0:8001 --workers=1 app.main:app --reload --timeout 600 + gunicorn -b 0.0.0.0:8000 --workers=1 app.main:app --reload --timeout 600 fi if [ "$ENVIRONMENT" = "prod" ]; then From 35963549bad206d2ffa21c38c5bc3628adefc8e1 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Tue, 17 Dec 2019 19:05:43 +0800 Subject: [PATCH 07/21] did api --- app/main.py | 2 ++ app/models/data.py | 14 +++++++++++++- app/resources/polkascan.py | 12 +++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/main.py b/app/main.py index 9c7c7c6..e94ef4f 100644 --- a/app/main.py +++ b/app/main.py @@ -80,6 +80,8 @@ app.add_route('/balances/transfer', polkascan.BalanceTransferListResource()) app.add_route('/balances/transfer/{item_id}', polkascan.BalanceTransferDetailResource()) app.add_route('/transfer/{did}', polkascan.TransferListResource()) +app.add_route('/did', polkascan.DidListResource()) +app.add_route('/did/{item_id}', polkascan.DidDetailResource()) app.add_route('/account', polkascan.AccountResource()) app.add_route('/account/{item_id}', polkascan.AccountDetailResource()) app.add_route('/accountindex', polkascan.AccountIndexListResource()) diff --git a/app/models/data.py b/app/models/data.py index e3844e5..6e07086 100644 --- a/app/models/data.py +++ b/app/models/data.py @@ -778,4 +778,16 @@ class Transfer(BaseModel): def serialize_id(self): - return '{}-{}'.format(self.block_id, self.event_idx) \ No newline at end of file + return '{}-{}'.format(self.block_id, self.event_idx) + +class Did(BaseModel): + __tablename__ = 'data_did' + + did = sa.Column(sa.String(50), primary_key=True) + address = sa.Column(sa.String(48),index=True) + superior = sa.Column(sa.String(66),index=True) + did_hash = sa.Column(sa.String(66),index=True) + creator = sa.Column(sa.String(50)) + social_account_hash = sa.Column(sa.String(66),index =True) + def serialize_id(self): + return self.did \ No newline at end of file diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 4703876..53ea66e 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -25,7 +25,7 @@ from app.models.data import Block, Extrinsic, Event, RuntimeCall, RuntimeEvent, Runtime, RuntimeModule, \ RuntimeCallParam, RuntimeEventAttribute, RuntimeType, RuntimeStorage, Account, Session, DemocracyProposal, Contract, \ BlockTotal, SessionValidator, Log, DemocracyReferendum, AccountIndex, RuntimeConstant, SessionNominator, \ - DemocracyVote, Transfer + DemocracyVote, Transfer, Did from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIDetailResource,JSONAPIListResource2 from app.settings import SUBSTRATE_RPC_URL, SUBSTRATE_METADATA_VERSION, SUBSTRATE_ADDRESS_TYPE, TYPE_REGISTRY from app.type_registry import load_type_registry @@ -320,6 +320,16 @@ def decimal_default_proc(obj): return float(obj) raise TypeError +class DidListResource(JSONAPIListResource): + def get_query(self): + return Did.query(self.session) + +class DidDetailResource(JSONAPIDetailResource): + def get_item(self, item_id): + print(item_id) + return Did.query(self.session).get(item_id).first() + + class AccountResource(JSONAPIListResource): def get_query(self): From 5d585dea90afb2ac004ce697d7b5002aee5df3b8 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 2 Jan 2020 21:24:15 +0800 Subject: [PATCH 08/21] merge --- app/resources/polkascan.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 9b906c4..5aa5541 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -26,7 +26,7 @@ RuntimeCallParam, RuntimeEventAttribute, RuntimeType, RuntimeStorage, Account, Session, DemocracyProposal, Contract, \ BlockTotal, SessionValidator, Log, DemocracyReferendum, AccountIndex, RuntimeConstant, SessionNominator, \ DemocracyVote, CouncilMotion, CouncilVote, TechCommProposal, TechCommProposalVote, TreasuryProposal, Transfer, Did -from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIDetailResource +from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIListResource2,JSONAPIDetailResource from app.settings import SUBSTRATE_RPC_URL, SUBSTRATE_METADATA_VERSION, SUBSTRATE_ADDRESS_TYPE, TYPE_REGISTRY from app.type_registry import load_type_registry from app.utils.ss58 import ss58_decode, ss58_encode From 4adaddc91bb53584bdc461f5eaa690845ab958bf Mon Sep 17 00:00:00 2001 From: haoming06 Date: Mon, 6 Jan 2020 16:10:19 +0800 Subject: [PATCH 09/21] merge --- app/type_registry/prochain.json | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/app/type_registry/prochain.json b/app/type_registry/prochain.json index 7508e69..ce41553 100644 --- a/app/type_registry/prochain.json +++ b/app/type_registry/prochain.json @@ -1,7 +1,9 @@ { "default": { + "Did":"Vec", "Keys": "SessionKeysPolkadot", "BlockNumber": "U32", + "Index": "U64", "ExternalAddress":{ "type":"struct", "type_mapping":[ @@ -26,7 +28,7 @@ ["rewards_ratio", "u64"], ["max_quota", "u64"] ]}, - "UnlockRecords": { + "UnlockedRecords": { "type":"struct", "type_mapping": [ @@ -41,9 +43,9 @@ ["address", "AccountId"], ["superior", "Hash"], ["creator", "AccountId"], - ["did_ele", "Vec"], + ["did", "Did"], ["locked_records", "Option>"], - ["unlock_records", "Option>"], + ["unlock_records", "Option>"], ["social_account", "Option"], ["subordinate_count", "u64"], ["group_name","Option>"], @@ -71,22 +73,6 @@ ["period", "Moment"] ] }, - "HTLC":{ - "type":"struct", - "type_mapping":[ - ["block_number","BlockNumber"], - ["out_amount","Balance"], - ["expire_height","BlockNumber"], - ["random_number_hash","Hash"], - ["swap_id","Hash"], - ["timestamp","Moment"], - ["sender_addr","Vec"], - ["sender_chain_type","u64"], - ["receiver_addr","AccountId"], - ["receiver_chain_type","u64"], - ["recipient_addr","Vec"] - ] - }, "EventHTLC":{ "type":"struct", "type_mapping":[ From fb480747180d86684187fc39ecdcd367aa292f90 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Fri, 17 Jan 2020 20:03:16 +0800 Subject: [PATCH 10/21] did --- app/resources/polkascan.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 5aa5541..28177f0 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -352,8 +352,10 @@ def get_query(self): class DidDetailResource(JSONAPIDetailResource): def get_item(self, item_id): - print(item_id) - return Did.query(self.session).get(item_id).first() + if item_id and item_id.startswith('0x'): + return Did.query(self.session).filter_by(did_hash=item_id[2:]).first() + else: + return Did.query(self.session).get(item_id) class AccountResource(JSONAPIListResource): From ae8edb30f34a29605dd696088ddde107ed9b17b3 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Fri, 17 Jan 2020 21:10:33 +0800 Subject: [PATCH 11/21] git module --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 09dcc72..9e0684b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/polkascan/py-substrate-interface.git [submodule "py-scale-codec"] path = py-scale-codec - url = https://github.com/polkascan/py-scale-codec.git + url = https://github.com/ProChain/py-scale-codec.git From abab2d7fddc64d528327a4d6a11d2db886d80e93 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Fri, 17 Jan 2020 21:18:04 +0800 Subject: [PATCH 12/21] requirements --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7e915ae..6531333 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,5 +36,6 @@ urllib3==1.25.3 xxhash==1.4.1 zipp==0.5.2 -git+https://github.com/polkascan/py-scale-codec.git@master#egg=scalecodec +git+https://github.com/ProChain/py-scale-codec.git@master#egg=scalecodec git+https://github.com/polkascan/py-substrate-interface.git@master#egg=substrateinterface + From a486bd577c8b98031b480723521be93289ae8c6e Mon Sep 17 00:00:00 2001 From: haoming06 Date: Mon, 3 Feb 2020 15:08:28 +0800 Subject: [PATCH 13/21] did --- app/resources/base.py | 37 +++++++++++++++++++++++++++++++------ app/resources/polkascan.py | 25 ++++++++++++++++++++----- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/app/resources/base.py b/app/resources/base.py index dd5a2ad..e1c27f7 100644 --- a/app/resources/base.py +++ b/app/resources/base.py @@ -25,7 +25,7 @@ from sqlalchemy.orm import Session from app.settings import MAX_RESOURCE_PAGE_SIZE, DOGPILE_CACHE_SETTINGS - +from app.models.data import Did class BaseResource(object): @@ -46,6 +46,33 @@ def get_meta(self): def serialize_item(self, item): return item.serialize() + #["address","address2"] + def convert_to_did_items(self): + return [] + + def convert_to_did(self,data): + items = self.convert_to_did_items() + if items and len(items)>0: + if isinstance(data,list): + address = [] + for row in data: + for item in items: + address.append(row['attributes'][item]) + alldid = Did.query(self.session).filter(Did.address.in_(address)).all() + did_map = dict([(did.address,did.did) for did in alldid]) + for row in data: + for item in items: + if row['attributes'][item] in did_map: + row['attributes'][item+'_source'] = row['attributes'][item] + row['attributes'][item] = did_map[row['attributes'][item]] + else: + for item in items: + did = Did.query(self.session).filter_by(address=data['attributes'][item]).first() + if did: + data['attributes'][item+'_source'] = data['attributes'][item] + data['attributes'][item] = did.did + return data + def process_get_response(self, req, resp, **kwargs): return { 'status': falcon.HTTP_200, @@ -54,7 +81,7 @@ def process_get_response(self, req, resp, **kwargs): } def get_jsonapi_response(self, data, meta=None, errors=None, links=None, relationships=None, included=None): - + data = self.convert_to_did(data) result = { 'meta': { "authors": [ @@ -67,7 +94,6 @@ def get_jsonapi_response(self, data, meta=None, errors=None, links=None, relatio "data": data, "links": {} } - if meta: result['meta'].update(meta) @@ -135,7 +161,6 @@ def process_get_response(self, req, resp, **kwargs): items = self.get_query() items = self.apply_filters(items, req.params) items = self.apply_paging(items, req.params) - return { 'status': falcon.HTTP_200, 'media': self.get_jsonapi_response( @@ -169,7 +194,7 @@ def process_get_response(self, req, resp, **kwargs): return { 'status': falcon.HTTP_200, 'media': self.get_jsonapi_response( - data=[self.serialize_item(item) for item in items], + data= [self.serialize_item(item) for item in items], meta=self.get_meta() ), 'cacheable': True @@ -203,7 +228,7 @@ def process_get_response(self, req, resp, **kwargs): response = { 'status': falcon.HTTP_200, 'media': self.get_jsonapi_response( - data=self.serialize_item(item), + data= self.serialize_item(item), relationships=self.get_relationships(req.params.get('include') or [], item), meta=self.get_meta() ), diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 11a58ac..728f576 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -123,7 +123,9 @@ def apply_filters(self, query, params): query = query.filter_by(address=account_id) return query - + + def convert_to_did_items(self): + return ["address"] class ExtrinsicDetailResource(JSONAPIDetailResource): @@ -153,7 +155,8 @@ def serialize_item(self, item): return data - + def convert_to_did_items(self): + return ["address"] class EventsListResource(JSONAPIListResource): def apply_filters(self, query, params): @@ -289,7 +292,9 @@ def serialize_item(self, item): 'fee': item.attributes[3]['value'] } } - + def convert_to_did_items(self): + return ['sender','destination'] + class BalanceTransferDetailResource(JSONAPIDetailResource): @@ -312,6 +317,8 @@ def serialize_item(self, item): } } + def convert_to_did_items(self): + return ['sender','destination'] class TransferListResource(JSONAPIListResource2): @@ -365,7 +372,8 @@ def get_query(self): Account.updated_at_block.desc() ) - + def convert_to_did_items(self): + return ['address'] class AccountDetailResource(JSONAPIDetailResource): cache_expiration_time = 6 @@ -379,9 +387,14 @@ def __init__(self): def get_item(self, item_id): if item_id[0:2] == '0x': return Account.query(self.session).filter_by(id=item_id[2:]).first() + elif item_id[0:3] == 'did': + did = Did.query(self.session).filter_by(did=item_id).first() + return Account.query(self.session).filter_by(address = did.address).first() else: return Account.query(self.session).filter_by(address=item_id).first() - + def convert_to_did_items(self): + return ['address'] + def get_relationships(self, include_list, item): relationships = {} @@ -455,6 +468,8 @@ def get_query(self): AccountIndex.updated_at_block.desc() ) + def convert_to_did_items(self): + return ['address'] class AccountIndexDetailResource(JSONAPIDetailResource): From e16f5ef351dfcd008aa782c639c86b4ca76a6c04 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Mon, 3 Feb 2020 15:43:22 +0800 Subject: [PATCH 14/21] fix did --- app/resources/polkascan.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 728f576..68c9ede 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -116,6 +116,11 @@ def apply_filters(self, query, params): if params.get('filter[address]')[0:2] == '0x': account_id = params.get('filter[address]')[2:] + elif params.get('filter[address]')[0:3] == 'did': + did = Did.query(self.session).filter_by(did=params.get('filter[address]')).first() + account = Account.query(self.session).filter_by(address = did.address).first() + if account: + account_id = account.id else: account_id = ss58_decode(params.get( 'filter[address]'), SUBSTRATE_ADDRESS_TYPE) From ebf0da4cda2e4e146a5c8ea216e1805bbaaea15b Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 6 Feb 2020 12:13:23 +0800 Subject: [PATCH 15/21] fix --- app/resources/polkascan.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 68c9ede..2f948e5 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -118,9 +118,7 @@ def apply_filters(self, query, params): account_id = params.get('filter[address]')[2:] elif params.get('filter[address]')[0:3] == 'did': did = Did.query(self.session).filter_by(did=params.get('filter[address]')).first() - account = Account.query(self.session).filter_by(address = did.address).first() - if account: - account_id = account.id + account_id = ss58_decode(did.address, SUBSTRATE_ADDRESS_TYPE) else: account_id = ss58_decode(params.get( 'filter[address]'), SUBSTRATE_ADDRESS_TYPE) From 3ae0018f986d7020af7a1d40deef979f12b5a5d7 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Sat, 8 Feb 2020 17:15:20 +0800 Subject: [PATCH 16/21] did members --- app/main.py | 1 + app/resources/base.py | 35 ++++++++++++++++++++++++++--------- app/resources/polkascan.py | 9 ++++++++- 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/app/main.py b/app/main.py index e3ac6e4..c983ddf 100644 --- a/app/main.py +++ b/app/main.py @@ -82,6 +82,7 @@ app.add_route('/transfer/{did}', polkascan.TransferListResource()) app.add_route('/did', polkascan.DidListResource()) app.add_route('/did/{item_id}', polkascan.DidDetailResource()) +app.add_route('/did/members/{did_hash}', polkascan.DidMembersResource()) app.add_route('/account', polkascan.AccountResource()) app.add_route('/account/{item_id}', polkascan.AccountDetailResource()) app.add_route('/accountindex', polkascan.AccountIndexListResource()) diff --git a/app/resources/base.py b/app/resources/base.py index e1c27f7..200cc99 100644 --- a/app/resources/base.py +++ b/app/resources/base.py @@ -186,19 +186,36 @@ def apply_paging(self, query, params): page_size = min(int(params.get('page[size]', 25)), MAX_RESOURCE_PAGE_SIZE) return query[page * page_size: page * page_size + page_size] + def has_total(self): + return False + def process_get_response(self, req, resp, **kwargs): items = self.get_query(kwargs.get(self.get_item_url_name())) items = self.apply_filters(items, req.params) + total = -1 + if self.has_total(): + total = items.count() items = self.apply_paging(items, req.params) - - return { - 'status': falcon.HTTP_200, - 'media': self.get_jsonapi_response( - data= [self.serialize_item(item) for item in items], - meta=self.get_meta() - ), - 'cacheable': True - } + if total >= 0: + meta = self.get_meta() + meta['total'] = total + return { + 'status': falcon.HTTP_200, + 'media': self.get_jsonapi_response( + data = [self.serialize_item(item) for item in items], + meta = meta + ), + 'cacheable': True + } + else: + return { + 'status': falcon.HTTP_200, + 'media': self.get_jsonapi_response( + data = [self.serialize_item(item) for item in items], + meta=self.get_meta() + ), + 'cacheable': True + } class JSONAPIDetailResource(JSONAPIResource, ABC): cache_expiration_time = DOGPILE_CACHE_SETTINGS['default_detail_cache_expiration_time'] diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 2f948e5..3e28049 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -366,7 +366,14 @@ def get_item(self, item_id): return Did.query(self.session).filter_by(did_hash=item_id[2:]).first() else: return Did.query(self.session).get(item_id) - + +class DidMembersResource(JSONAPIListResource2): + def get_item_url_name(self): + return 'did_hash' + def get_query(self,did_hash): + return Did.query(self.session).filter_by(superior = did_hash) + def has_total(self): + return True class AccountResource(JSONAPIListResource): From cc6c5cec4f3ebca971eff1cc0aa5fe5c0d915e45 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Thu, 13 Feb 2020 18:19:18 +0800 Subject: [PATCH 17/21] query did by social --- app/main.py | 1 + app/resources/polkascan.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/app/main.py b/app/main.py index c983ddf..f87ee72 100644 --- a/app/main.py +++ b/app/main.py @@ -82,6 +82,7 @@ app.add_route('/transfer/{did}', polkascan.TransferListResource()) app.add_route('/did', polkascan.DidListResource()) app.add_route('/did/{item_id}', polkascan.DidDetailResource()) +app.add_route('/did/social_account/{item_id}', polkascan.DidDetailBySocialAccountResource()) app.add_route('/did/members/{did_hash}', polkascan.DidMembersResource()) app.add_route('/account', polkascan.AccountResource()) app.add_route('/account/{item_id}', polkascan.AccountDetailResource()) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 3e28049..877bc4a 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -367,6 +367,10 @@ def get_item(self, item_id): else: return Did.query(self.session).get(item_id) +class DidDetailBySocialAccountResource(JSONAPIDetailResource): + def get_item(self, item_id): + return Did.query(self.session).filter_by(social_account_hash=item_id).first() + class DidMembersResource(JSONAPIListResource2): def get_item_url_name(self): return 'did_hash' From 4050a1764584aa4c07ae82e3a99ba48238e09c76 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Wed, 26 Feb 2020 09:13:59 +0800 Subject: [PATCH 18/21] did invite report --- app/main.py | 1 + app/resources/polkascan.py | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/app/main.py b/app/main.py index f87ee72..ed5ed73 100644 --- a/app/main.py +++ b/app/main.py @@ -84,6 +84,7 @@ app.add_route('/did/{item_id}', polkascan.DidDetailResource()) app.add_route('/did/social_account/{item_id}', polkascan.DidDetailBySocialAccountResource()) app.add_route('/did/members/{did_hash}', polkascan.DidMembersResource()) +app.add_route('/did/invite_ranking',polkascan.DidInviteRanking()) app.add_route('/account', polkascan.AccountResource()) app.add_route('/account/{item_id}', polkascan.AccountDetailResource()) app.add_route('/accountindex', polkascan.AccountIndexListResource()) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 877bc4a..ef03f73 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -379,6 +379,16 @@ def get_query(self,did_hash): def has_total(self): return True +class DidInviteRanking(JSONAPIListResource): + def get_query(self): + m = self.session.execute("select t1.did,t1.social_account_hash,count(t1.did) num from data_did t1 left join data_did t2 on t2.`superior` = concat('0x',t1.`did_hash`) group by t1.did,t1.social_account_hash order by count(t1.did) desc limit 0,10") + result = [] + for item in m: + result.append([item.did,item.social_account_hash,item.num]) + return result + def serialize_item(self, item): + return item + class AccountResource(JSONAPIListResource): def get_query(self): From 8a8f9f7da7afad4e2e43d7d3ea7e6055c8ed01f4 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Tue, 24 Mar 2020 22:32:01 +0800 Subject: [PATCH 19/21] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E5=90=8E=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E5=8F=98=E4=BA=86=20transfer=20fee?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/resources/base.py | 2 ++ app/resources/polkascan.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/resources/base.py b/app/resources/base.py index 200cc99..ac28415 100644 --- a/app/resources/base.py +++ b/app/resources/base.py @@ -161,6 +161,8 @@ def process_get_response(self, req, resp, **kwargs): items = self.get_query() items = self.apply_filters(items, req.params) items = self.apply_paging(items, req.params) + print(len(items)) + print(items) return { 'status': falcon.HTTP_200, 'media': self.get_jsonapi_response( diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index ef03f73..2cb5e65 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -292,7 +292,7 @@ def serialize_item(self, item): 'destination': ss58_encode(item.attributes[1]['value'].replace('0x', ''), SUBSTRATE_ADDRESS_TYPE), 'destination_id': item.attributes[1]['value'].replace('0x', ''), 'value': item.attributes[2]['value'], - 'fee': item.attributes[3]['value'] + 'fee': 0 } } def convert_to_did_items(self): From 33c73d062dadd3662f7231f3a8679b2951aa0061 Mon Sep 17 00:00:00 2001 From: haoming06 Date: Tue, 24 Mar 2020 22:47:09 +0800 Subject: [PATCH 20/21] scalecodec>=0.9.17 --- requirements.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6531333..93a9000 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,6 +36,5 @@ urllib3==1.25.3 xxhash==1.4.1 zipp==0.5.2 -git+https://github.com/ProChain/py-scale-codec.git@master#egg=scalecodec -git+https://github.com/polkascan/py-substrate-interface.git@master#egg=substrateinterface - +scalecodec>=0.9.17 +substrate-interface>=0.9.3 From 52138d93f141c2f63fb73b68c0e759f23a63254d Mon Sep 17 00:00:00 2001 From: haoming06 Date: Fri, 27 Mar 2020 07:32:46 +0800 Subject: [PATCH 21/21] fix fee --- app/resources/polkascan.py | 55 +++++++++++---------------------- app/settings.py | 2 ++ app/type_registry/prochain.json | 21 ++++++++----- 3 files changed, 34 insertions(+), 44 deletions(-) diff --git a/app/resources/polkascan.py b/app/resources/polkascan.py index 2cb5e65..ecd5bf8 100644 --- a/app/resources/polkascan.py +++ b/app/resources/polkascan.py @@ -27,10 +27,10 @@ BlockTotal, SessionValidator, Log, DemocracyReferendum, AccountIndex, RuntimeConstant, SessionNominator, \ DemocracyVote, CouncilMotion, CouncilVote, TechCommProposal, TechCommProposalVote, TreasuryProposal, Transfer, Did from app.resources.base import JSONAPIResource, JSONAPIListResource, JSONAPIListResource2,JSONAPIDetailResource -from app.settings import SUBSTRATE_RPC_URL, SUBSTRATE_METADATA_VERSION, SUBSTRATE_ADDRESS_TYPE, TYPE_REGISTRY +from app.settings import SUBSTRATE_RPC_URL, SUBSTRATE_METADATA_VERSION, SUBSTRATE_ADDRESS_TYPE, TYPE_REGISTRY_PATH from app.utils.ss58 import ss58_decode, ss58_encode from scalecodec.base import RuntimeConfiguration -from scalecodec.type_registry import load_type_registry_preset +from scalecodec.type_registry import load_type_registry_preset,load_type_registry_file from substrateinterface import SubstrateInterface import json import decimal @@ -404,8 +404,8 @@ class AccountDetailResource(JSONAPIDetailResource): def __init__(self): RuntimeConfiguration().update_type_registry(load_type_registry_preset('default')) - if TYPE_REGISTRY != 'default': - RuntimeConfiguration().update_type_registry(load_type_registry_preset(TYPE_REGISTRY)) + if TYPE_REGISTRY_PATH: + RuntimeConfiguration().update_type_registry(load_type_registry_file(TYPE_REGISTRY_PATH)) super(AccountDetailResource, self).__init__() def get_item(self, item_id): @@ -433,54 +433,35 @@ def get_relationships(self, include_list, item): return relationships def serialize_item(self, item): - substrate = SubstrateInterface( - SUBSTRATE_RPC_URL, metadata_version=SUBSTRATE_METADATA_VERSION) + substrate = SubstrateInterface(SUBSTRATE_RPC_URL) data = item.serialize() storage_call = RuntimeStorage.query(self.session).filter_by( - module_id='balances', - name='FreeBalance', + module_id='system', + name='Account', ).order_by(RuntimeStorage.spec_version.desc()).first() + + print(storage_call) - data['attributes']['free_balance'] = substrate.get_storage( + account = substrate.get_storage( block_hash=None, - module='Balances', - function='FreeBalance', + module='System', + function='Account', params=item.id, return_scale_type=storage_call.type_value, hasher=storage_call.type_hasher, metadata_version=SUBSTRATE_METADATA_VERSION ) - storage_call = RuntimeStorage.query(self.session).filter_by( - module_id='balances', - name='ReservedBalance', - ).order_by(RuntimeStorage.spec_version.desc()).first() + print('----------------') - data['attributes']['reserved_balance'] = substrate.get_storage( - block_hash=None, - module='Balances', - function='ReservedBalance', - params=item.id, - return_scale_type=storage_call.type_value, - hasher=storage_call.type_hasher, - metadata_version=SUBSTRATE_METADATA_VERSION - ) + print(account) - storage_call = RuntimeStorage.query(self.session).filter_by( - module_id='system', - name='AccountNonce', - ).order_by(RuntimeStorage.spec_version.desc()).first() + data['attributes']['free_balance'] = account['data']['free'] - data['attributes']['nonce'] = substrate.get_storage( - block_hash=None, - module='System', - function='AccountNonce', - params=item.id, - return_scale_type=storage_call.type_value, - hasher=storage_call.type_hasher, - metadata_version=SUBSTRATE_METADATA_VERSION - ) + data['attributes']['reserved_balance'] = account['data']['reserved'] + + data['attributes']['nonce'] = account['nonce'] return data diff --git a/app/settings.py b/app/settings.py index d8cdcdf..476b593 100644 --- a/app/settings.py +++ b/app/settings.py @@ -34,6 +34,8 @@ SUBSTRATE_METADATA_VERSION = int(os.environ.get("SUBSTRATE_METADATA_VERSION", 8)) TYPE_REGISTRY = os.environ.get("TYPE_REGISTRY", "default") +TYPE_REGISTRY_PATH = os.environ.get("TYPE_REGISTRY_PATH", None) + DOGPILE_CACHE_SETTINGS = { diff --git a/app/type_registry/prochain.json b/app/type_registry/prochain.json index ce41553..8d088a0 100644 --- a/app/type_registry/prochain.json +++ b/app/type_registry/prochain.json @@ -1,9 +1,16 @@ { - "default": { + "types": { + "Keys": { + "type": "struct", + "type_mapping": [ + ["grandpa", "AccountId"], + ["babe", "AccountId"], + ["im_online", "AccountId"], + ["authority_discovery", "AccountId"] + ] + }, "Did":"Vec", - "Keys": "SessionKeysPolkadot", "BlockNumber": "U32", - "Index": "U64", "ExternalAddress":{ "type":"struct", "type_mapping":[ @@ -16,7 +23,8 @@ "type":"struct", "type_mapping":[ ["event_name","Vec"], - ["event_url","Vec"] + ["event_url","Vec"], + ["event_data","Vec"] ] }, "LockedRecords":{ @@ -46,6 +54,7 @@ ["did", "Did"], ["locked_records", "Option>"], ["unlock_records", "Option>"], + ["is_partner","bool"], ["social_account", "Option"], ["subordinate_count", "u64"], ["group_name","Option>"], @@ -82,11 +91,9 @@ ["expire_height","u32"], ["random_number_hash","Vec"], ["swap_id","Hash"], - ["event_timestamp","u64"], - ["htlc_timestamp","u64"], ["sender_addr","Vec"], ["sender_chain_type","HTLCChain"], - ["receiver_addr","Vec"], + ["receiver_addr","Hash"], ["receiver_chain_type","HTLCChain"], ["recipient_addr","Vec"], ["out_amount","Balance"],