Skip to content

Commit

Permalink
nns: Accept expiration period in renew
Browse files Browse the repository at this point in the history
Port neo-project/non-native-contracts#13.

Signed-off-by: Anna Shaleva <[email protected]>
  • Loading branch information
AnnaShaleva authored and roman-khimov committed Nov 12, 2024
1 parent 280a51d commit 67f42e1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 8 deletions.
2 changes: 2 additions & 0 deletions contracts/nns/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ permissions:
- hash: fffdc93764dbaddd97c48f252a53ea4643faa3fd
methods: ["update"]
- methods: ["onNEP11Payment"]
overloads:
renewDefault: renew
29 changes: 24 additions & 5 deletions contracts/nns/contract.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ const (
millisecondsInSecond = 1000
// millisecondsInYear is amount of milliseconds per year.
millisecondsInYear = int64(365 * 24 * 3600 * millisecondsInSecond)
// millisecondsInTenYears is the amount of milliseconds per ten years.
millisecondsInTenYears = 10 * millisecondsInYear
)

// RecordState is a type that registered entities are saved to.
Expand Down Expand Up @@ -461,16 +463,33 @@ func saveDomain(ctx storage.Context, name, email string, refresh, retry, expire,
putSoaRecord(ctx, name, email, refresh, retry, expire, ttl)
}

// Renew increases domain expiration date.
func Renew(name string) int64 {
// RenewDefault increases domain expiration date for 1 year and returns
// the new expriration timestamp.
func RenewDefault(name string) int64 {
return Renew(name, 1)
}

// Renew increases domain expiration date up to the specified amount of years
// (from 1 to 10, can't renew for more than 10 years). Returns new expiration
// timestamp.
func Renew(name string, years int) int64 {
if years < 1 || years > 10 {
panic("invalid renewal period value")
}
if len(name) > maxDomainNameLength {
panic("too long name")
panic("invalid domain name format")
}
runtime.BurnGas(GetPrice())
runtime.BurnGas(int(GetPrice()) * years)
ctx := storage.GetContext()
ns := getNameState(ctx, []byte(name))
ns.checkAdmin()
ns.Expiration += millisecondsInYear
ns.Expiration += millisecondsInYear * int64(years)

fragments := splitAndCheck(name)
// TLDs are not subject to this check.
if len(fragments) > 1 && ns.Expiration > int64(runtime.GetTime())+millisecondsInTenYears {
panic("10 years of expiration period at max is allowed")
}
putNameState(ctx, ns)
return ns.Expiration
}
Expand Down
15 changes: 12 additions & 3 deletions tests/nns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,16 +401,25 @@ func TestNNSRenew(t *testing.T) {

const msPerYear = 365 * 24 * time.Hour / time.Millisecond
b := c.TopBlock(t)
ts := b.Timestamp + uint64(expire*1000) + uint64(msPerYear)
renewalPeriod := int64(2)
ts := b.Timestamp + uint64(expire*1000) + uint64(msPerYear)*uint64(renewalPeriod)

cAcc := c.WithSigners(acc)
cAcc.InvokeFail(t, "not witnessed by admin", "renew", "testdomain.com")
c1.Invoke(t, ts, "renew", "testdomain.com")
cAcc.InvokeFail(t, "not witnessed by admin", "renew", "testdomain.com", renewalPeriod)
c1.Invoke(t, ts, "renew", "testdomain.com", renewalPeriod)
expected := stackitem.NewMapWithValue([]stackitem.MapElement{
{Key: stackitem.Make("name"), Value: stackitem.Make("testdomain.com")},
{Key: stackitem.Make("expiration"), Value: stackitem.Make(ts)},
{Key: stackitem.Make("admin"), Value: stackitem.Null{}}})
cAcc.Invoke(t, expected, "properties", "testdomain.com")

// Invalid renewal period.
c1.InvokeFail(t, "invalid renewal period value", "renew", "testdomain.com", 11)
// Too large expiration period.
c1.InvokeFail(t, "10 years of expiration period at max is allowed", "renew", "testdomain.com", 10)

// Default renewal period.
c1.Invoke(t, ts+uint64(msPerYear), "renew", "testdomain.com")
}

func TestNNSResolve(t *testing.T) {
Expand Down

0 comments on commit 67f42e1

Please sign in to comment.