Browse Source

Add name index for Xaya (#890)

* Rename NamecoinBlockProcessor.

For Xaya, we will use the same kind of logic for keeping track of an
index of names in addition to the index of addresses.  Thus it makes
sense to call it by some more generic name.  Here, we rename it to
NameIndexBlockProcessor.

* Create NameIndexMixin from Namecoin.

This factors out some code from Namecoin to a new NameIndexMixin.  This
code is what we need to keep track of a name index in addition to the
address index, as done by the NameIndexBlockProcessor.

With the code factored out, the Coin itself only needs to define the
set of possible name operations it allows (and where they have the name
by which the index will be built).

For now, this is only used by Namecoin.  But in the future, we will use
it for Xaya as well.

* Add name indexing to Xaya.

Change the Xaya definition so that it handles name scripts correctly:
We want to strip them off the "real" address for indexing by address,
and we want to keep a separate index on names like Namecoin does.
patch-2
Daniel Kraft 6 years ago
committed by Neil
parent
commit
47565b5c44
  1. 144
      electrumx/lib/coins.py
  2. 2
      electrumx/server/block_processor.py
  3. 60
      tests/transactions/xaya_mainnet_namereg_a32f38.json
  4. 69
      tests/transactions/xaya_mainnet_nameupd_83747d.json

144
electrumx/lib/coins.py

@ -427,6 +427,58 @@ class NameMixin(object):
return named_values, address_script
class NameIndexMixin(NameMixin):
"""Shared definitions for coins that have a name index
This class defines common functions and logic for coins that have
a name index in addition to the index by address / script."""
BLOCK_PROCESSOR = block_proc.NameIndexBlockProcessor
@classmethod
def build_name_index_script(cls, name):
"""Returns the script by which names are indexed"""
from electrumx.lib.script import Script
res = bytearray()
res.append(cls.OP_NAME_UPDATE)
res.extend(Script.push_data(name))
res.extend(Script.push_data(bytes([])))
res.append(OpCodes.OP_2DROP)
res.append(OpCodes.OP_DROP)
res.append(OpCodes.OP_RETURN)
return bytes(res)
@classmethod
def split_name_script(cls, script):
named_values, address_script = cls.interpret_name_prefix(script, cls.NAME_OPERATIONS)
if named_values is None or "name" not in named_values:
return None, address_script
name_index_script = cls.build_name_index_script(named_values["name"][1])
return name_index_script, address_script
@classmethod
def hashX_from_script(cls, script):
_, address_script = cls.split_name_script(script)
return super().hashX_from_script(address_script)
@classmethod
def address_from_script(cls, script):
_, address_script = cls.split_name_script(script)
return super().address_from_script(address_script)
@classmethod
def name_hashX_from_script(cls, script):
name_index_script, _ = cls.split_name_script(script)
if name_index_script is None:
return None
return super().hashX_from_script(name_index_script)
class HOdlcoin(Coin):
NAME = "HOdlcoin"
SHORTNAME = "HODLC"
@ -959,7 +1011,7 @@ class Unitus(Coin):
# Source: namecoin.org
class Namecoin(NameMixin, AuxPowMixin, Coin):
class Namecoin(NameIndexMixin, AuxPowMixin, Coin):
NAME = "Namecoin"
SHORTNAME = "NMC"
NET = "mainnet"
@ -979,74 +1031,24 @@ class Namecoin(NameMixin, AuxPowMixin, Coin):
'luggscoqbymhvnkp.onion t82',
'ulrichard.ch s50006 t50005',
]
BLOCK_PROCESSOR = block_proc.NamecoinBlockProcessor
BLOCK_PROCESSOR = block_proc.NameIndexBlockProcessor
# Name opcodes
OP_NAME_NEW = OpCodes.OP_1
OP_NAME_FIRSTUPDATE = OpCodes.OP_2
OP_NAME_UPDATE = OpCodes.OP_3
@classmethod
def build_name_index_script(cls, name):
"""Returns the normalised script by which names are indexed"""
from electrumx.lib.script import Script
normalized_name_op_script = bytearray()
normalized_name_op_script.append(cls.OP_NAME_UPDATE)
normalized_name_op_script.extend(Script.push_data(name))
normalized_name_op_script.extend(Script.push_data(bytes([])))
normalized_name_op_script.append(OpCodes.OP_2DROP)
normalized_name_op_script.append(OpCodes.OP_DROP)
normalized_name_op_script.append(OpCodes.OP_RETURN)
return bytes(normalized_name_op_script)
@classmethod
def split_name_script(cls, script):
from electrumx.lib.script import Script
# Opcode sequences for name operations
NAME_NEW_OPS = [cls.OP_NAME_NEW, -1, OpCodes.OP_2DROP]
NAME_FIRSTUPDATE_OPS = [cls.OP_NAME_FIRSTUPDATE, "name", -1, -1,
OpCodes.OP_2DROP, OpCodes.OP_2DROP]
NAME_UPDATE_OPS = [cls.OP_NAME_UPDATE, "name", -1, OpCodes.OP_2DROP,
OpCodes.OP_DROP]
ops = [
NAME_NEW_OPS,
NAME_FIRSTUPDATE_OPS,
NAME_UPDATE_OPS,
]
named_values, address_script = cls.interpret_name_prefix(script, ops)
if named_values is None or "name" not in named_values:
return None, address_script
normalized_name_op_script = cls.build_name_index_script(named_values["name"][1])
return bytes(normalized_name_op_script), address_script
@classmethod
def hashX_from_script(cls, script):
_name_op_script, address_script = cls.split_name_script(script)
return super().hashX_from_script(address_script)
@classmethod
def address_from_script(cls, script):
_name_op_script, address_script = cls.split_name_script(script)
return super().address_from_script(address_script)
@classmethod
def name_hashX_from_script(cls, script):
name_op_script, _address_script = cls.split_name_script(script)
if name_op_script is None:
return None
return super().hashX_from_script(name_op_script)
# Valid name prefixes.
NAME_NEW_OPS = [OP_NAME_NEW, -1, OpCodes.OP_2DROP]
NAME_FIRSTUPDATE_OPS = [OP_NAME_FIRSTUPDATE, "name", -1, -1,
OpCodes.OP_2DROP, OpCodes.OP_2DROP]
NAME_UPDATE_OPS = [OP_NAME_UPDATE, "name", -1, OpCodes.OP_2DROP,
OpCodes.OP_DROP]
NAME_OPERATIONS = [
NAME_NEW_OPS,
NAME_FIRSTUPDATE_OPS,
NAME_UPDATE_OPS,
]
class NamecoinTestnet(Namecoin):
@ -3181,7 +3183,7 @@ class CPUchain(Coin):
return cpupower.getPoWHash(header)
class Xaya(AuxPowMixin, Coin):
class Xaya(NameIndexMixin, AuxPowMixin, Coin):
NAME = "Xaya"
SHORTNAME = "CHI"
NET = "mainnet"
@ -3203,6 +3205,20 @@ class Xaya(AuxPowMixin, Coin):
'xaya.domob.eu s50002',
]
# Op-codes for name operations
OP_NAME_REGISTER = OpCodes.OP_1
OP_NAME_UPDATE = OpCodes.OP_2
# Valid name prefixes.
NAME_REGISTER_OPS = [OP_NAME_REGISTER, "name", -1, OpCodes.OP_2DROP,
OpCodes.OP_DROP]
NAME_UPDATE_OPS = [OP_NAME_UPDATE, "name", -1, OpCodes.OP_2DROP,
OpCodes.OP_DROP]
NAME_OPERATIONS = [
NAME_REGISTER_OPS,
NAME_UPDATE_OPS,
]
@classmethod
def genesis_block(cls, block):
super().genesis_block(block)

