moved some validator utils to tendermint utils, election approval now handled by planetmint

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
Lorenz Herzberger 2022-10-10 13:35:04 +02:00
parent 54e821ebaf
commit db7d9663f1
No known key found for this signature in database
GPG Key ID: FA5EE906EB55316A
8 changed files with 78 additions and 70 deletions

View File

@ -21,10 +21,8 @@ from tendermint.abci.types_pb2 import (
ResponseCommit,
)
from planetmint import Planetmint
from planetmint.transactions.types.elections.election import Election
from planetmint.tendermint_utils import decode_transaction, calculate_hash
from planetmint.tendermint_utils import decode_transaction, calculate_hash, decode_validator
from planetmint.lib import Block
import planetmint.transactions.types.elections.validator_utils as vutils
from planetmint.events import EventTypes, Event
@ -87,7 +85,7 @@ class App(BaseApplication):
app_hash = "" if block is None else block["app_hash"]
height = 0 if block is None else block["height"] + 1
known_validators = self.planetmint_node.get_validators()
validator_set = [vutils.decode_validator(v) for v in genesis.validators]
validator_set = [decode_validator(v) for v in genesis.validators]
if known_validators and known_validators != validator_set:
self.log_abci_migration_error(known_chain["chain_id"], known_validators)
sys.exit(1)

View File

@ -43,7 +43,7 @@ from planetmint.transactions.common.transaction_mode_types import (
BROADCAST_TX_ASYNC,
BROADCAST_TX_SYNC,
)
from planetmint.tendermint_utils import encode_transaction, merkleroot, key_from_base64, public_key_to_base64
from planetmint.tendermint_utils import encode_transaction, merkleroot, key_from_base64, public_key_to_base64, encode_validator, new_validator_set
from planetmint import exceptions as core_exceptions
from planetmint.transactions.types.elections.election import Election
from planetmint.transactions.types.elections.vote import Vote
@ -874,7 +874,7 @@ class Planetmint(object):
if not self.has_election_concluded(election, votes):
continue
validator_update = election.on_approval(self, new_height)
validator_update = self.approve_election(election, new_height)
self.store_election(election.id, new_height, is_concluded=True)
return [validator_update] if validator_update else []
@ -947,11 +947,28 @@ class Planetmint(object):
elections = self._get_votes(txns)
for election_id in elections:
election = self.get_transaction(election_id)
# election.on_rollback(self, new_height)
if election.operation == VALIDATOR_ELECTION:
# TODO change to `new_height + 2` when upgrading to Tendermint 0.24.0.
self.delete_validator_set(new_height + 1)
if election.operation == CHAIN_MIGRATION_ELECTION:
self.delete_abci_chain(new_height)
def approve_election(self, election, new_height):
"""Override to update the database state according to the
election rules. Consider the current database state to account for
other concluded elections, if required.
"""
if election.operation == CHAIN_MIGRATION_ELECTION:
self.migrate_abci_chain()
if election.operation == VALIDATOR_ELECTION:
validator_updates = [election.asset["data"]]
curr_validator_set = self.get_validators(new_height)
updated_validator_set = new_validator_set(curr_validator_set, validator_updates)
updated_validator_set = [v for v in updated_validator_set if v["voting_power"] > 0]
# TODO change to `new_height + 2` when upgrading to Tendermint 0.24.0.
self.store_validator_set(new_height + 1, updated_validator_set)
return encode_validator(election.asset["data"])
Block = namedtuple("Block", ("app_hash", "height", "transactions"))

View File

@ -6,10 +6,64 @@
import base64
import hashlib
import json
import codecs
from binascii import hexlify
from tendermint.abci import types_pb2
from tendermint.crypto import keys_pb2
from hashlib import sha3_256
from planetmint.transactions.common.exceptions import InvalidPublicKey
def encode_validator(v):
ed25519_public_key = v["public_key"]["value"]
pub_key = keys_pb2.PublicKey(ed25519=bytes.fromhex(ed25519_public_key))
return types_pb2.ValidatorUpdate(pub_key=pub_key, power=v["power"])
def decode_validator(v):
return {
"public_key": {
"type": "ed25519-base64",
"value": codecs.encode(v.pub_key.ed25519, "base64").decode().rstrip("\n"),
},
"voting_power": v.power,
}
def new_validator_set(validators, updates):
validators_dict = {}
for v in validators:
validators_dict[v["public_key"]["value"]] = v
updates_dict = {}
for u in updates:
decoder = get_public_key_decoder(u["public_key"])
public_key64 = base64.b64encode(decoder(u["public_key"]["value"])).decode("utf-8")
updates_dict[public_key64] = {
"public_key": {"type": "ed25519-base64", "value": public_key64},
"voting_power": u["power"],
}
new_validators_dict = {**validators_dict, **updates_dict}
return list(new_validators_dict.values())
def get_public_key_decoder(pk):
encoding = pk["type"]
decoder = base64.b64decode
if encoding == "ed25519-base16":
decoder = base64.b16decode
elif encoding == "ed25519-base32":
decoder = base64.b32decode
elif encoding == "ed25519-base64":
decoder = base64.b64decode
else:
raise InvalidPublicKey("Invalid `type` specified for public key `value`")
return decoder
def encode_transaction(value):
"""Encode a transaction (dict) to Base64."""

