mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-26 11:11:41 +00:00
update namereg with longer names, more allowed chars
This commit is contained in:
@ -198,7 +198,7 @@ func testNameReg(t *testing.T, typ string) {
|
||||
data := "if not now, when"
|
||||
fee := int64(1000)
|
||||
numDesiredBlocks := int64(2)
|
||||
amt := fee + numDesiredBlocks*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
amt := fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
|
||||
eid := types.EventStringNameReg(name)
|
||||
subscribe(t, con, eid)
|
||||
@ -243,7 +243,7 @@ func testNameReg(t *testing.T, typ string) {
|
||||
// update the data as the owner, make sure still there
|
||||
numDesiredBlocks = int64(2)
|
||||
data = "these are amongst the things I wish to bestow upon the youth of generations come: a safe supply of honey, and a better money. For what else shall they need"
|
||||
amt = fee + numDesiredBlocks*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
amt = fee + numDesiredBlocks*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
tx = makeDefaultNameTx(t, typ, name, data, amt, fee)
|
||||
broadcastTx(t, typ, tx)
|
||||
// commit block
|
||||
|
@ -543,14 +543,13 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab
|
||||
|
||||
// validate the input strings
|
||||
if err := tx.ValidateStrings(); err != nil {
|
||||
log.Info(err.Error())
|
||||
return types.ErrTxInvalidString
|
||||
return err
|
||||
}
|
||||
|
||||
value := tx.Input.Amount - tx.Fee
|
||||
|
||||
// let's say cost of a name for one block is len(data) + 32
|
||||
costPerBlock := types.NameCostPerBlock * types.NameCostPerByte * tx.BaseEntryCost()
|
||||
costPerBlock := types.NameCostPerBlock(types.NameBaseCost(tx.Name, tx.Data))
|
||||
expiresIn := int(value / costPerBlock)
|
||||
lastBlockHeight := _s.LastBlockHeight
|
||||
|
||||
@ -591,7 +590,7 @@ func ExecTx(blockCache *BlockCache, tx types.Tx, runCall bool, evc events.Fireab
|
||||
} else {
|
||||
// since the size of the data may have changed
|
||||
// we use the total amount of "credit"
|
||||
oldCredit := int64(entry.Expires-lastBlockHeight) * types.BaseEntryCost(entry.Name, entry.Data)
|
||||
oldCredit := int64(entry.Expires-lastBlockHeight) * types.NameBaseCost(entry.Name, entry.Data)
|
||||
credit := oldCredit + value
|
||||
expiresIn = int(credit / costPerBlock)
|
||||
if expiresIn < types.MinNameRegistrationPeriod {
|
||||
|
@ -219,12 +219,12 @@ func TestNameTxs(t *testing.T) {
|
||||
startingBlock := state.LastBlockHeight
|
||||
|
||||
// try some bad names. these should all fail
|
||||
names := []string{"", "\n", "123#$%", "\x00", string([]byte{20, 40, 60, 80}), "baffledbythespectacleinallofthisyouseeehesaidwithouteyes", "no spaces please"}
|
||||
names := []string{"", "\n", "123#$%", "\x00", string([]byte{20, 40, 60, 80}), "baffledbythespectacleinallofthisyouseeehesaidwithouteyessurprised", "no spaces please"}
|
||||
data := "something about all this just doesn't feel right."
|
||||
fee := int64(1000)
|
||||
numDesiredBlocks := 5
|
||||
for _, name := range names {
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee)
|
||||
tx.Sign(state.ChainID, privAccounts[0])
|
||||
|
||||
@ -237,7 +237,7 @@ func TestNameTxs(t *testing.T) {
|
||||
name := "hold_it_chum"
|
||||
datas := []string{"cold&warm", "!@#$%^&*()", "<<<>>>>", "because why would you ever need a ~ or a & or even a % in a json file? make your case and we'll talk"}
|
||||
for _, data := range datas {
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee)
|
||||
tx.Sign(state.ChainID, privAccounts[0])
|
||||
|
||||
@ -266,9 +266,9 @@ func TestNameTxs(t *testing.T) {
|
||||
}
|
||||
|
||||
// try a good one, check data, owner, expiry
|
||||
name = "looking_good/karaoke_bar"
|
||||
data = "on this side of neptune there are 1234567890 people: first is OMNIVORE. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')"
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
name = "@looking_good/karaoke_bar.broadband"
|
||||
data = "on this side of neptune there are 1234567890 people: first is OMNIVORE+-3. Or is it. Ok this is pretty restrictive. No exclamations :(. Faces tho :')"
|
||||
amt := fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
tx, _ := types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee)
|
||||
tx.Sign(state.ChainID, privAccounts[0])
|
||||
if err := execTxWithState(state, tx, true); err != nil {
|
||||
@ -325,7 +325,7 @@ func TestNameTxs(t *testing.T) {
|
||||
data = "In the beginning there was no thing, not even the beginning. It hadn't been here, no there, nor for that matter anywhere, not especially because it had not to even exist, let alone to not. Nothing especially odd about that."
|
||||
oldCredit := amt - fee
|
||||
numDesiredBlocks = 10
|
||||
amt = fee + (int64(numDesiredBlocks)*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data) - oldCredit)
|
||||
amt = fee + (int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data) - oldCredit)
|
||||
tx, _ = types.NewNameTx(state, privAccounts[1].PubKey, name, data, amt, fee)
|
||||
tx.Sign(state.ChainID, privAccounts[1])
|
||||
if err := execTxWithState(state, tx, true); err != nil {
|
||||
@ -351,7 +351,7 @@ func TestNameTxs(t *testing.T) {
|
||||
// test removal by key1 after expiry
|
||||
name = "looking_good/karaoke_bar"
|
||||
data = "some data"
|
||||
amt = fee + int64(numDesiredBlocks)*types.NameCostPerByte*types.NameCostPerBlock*types.BaseEntryCost(name, data)
|
||||
amt = fee + int64(numDesiredBlocks)*types.NameByteCostMultiplier*types.NameBlockCostMultiplier*types.NameBaseCost(name, data)
|
||||
tx, _ = types.NewNameTx(state, privAccounts[0].PubKey, name, data, amt, fee)
|
||||
tx.Sign(state.ChainID, privAccounts[0])
|
||||
if err := execTxWithState(state, tx, true); err != nil {
|
||||
@ -511,7 +511,7 @@ proof-of-work chain as proof of what happened while they were gone `
|
||||
tx.Input.Sequence += 1
|
||||
tx.Input.Signature = privAccounts[0].Sign(state.ChainID, tx)
|
||||
err = execTxWithState(state, tx, true)
|
||||
if err != types.ErrTxInvalidString {
|
||||
if _, ok := err.(types.ErrTxInvalidString); !ok {
|
||||
t.Errorf("Expected invalid string error. Got: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -12,16 +12,16 @@ var (
|
||||
|
||||
// cost for storing a name for a block is
|
||||
// CostPerBlock*CostPerByte*(len(data) + 32)
|
||||
NameCostPerByte int64 = 1
|
||||
NameCostPerBlock int64 = 1
|
||||
NameByteCostMultiplier int64 = 1
|
||||
NameBlockCostMultiplier int64 = 1
|
||||
|
||||
MaxNameLength = 32
|
||||
MaxNameLength = 64
|
||||
MaxDataLength = 1 << 16
|
||||
|
||||
// Name should be alphanum, underscore, slash
|
||||
// Name should be file system lik
|
||||
// Data should be anything permitted in JSON
|
||||
regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/]*$")
|
||||
regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-"':,\n\t.{}()\[\]]*$`)
|
||||
regexpAlphaNum = regexp.MustCompile("^[a-zA-Z0-9._/-@]*$")
|
||||
regexpJSON = regexp.MustCompile(`^[a-zA-Z0-9_/ \-+"':,\n\t.{}()\[\]]*$`)
|
||||
)
|
||||
|
||||
// filter strings
|
||||
@ -34,10 +34,14 @@ func validateNameRegEntryData(data string) bool {
|
||||
}
|
||||
|
||||
// base cost is "effective" number of bytes
|
||||
func BaseEntryCost(name, data string) int64 {
|
||||
func NameBaseCost(name, data string) int64 {
|
||||
return int64(len(data) + 32)
|
||||
}
|
||||
|
||||
func NameCostPerBlock(baseCost int64) int64 {
|
||||
return NameBlockCostMultiplier * NameByteCostMultiplier * baseCost
|
||||
}
|
||||
|
||||
type NameRegEntry struct {
|
||||
Name string `json:"name"` // registered name for the entry
|
||||
Owner []byte `json:"owner"` // address that created the entry
|
||||
|
23
types/tx.go
23
types/tx.go
@ -22,10 +22,17 @@ var (
|
||||
ErrTxUnknownPubKey = errors.New("Error unknown pubkey")
|
||||
ErrTxInvalidPubKey = errors.New("Error invalid pubkey")
|
||||
ErrTxInvalidSignature = errors.New("Error invalid signature")
|
||||
ErrTxInvalidString = errors.New("Error invalid string")
|
||||
ErrTxPermissionDenied = errors.New("Error permission denied")
|
||||
)
|
||||
|
||||
type ErrTxInvalidString struct {
|
||||
Msg string
|
||||
}
|
||||
|
||||
func (e ErrTxInvalidString) Error() string {
|
||||
return e.Msg
|
||||
}
|
||||
|
||||
type ErrTxInvalidSequence struct {
|
||||
Got int
|
||||
Expected int
|
||||
@ -220,30 +227,26 @@ func (tx *NameTx) WriteSignBytes(chainID string, w io.Writer, n *int64, err *err
|
||||
|
||||
func (tx *NameTx) ValidateStrings() error {
|
||||
if len(tx.Name) == 0 {
|
||||
return errors.New("Name must not be empty")
|
||||
return ErrTxInvalidString{"Name must not be empty"}
|
||||
}
|
||||
if len(tx.Name) > MaxNameLength {
|
||||
return errors.New(Fmt("Name is too long. Max %d bytes", MaxNameLength))
|
||||
return ErrTxInvalidString{Fmt("Name is too long. Max %d bytes", MaxNameLength)}
|
||||
}
|
||||
if len(tx.Data) > MaxDataLength {
|
||||
return errors.New(Fmt("Data is too long. Max %d bytes", MaxDataLength))
|
||||
return ErrTxInvalidString{Fmt("Data is too long. Max %d bytes", MaxDataLength)}
|
||||
}
|
||||
|
||||
if !validateNameRegEntryName(tx.Name) {
|
||||
return errors.New(Fmt("Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, and forward slashes allowed", tx.Name))
|
||||
return ErrTxInvalidString{Fmt("Invalid characters found in NameTx.Name (%s). Only alphanumeric, underscores, dashes, forward slashes, and @ are allowed", tx.Name)}
|
||||
}
|
||||
|
||||
if !validateNameRegEntryData(tx.Data) {
|
||||
return errors.New(Fmt("Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data))
|
||||
return ErrTxInvalidString{Fmt("Invalid characters found in NameTx.Data (%s). Only the kind of things found in a JSON file are allowed", tx.Data)}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tx *NameTx) BaseEntryCost() int64 {
|
||||
return BaseEntryCost(tx.Name, tx.Data)
|
||||
}
|
||||
|
||||
func (tx *NameTx) String() string {
|
||||
return Fmt("NameTx{%v -> %s: %s}", tx.Input, tx.Name, tx.Data)
|
||||
}
|
||||
|
Reference in New Issue
Block a user