mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-29 04:31:44 +00:00
name reg
This commit is contained in:
@ -296,7 +296,7 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
||||
|
||||
// TODO: do something with fees
|
||||
fees := uint64(0)
|
||||
_s := blockCache.State() // hack to access validators and event switch.
|
||||
_s := blockCache.State() // hack to access validators and block height
|
||||
|
||||
// Exec tx
|
||||
switch tx := tx_.(type) {
|
||||
@ -478,6 +478,102 @@ func ExecTx(blockCache *BlockCache, tx_ types.Tx, runCall bool, evc events.Firea
|
||||
|
||||
return nil
|
||||
|
||||
case *types.NameTx:
|
||||
var inAcc *account.Account
|
||||
|
||||
// Validate input
|
||||
inAcc = blockCache.GetAccount(tx.Input.Address)
|
||||
if inAcc == nil {
|
||||
log.Debug(Fmt("Can't find in account %X", tx.Input.Address))
|
||||
return types.ErrTxInvalidAddress
|
||||
}
|
||||
// pubKey should be present in either "inAcc" or "tx.Input"
|
||||
if err := checkInputPubKey(inAcc, tx.Input); err != nil {
|
||||
log.Debug(Fmt("Can't find pubkey for %X", tx.Input.Address))
|
||||
return err
|
||||
}
|
||||
signBytes := account.SignBytes(tx)
|
||||
err := validateInput(inAcc, signBytes, tx.Input)
|
||||
if err != nil {
|
||||
log.Debug(Fmt("validateInput failed on %X:", tx.Input.Address))
|
||||
return err
|
||||
}
|
||||
// fee is in addition to the amount which is used to determine the TTL
|
||||
if tx.Input.Amount < tx.Fee {
|
||||
log.Debug(Fmt("Sender did not send enough to cover the fee %X", tx.Input.Address))
|
||||
return types.ErrTxInsufficientFunds
|
||||
}
|
||||
|
||||
value := tx.Input.Amount - tx.Fee
|
||||
|
||||
// let's say cost of a name for one block is len(data) + 32
|
||||
// TODO: the casting is dangerous and things can overflow (below)!
|
||||
// we should make LastBlockHeight a uint64
|
||||
costPerBlock := uint(len(tx.Data) + 32)
|
||||
expiresIn := uint(value / uint64(costPerBlock))
|
||||
|
||||
// check if the name exists
|
||||
entry := blockCache.GetNameRegEntry(tx.Name)
|
||||
|
||||
if entry != nil {
|
||||
var expired bool
|
||||
// if the entry already exists, and hasn't expired, we must be owner
|
||||
if entry.Expires > _s.LastBlockHeight {
|
||||
// ensure we are owner
|
||||
if bytes.Compare(entry.Owner, tx.Input.Address) != 0 {
|
||||
log.Debug(Fmt("Sender %X is trying to update a name (%s) for which he is not owner", tx.Input.Address, tx.Name))
|
||||
return types.ErrTxInvalidAddress // (?)
|
||||
}
|
||||
} else {
|
||||
expired = true
|
||||
}
|
||||
|
||||
// no value and empty data means delete the entry
|
||||
if value == 0 && len(tx.Data) == 0 {
|
||||
// maybe we reward you for telling us we can delete this crap
|
||||
// (owners if not expired, anyone if expired)
|
||||
blockCache.RemoveNameRegEntry(entry.Name)
|
||||
} else {
|
||||
// update the entry by bumping the expiry
|
||||
// and changing the data
|
||||
if expired {
|
||||
entry.Expires = _s.LastBlockHeight + expiresIn
|
||||
} else {
|
||||
// since the size of the data may have changed
|
||||
// we use the total amount of "credit"
|
||||
credit := uint64((entry.Expires - _s.LastBlockHeight) * uint(len(entry.Data)))
|
||||
credit += value
|
||||
expiresIn = uint(credit) / costPerBlock
|
||||
entry.Expires = _s.LastBlockHeight + expiresIn
|
||||
}
|
||||
entry.Data = tx.Data
|
||||
blockCache.UpdateNameRegEntry(entry)
|
||||
}
|
||||
} else {
|
||||
if expiresIn < 5 {
|
||||
return fmt.Errorf("Names must be registered for at least 5 blocks")
|
||||
}
|
||||
// entry does not exist, so create it
|
||||
entry = &types.NameRegEntry{
|
||||
Name: tx.Name,
|
||||
Owner: tx.Input.Address,
|
||||
Data: tx.Data,
|
||||
Expires: _s.LastBlockHeight + expiresIn,
|
||||
}
|
||||
blockCache.UpdateNameRegEntry(entry)
|
||||
}
|
||||
|
||||
// TODO: something with the value sent?
|
||||
|
||||
// Good!
|
||||
inAcc.Sequence += 1
|
||||
inAcc.Balance -= value
|
||||
blockCache.UpdateAccount(inAcc)
|
||||
|
||||
// TODO: maybe we want to take funds on error and allow txs in that don't do anythingi?
|
||||
|
||||
return nil
|
||||
|
||||
case *types.BondTx:
|
||||
valInfo := blockCache.State().GetValidatorInfo(tx.PubKey.Address())
|
||||
if valInfo != nil {
|
||||
|
Reference in New Issue
Block a user