add schemas from blockstack_client

This commit is contained in:
Jude Nelson
2018-01-29 19:05:05 -05:00
parent 4fd0d45e54
commit cbf2b93a86

508
blockstack/lib/schemas.py Normal file
View File

@@ -0,0 +1,508 @@
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Blockstack-client
~~~~~
copyright: (c) 2014-2015 by Halfmoon Labs, Inc.
copyright: (c) 2016 by Blockstack.org
This file is part of Blockstack-client.
Blockstack-client is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Blockstack-client is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Blockstack-client. If not, see <http://www.gnu.org/licenses/>.
"""
from .config import LENGTHS, NAME_OPCODES, NAME_TRANSFER, TRANSFER_KEEP_DATA, TRANSFER_REMOVE_DATA, NAME_REGISTRATION
# schema constants
OP_HEX_PATTERN = r'^([0-9a-fA-F]+)$'
OP_CONSENSUS_HASH_PATTERN = r'^([0-9a-fA-F]{{{}}})$'.format(LENGTHS['consensus_hash'] * 2)
OP_ZONEFILE_HASH_PATTERN = r'^([0-9a-fA-F]{{{}}})$'.format(LENGTHS['value_hash'] * 2)
OP_BASE64_EMPTY_PATTERN = '^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$' # base64 with empty string
OP_BASE58CHECK_CLASS = r'[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]'
OP_BASE58CHECK_PATTERN = r'^({}+)$'.format(OP_BASE58CHECK_CLASS)
OP_ADDRESS_PATTERN = r'^({}{{1,35}})$'.format(OP_BASE58CHECK_CLASS)
OP_NAME_CHARS = r'a-z0-9\-_.+'
OP_NAME_CHARS_NOPERIOD = r'a-z0-9\-_+'
OP_NAME_CLASS = r'[{}]{{{},{}}}'.format(OP_NAME_CHARS, LENGTHS['fqn_min'], LENGTHS['fqn_max'])
OP_NAMESPACE_CLASS = r'[{}]{{{},{}}}'.format(OP_NAME_CHARS, 1, LENGTHS['namespace_id'])
OP_NAMESPACE_PATTERN = r'^({})$'.format(OP_NAMESPACE_CLASS)
OP_NAMESPACE_ID_HASH_PATTERN = r'^([0-9a-fA-F]{40})$'
OP_NAME_PATTERN = r'^({})$'.format(OP_NAME_CLASS)
OP_SUBDOMAIN_NAME_PATTERN = r'^([{}]+){{1,{}}}\.({})$'.format(OP_NAME_CHARS_NOPERIOD, LENGTHS['fqn_max'], OP_NAME_CLASS)
OP_NAME_OR_SUBDOMAIN_FRAGMENT = r'({})|({})'.format(OP_NAME_PATTERN, OP_SUBDOMAIN_NAME_PATTERN)
OP_NAME_OR_SUBDOMAIN_PATTERN = r'^{}$'.format(OP_NAME_OR_SUBDOMAIN_FRAGMENT)
OP_URI_TARGET_PATTERN = r'^([a-z0-9+]+)://([a-zA-Z0-9\-_.~%#?&\\:/=]+)$'
OP_URI_TARGET_PATTERN_NOSCHEME = r'^([a-zA-Z0-9\-_.~%#?&\\:/=]+)$'
OP_URLENCODED_CLASS = r'[a-zA-Z0-9\-_.~%/]'
OP_URLENCODED_PATTERN = r'^({}+)$'.format(OP_URLENCODED_CLASS)
OP_P2PKH_PATTERN = r'^76[aA]914[0-9a-fA-F]{40}88[aA][cC]$'
OP_SCRIPT_PATTERN = r'^[0-9a-fA-F]+$'
OP_CODE_PATTERN = r'^([{}]{{1}}|{}{}|{}{}|{}{})$'.format(
''.join(NAME_OPCODES.values()),
NAME_TRANSFER, TRANSFER_KEEP_DATA,
NAME_TRANSFER, TRANSFER_REMOVE_DATA,
NAME_REGISTRATION, NAME_REGISTRATION
)
OP_CODE_NAME_PATTERN = '|'.join(NAME_OPCODES.keys())
OP_HEX_PATTERN = r'^([0-9a-fA-F]+)$'
OP_PUBKEY_PATTERN = OP_HEX_PATTERN
OP_TXID_PATTERN = OP_HEX_PATTERN
URI_RECORD_SCHEMA = {
'type': 'object',
'properties': {
'name': {
'type': 'string'
},
'priority': {
'type': 'integer',
'minimum': 0,
'maximum': 65535,
},
'weight': {
'type': 'integer',
'minimum': 0,
'maximum': 65535,
},
'target': {
'anyOf': [
{
'type': 'string',
'pattern': OP_URI_TARGET_PATTERN,
},
{
'type': 'string',
'pattern': OP_URI_TARGET_PATTERN_NOSCHEME,
},
],
},
'class': {
'type': 'string'
},
'_missing_class': {
'type': 'boolean'
},
},
'required': [
'name',
'priority',
'weight',
'target'
],
}
TXT_RECORD_SCHEMA = {
'type': 'object',
'properties': {
'name': {
'type': 'string',
'pattern': OP_URLENCODED_PATTERN,
},
'txt': {
'type': ['string',
'array']
},
},
'required': [
'name',
'txt'
],
}
USER_ZONEFILE_SCHEMA = {
'type': 'object',
'properties': {
'txt': {
'type': 'array',
'items': TXT_RECORD_SCHEMA,
},
'uri': {
'type': 'array',
'items': URI_RECORD_SCHEMA,
},
'$origin': {
'type': 'string',
'pattern': OP_NAME_PATTERN,
},
'$ttl': {
'type': 'integer',
'minimum': 0,
'maximum': 2147483647,
},
},
'required': [
'$origin',
'$ttl'
],
}
OP_HISTORY_SCHEMA = {
'type': 'object',
'properties': {
'address': {
'type': 'string',
'pattern': OP_ADDRESS_PATTERN,
},
'base': {
'type': 'integer',
'minimum': 0,
'maximum': 255,
},
'buckets': {
'anyOf': [
{
'type': 'string',
'pattern': r'^\[((0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15), ){15}(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15)\]$'
},
{
'type': 'array',
'items': {
'type': 'integer',
'minItems': 16,
'maxItems': 16,
},
},
{
'type': 'null',
},
],
},
'block_number': {
'type': 'integer',
'minimum': 0,
},
'coeff': {
'anyOf': [
{
'type': 'integer',
'minimum': 0,
'maximum': 255,
},
{
'type': 'null'
},
],
},
'consensus_hash': {
'anyOf': [
{
'type': 'string',
'pattern': OP_CONSENSUS_HASH_PATTERN,
},
{
'type': 'null'
},
],
},
'domain': {
'type': 'string',
'pattern': OP_NAME_PATTERN,
},
'fee': {
'type': 'integer',
'minimum': 0,
},
'first_registered': {
'type': 'integer',
'minimum': 0,
},
'history_snapshot': {
'type': 'boolean',
},
'importer': {
'anyOf': [
{
'type': 'string',
'pattern': OP_P2PKH_PATTERN,
},
{
'type': 'null',
},
],
},
'importer_address': {
'anyOf': [
{
'type': 'string',
'pattern': OP_ADDRESS_PATTERN,
},
{
'type': 'null',
},
],
},
'last_renewed': {
'type': 'integer',
'minimum': 0,
},
'op': {
'type': 'string',
'pattern': OP_CODE_PATTERN,
},
'op_fee': {
'type': 'number',
},
'opcode': {
'type': 'string',
'pattern': OP_CODE_NAME_PATTERN,
},
'revoked': {
'type': 'boolean',
},
'sender': {
'type': 'string',
'pattern': OP_SCRIPT_PATTERN,
},
'sender_pubkey': {
'anyOf': [
{
'type': 'string',
'pattern': OP_PUBKEY_PATTERN,
},
{
'type': 'null'
},
],
},
'sequence': {
'type': 'integer',
'minimum': 0,
},
'recipient': {
'anyOf': [
{
'type': 'string',
'pattern': OP_SCRIPT_PATTERN,
},
{
'type': 'null'
},
],
},
'recipient_address': {
'anyOf': [
{
'type': 'string',
'pattern': OP_ADDRESS_PATTERN,
},
{
'type': 'null'
},
],
},
'recipient_pubkey': {
'anyOf': [
{
'type': 'string',
'pattern': OP_PUBKEY_PATTERN,
},
{
'type': 'null'
},
],
},
'txid': {
'type': 'string',
'pattern': OP_TXID_PATTERN,
},
'value_hash': {
'anyOf': [
{
'type': 'string',
'pattern': OP_ZONEFILE_HASH_PATTERN,
},
{
'type': 'null',
},
],
},
'vtxindex': {
'type': 'integer',
'minimum': 0,
},
'zonefile': {
'type': 'string',
'pattern': OP_BASE64_EMPTY_PATTERN,
},
},
'required': [
'op',
'opcode',
'txid',
'vtxindex'
],
}
NAMEOP_SCHEMA_PROPERTIES = {
'address': OP_HISTORY_SCHEMA['properties']['address'],
'block_number': OP_HISTORY_SCHEMA['properties']['block_number'],
'consensus_hash': OP_HISTORY_SCHEMA['properties']['consensus_hash'],
'domain': OP_HISTORY_SCHEMA['properties']['domain'],
'expired': {
# NOTE: filled in by the indexer
'type': 'boolean',
},
'expire_block': {
# NOTE: filled in by the indexer
'type': 'integer',
'minimum': -1,
},
'renewal_deadline': {
# NOTE: filled in by the indexer
'type': 'integer',
'minimum': -1,
},
'first_registered': OP_HISTORY_SCHEMA['properties']['first_registered'],
'history': {
'type': 'object',
'patternProperties': {
'^([0-9]+)$': {
'type': 'array',
'items': OP_HISTORY_SCHEMA,
},
},
},
'history_snapshot': {
'type': 'boolean',
},
'importer': OP_HISTORY_SCHEMA['properties']['importer'],
'importer_address': OP_HISTORY_SCHEMA['properties']['importer_address'],
'last_renewed': OP_HISTORY_SCHEMA['properties']['last_renewed'],
'name': {
'type': 'string',
'pattern': OP_NAME_PATTERN,
},
'op': OP_HISTORY_SCHEMA['properties']['op'],
'op_fee': OP_HISTORY_SCHEMA['properties']['op_fee'],
'opcode': OP_HISTORY_SCHEMA['properties']['opcode'],
'revoked': OP_HISTORY_SCHEMA['properties']['revoked'],
'sender': OP_HISTORY_SCHEMA['properties']['sender'],
'sender_pubkey': OP_HISTORY_SCHEMA['properties']['sender_pubkey'],
'sequence': OP_HISTORY_SCHEMA['properties']['sequence'],
'recipient': OP_HISTORY_SCHEMA['properties']['recipient'],
'recipient_address': OP_HISTORY_SCHEMA['properties']['recipient_address'],
'txid': OP_HISTORY_SCHEMA['properties']['txid'],
'value_hash': OP_HISTORY_SCHEMA['properties']['value_hash'],
'vtxindex': OP_HISTORY_SCHEMA['properties']['vtxindex'],
'zonefile': OP_HISTORY_SCHEMA['properties']['zonefile'],
}
NAMESPACE_SCHEMA_PROPERTIES = {
'address': OP_HISTORY_SCHEMA['properties']['address'],
'base': OP_HISTORY_SCHEMA['properties']['base'],
'block_number': OP_HISTORY_SCHEMA['properties']['block_number'],
'buckets': OP_HISTORY_SCHEMA['properties']['buckets'],
'coeff': OP_HISTORY_SCHEMA['properties']['coeff'],
'fee': OP_HISTORY_SCHEMA['properties']['fee'],
'history': {
'type': 'object',
'patternProperties': {
'^([0-9]+)$': {
'type': 'array',
'items': OP_HISTORY_SCHEMA,
},
},
},
'lifetime': {
'type': 'integer'
},
'namespace_id': {
'type': 'string',
'pattern': OP_NAMESPACE_PATTERN,
},
# legacy field
'namespace_id_hash': {
'type': 'string',
'pattern': OP_NAMESPACE_ID_HASH_PATTERN,
},
'no_vowel_discount': {
'type': 'integer',
'minimum': 0,
'maximum': 15,
},
'nonalpha_discount': {
'type': 'integer',
'minimum': 0,
'maximum': 15,
},
'op': OP_HISTORY_SCHEMA['properties']['op'],
'preorder_hash': {
'type': 'string',
'pattern': OP_NAMESPACE_ID_HASH_PATTERN,
},
'ready': {
'type': 'boolean',
},
'ready_block': {
'type': 'integer',
'minimum': 0,
},
'recipient': OP_HISTORY_SCHEMA['properties']['recipient'],
'recipient_address': OP_HISTORY_SCHEMA['properties']['recipient_address'],
'reveal_block': {
'type': 'integer',
'minimum': 0,
},
'sender': OP_HISTORY_SCHEMA['properties']['sender'],
'sender_pubkey': OP_HISTORY_SCHEMA['properties']['sender_pubkey'],
'txid': OP_HISTORY_SCHEMA['properties']['txid'],
'version': {
'type': 'integer',
'minimum': 1,
},
'vtxindex': OP_HISTORY_SCHEMA['properties']['vtxindex'],
}
NAMEOP_SCHEMA_REQUIRED = [
'address',
'block_number',
'op',
'op_fee',
'opcode',
'sender',
'txid',
'vtxindex'
]
NAMESPACE_SCHEMA_REQUIRED = [
'address',
'base',
'block_number',
'buckets',
'coeff',
'lifetime',
'namespace_id',
'no_vowel_discount',
'nonalpha_discount',
'op',
'ready',
'recipient',
'recipient_address',
'reveal_block',
'sender',
'sender_pubkey',
'txid',
'version',
'vtxindex'
]
SUBDOMAIN_SCHEMA_REQUIRED = [
'address',
'domain',
'block_number',
'sequence',
'txid',
'value_hash',
]