2
electrumx/server/block_processor.py

@ -690,7 +690,7 @@ class DecredBlockProcessor(BlockProcessor):
return start, count
class NamecoinBlockProcessor(BlockProcessor):
class NameIndexBlockProcessor(BlockProcessor):
def advance_txs(self, txs):
result = super().advance_txs(txs)

60
tests/transactions/xaya_mainnet_namereg_a32f38.json

@ -0,0 +1,60 @@
{
"txid": "a32f38a463b75f2cb9955f5660063e7888f9120b40f27312b65e53fad6a226fd",
"hash": "a32f38a463b75f2cb9955f5660063e7888f9120b40f27312b65e53fad6a226fd",
"version": 2,
"size": 240,
"vsize": 240,
"weight": 960,
"locktime": 0,
"vin": [
{
"txid": "c87eb7b9c71146a18f8ebaea93b74bfeb4795b265f151ba5a1e62ef32017bc34",
"vout": 0,
"scriptSig": {
"asm": "3045022100df2c9fdfa19e145a3d1f3b995e2925e6270f02dd13a9d5e79edc0bf7841517d40220722d8c694a21890bb24b82530f7e553371b9123d1e0e8c1ad818fe87c53e3cbb[ALL] 03a2bfae3cc2b43c7ac5e8ae402e1552b9edca7a2ff73ac1950ca52dae73791e95",
"hex": "483045022100df2c9fdfa19e145a3d1f3b995e2925e6270f02dd13a9d5e79edc0bf7841517d40220722d8c694a21890bb24b82530f7e553371b9123d1e0e8c1ad818fe87c53e3cbb012103a2bfae3cc2b43c7ac5e8ae402e1552b9edca7a2ff73ac1950ca52dae73791e95"
},
"sequence": 4294967294
}
],
"vout": [
{
"value": 1996928100,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5026b54aec9036aaf02473481356acb3fe45846a OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a9145026b54aec9036aaf02473481356acb3fe45846a88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"CPmgzsvaWeSNvXd5CNfzSLnX2ymjJ7jwtw"
]
}
},
{
"value": 1000000,
"n": 1,
"scriptPubKey": {
"nameOp": {
"op": "name_register",
"name": "p/domob",
"name_encoding": "utf8",
"value": "{}",
"value_encoding": "ascii"
},
"asm": "OP_NAME_REGISTER 702f646f6d6f62 32123 OP_2DROP OP_DROP OP_DUP OP_HASH160 eed2f5ecba300e6137c3a966d60cab012b490e01 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "5107702f646f6d6f62027b7d6d7576a914eed2f5ecba300e6137c3a966d60cab012b490e0188ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"CeEg7VvAJ6rtz7MQ9sbkmEEb4zxRbSU4JT"
]
}
}
],
"hex": "020000000134bc1720f32ee6a1a51b155f265b79b4fe4bb793eaba8e8fa14611c7b9b77ec8000000006b483045022100df2c9fdfa19e145a3d1f3b995e2925e6270f02dd13a9d5e79edc0bf7841517d40220722d8c694a21890bb24b82530f7e553371b9123d1e0e8c1ad818fe87c53e3cbb012103a2bfae3cc2b43c7ac5e8ae402e1552b9edca7a2ff73ac1950ca52dae73791e95feffffff0264b40677000000001976a9145026b54aec9036aaf02473481356acb3fe45846a88ac40420f0000000000275107702f646f6d6f62027b7d6d7576a914eed2f5ecba300e6137c3a966d60cab012b490e0188ac00000000",
"blockhash": "1efbbbe72b0198a68bd3a9f5d349f4bcb5d87c660262a6c6731c37b1cb61a73e",
"confirmations": 1032707,
"time": 1531484387,
"blocktime": 1531484387
}