View File

@ -11,9 +11,5 @@ from planetmint.transactions.types.elections.election import Election
class ChainMigrationElection(Election):
OPERATION = CHAIN_MIGRATION_ELECTION
# CREATE = OPERATION
ALLOWED_OPERATIONS = (OPERATION,)
TX_SCHEMA_CUSTOM = TX_SCHEMA_CHAIN_MIGRATION_ELECTION
def on_approval(self, planet, *args, **kwargs): # TODO: move somewhere else
planet.migrate_abci_chain()

View File

@ -66,10 +66,3 @@ class Election(Transaction):
_validate_schema(TX_SCHEMA_COMMON, tx)
if cls.TX_SCHEMA_CUSTOM:
_validate_schema(cls.TX_SCHEMA_CUSTOM, tx)
def on_approval(self, planet, new_height):
"""Override to update the database state according to the
election rules. Consider the current database state to account for
other concluded elections, if required.
"""
raise NotImplementedError

View File

@ -7,7 +7,7 @@ from planetmint.transactions.types.elections.election import Election
from planetmint.transactions.common.schema import TX_SCHEMA_VALIDATOR_ELECTION
from planetmint.transactions.common.transaction import VALIDATOR_ELECTION
from .validator_utils import new_validator_set, encode_validator, validate_asset_public_key
from .validator_utils import validate_asset_public_key
class ValidatorElection(Election):
@ -20,14 +20,3 @@ class ValidatorElection(Election):
def validate_schema(cls, tx):
super(ValidatorElection, cls).validate_schema(tx)
validate_asset_public_key(tx["asset"]["data"]["public_key"])
def on_approval(self, planet, new_height): # TODO: move somewhere else
validator_updates = [self.asset["data"]]
curr_validator_set = planet.get_validators(new_height)
updated_validator_set = new_validator_set(curr_validator_set, validator_updates)
updated_validator_set = [v for v in updated_validator_set if v["voting_power"] > 0]
# TODO change to `new_height + 2` when upgrading to Tendermint 0.24.0.
planet.store_validator_set(new_height + 1, updated_validator_set)
return encode_validator(self.asset["data"])

View File

@ -6,48 +6,10 @@
import base58
import base64
import binascii
import codecs
from tendermint.abci import types_pb2
from tendermint.crypto import keys_pb2
from planetmint.transactions.common.exceptions import InvalidPublicKey
def encode_validator(v):
ed25519_public_key = v["public_key"]["value"]
pub_key = keys_pb2.PublicKey(ed25519=bytes.fromhex(ed25519_public_key))
return types_pb2.ValidatorUpdate(pub_key=pub_key, power=v["power"])
def decode_validator(v):
return {
"public_key": {
"type": "ed25519-base64",
"value": codecs.encode(v.pub_key.ed25519, "base64").decode().rstrip("\n"),
},
"voting_power": v.power,
}
def new_validator_set(validators, updates):
validators_dict = {}
for v in validators:
validators_dict[v["public_key"]["value"]] = v
updates_dict = {}
for u in updates:
decoder = get_public_key_decoder(u["public_key"])
public_key64 = base64.b64encode(decoder(u["public_key"]["value"])).decode("utf-8")
updates_dict[public_key64] = {
"public_key": {"type": "ed25519-base64", "value": public_key64},
"voting_power": u["power"],
}
new_validators_dict = {**validators_dict, **updates_dict}
return list(new_validators_dict.values())
def encode_pk_to_base16(validator):
pk = validator["public_key"]
decoder = get_public_key_decoder(pk)

View File

@ -16,11 +16,10 @@ from planetmint import App
from planetmint.backend import query
from planetmint.transactions.common.crypto import generate_key_pair
from planetmint.core import OkCode, CodeTypeError, rollback
from planetmint.transactions.types.elections.election import Election
from planetmint.lib import Block
from planetmint.transactions.types.elections.chain_migration_election import ChainMigrationElection
from planetmint.transactions.types.elections.validator_election import ValidatorElection
from planetmint.transactions.types.elections.validator_utils import new_validator_set
from planetmint.tendermint_utils import new_validator_set
from planetmint.tendermint_utils import public_key_to_base64
from planetmint.version import __tm_supported_versions__