69
tests/transactions/xaya_mainnet_nameupd_83747d.json

@ -0,0 +1,69 @@
{
"txid": "83747d1e69e264644f425bc2dae3bedca6d72274a0f2f82b00d9a0a70714c2be",
"hash": "83747d1e69e264644f425bc2dae3bedca6d72274a0f2f82b00d9a0a70714c2be",
"version": 2,
"size": 413,
"vsize": 413,
"weight": 1652,
"locktime": 244772,
"vin": [
{
"txid": "59d8a63955615b49b550ca9207ae9c5853898370a37efe8fcb4cfbff7eba989e",
"vout": 0,
"scriptSig": {
"asm": "304402202f16982264f61a1bdd08cf5f5aa620fd761419416aceaf65226ba74a932e8ea50220520d2a8755da0f85c257afeb841fab9692807d177fd4693e0697308f658940ed[ALL] 02d9ce309aa25d552cc1e6e2557e4b91b8ad9d055ff74fc4241e6b5b1039792eae",
"hex": "47304402202f16982264f61a1bdd08cf5f5aa620fd761419416aceaf65226ba74a932e8ea50220520d2a8755da0f85c257afeb841fab9692807d177fd4693e0697308f658940ed012102d9ce309aa25d552cc1e6e2557e4b91b8ad9d055ff74fc4241e6b5b1039792eae"
},
"sequence": 4294967294
},
{
"txid": "a32f38a463b75f2cb9955f5660063e7888f9120b40f27312b65e53fad6a226fd",
"vout": 1,
"scriptSig": {
"asm": "3044022030710158479236b1e8da22cbe5710f0b1b1210fdfa3c68dcb955af8137340db8022064f8f2d2c4047f51f0e62ebe2ee2aac7d3eb574f57f497ad828fb2381234d81e[ALL] 03611ff32dd36a49b75873dc3770c1e5f6a83ea8a4f56fa1fd08400b7686eb4c21",
"hex": "473044022030710158479236b1e8da22cbe5710f0b1b1210fdfa3c68dcb955af8137340db8022064f8f2d2c4047f51f0e62ebe2ee2aac7d3eb574f57f497ad828fb2381234d81e012103611ff32dd36a49b75873dc3770c1e5f6a83ea8a4f56fa1fd08400b7686eb4c21"
},
"sequence": 4294967294
}
],
"vout": [
{
"value": 473277800,
"n": 0,
"scriptPubKey": {
"asm": "OP_DUP OP_HASH160 13f261c11e7471063893a4821331a1bd4496f5fb OP_EQUALVERIFY OP_CHECKSIG",
"hex": "76a91413f261c11e7471063893a4821331a1bd4496f5fb88ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"CJHMmfxKEypZd9oF5Ui9cSgWD7eaUC6cGT"
]
}
},
{
"value": 1000000,
"n": 1,
"scriptPubKey": {
"nameOp": {
"op": "name_update",
"name": "p/domob",
"name_encoding": "utf8",
"value": "{\"g\":{\"mv\":{\"d\":\"u\",\"n\":10}}}",
"value_encoding": "ascii"
},
"asm": "OP_NAME_UPDATE 702f646f6d6f62 7b2267223a7b226d76223a7b2264223a2275222c226e223a31307d7d7d OP_2DROP OP_DROP OP_DUP OP_HASH160 9375d04e6c8a332e0dd06dff3e9c037ac80d31a0 OP_EQUALVERIFY OP_CHECKSIG",
"hex": "5207702f646f6d6f621d7b2267223a7b226d76223a7b2264223a2275222c226e223a31307d7d7d6d7576a9149375d04e6c8a332e0dd06dff3e9c037ac80d31a088ac",
"reqSigs": 1,
"type": "pubkeyhash",
"addresses": [
"CVub35ZeaqJajwUxr7ib3sYBfQg19AhKRs"
]
}
}
],
"hex": "02000000029e98ba7efffb4ccb8ffe7ea370838953589cae0792ca50b5495b615539a6d859000000006a47304402202f16982264f61a1bdd08cf5f5aa620fd761419416aceaf65226ba74a932e8ea50220520d2a8755da0f85c257afeb841fab9692807d177fd4693e0697308f658940ed012102d9ce309aa25d552cc1e6e2557e4b91b8ad9d055ff74fc4241e6b5b1039792eaefefffffffd26a2d6fa535eb61273f2400b12f988783e0660565f95b92c5fb763a4382fa3010000006a473044022030710158479236b1e8da22cbe5710f0b1b1210fdfa3c68dcb955af8137340db8022064f8f2d2c4047f51f0e62ebe2ee2aac7d3eb574f57f497ad828fb2381234d81e012103611ff32dd36a49b75873dc3770c1e5f6a83ea8a4f56fa1fd08400b7686eb4c21feffffff0268a5351c000000001976a91413f261c11e7471063893a4821331a1bd4496f5fb88ac40420f0000000000425207702f646f6d6f621d7b2267223a7b226d76223a7b2264223a2275222c226e223a31307d7d7d6d7576a9149375d04e6c8a332e0dd06dff3e9c037ac80d31a088ac24bc0300",
"blockhash": "6d8071aa2e91e13004d9cc185e3a51a1975f33f190b171ce3d638ae17fdb1154",
"confirmations": 787951,
"time": 1539182355,
"blocktime": 1539182355
}
Loading…
Cancel
Save