diff --git a/cmd/devp2p/dns_route53.go b/cmd/devp2p/dns_route53.go
index 71118be543..c5f99529b8 100644
--- a/cmd/devp2p/dns_route53.go
+++ b/cmd/devp2p/dns_route53.go
@@ -32,9 +32,13 @@ import (
"gopkg.in/urfave/cli.v1"
)
-// The Route53 limits change sets to this size. DNS changes need to be split
-// up into multiple batches to work around the limit.
-const route53ChangeLimit = 30000
+const (
+ // Route53 limits change sets to 32k of 'RDATA size'. Change sets are also limited to
+ // 1000 items. UPSERTs count double.
+ // https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/DNSLimitations.html#limits-api-requests-changeresourcerecordsets
+ route53ChangeSizeLimit = 32000
+ route53ChangeCountLimit = 1000
+)
var (
route53AccessKeyFlag = cli.StringFlag{
@@ -102,7 +106,7 @@ func (c *route53Client) deploy(name string, t *dnsdisc.Tree) error {
}
// Submit change batches.
- batches := splitChanges(changes, route53ChangeLimit)
+ batches := splitChanges(changes, route53ChangeSizeLimit, route53ChangeCountLimit)
for i, changes := range batches {
log.Info(fmt.Sprintf("Submitting %d changes to Route53", len(changes)))
batch := new(route53.ChangeBatch)
@@ -176,7 +180,7 @@ func (c *route53Client) computeChanges(name string, records map[string]string, e
// Entry is unknown, push a new one
log.Info(fmt.Sprintf("Creating %s = %q", path, val))
changes = append(changes, newTXTChange("CREATE", path, ttl, splitTXT(val)))
- } else if prevValue != val {
+ } else if prevValue != val || prevRecords.ttl != ttl {
// Entry already exists, only change its content.
log.Info(fmt.Sprintf("Updating %s from %q to %q", path, prevValue, val))
changes = append(changes, newTXTChange("UPSERT", path, ttl, splitTXT(val)))
@@ -212,18 +216,26 @@ func sortChanges(changes []*route53.Change) {
// splitChanges splits up DNS changes such that each change batch
// is smaller than the given RDATA limit.
-func splitChanges(changes []*route53.Change, limit int) [][]*route53.Change {
- var batches [][]*route53.Change
- var batchSize int
+func splitChanges(changes []*route53.Change, sizeLimit, countLimit int) [][]*route53.Change {
+ var (
+ batches [][]*route53.Change
+ batchSize int
+ batchCount int
+ )
for _, ch := range changes {
// Start new batch if this change pushes the current one over the limit.
- size := changeSize(ch)
- if len(batches) == 0 || batchSize+size > limit {
+ count := changeCount(ch)
+ size := changeSize(ch) * count
+ overSize := batchSize+size > sizeLimit
+ overCount := batchCount+count > countLimit
+ if len(batches) == 0 || overSize || overCount {
batches = append(batches, nil)
batchSize = 0
+ batchCount = 0
}
batches[len(batches)-1] = append(batches[len(batches)-1], ch)
batchSize += size
+ batchCount += count
}
return batches
}
@@ -239,6 +251,13 @@ func changeSize(ch *route53.Change) int {
return size
}
+func changeCount(ch *route53.Change) int {
+ if *ch.Action == "UPSERT" {
+ return 2
+ }
+ return 1
+}
+
// collectRecords collects all TXT records below the given name.
func (c *route53Client) collectRecords(name string) (map[string]recordSet, error) {
log.Info(fmt.Sprintf("Retrieving existing TXT records on %s (%s)", name, c.zoneID))
diff --git a/cmd/devp2p/dns_route53_test.go b/cmd/devp2p/dns_route53_test.go
index f6ab6c1762..a2ef3791f6 100644
--- a/cmd/devp2p/dns_route53_test.go
+++ b/cmd/devp2p/dns_route53_test.go
@@ -140,11 +140,23 @@ func TestRoute53ChangeSort(t *testing.T) {
t.Fatalf("wrong changes (got %d, want %d)", len(changes), len(wantChanges))
}
+ // Check splitting according to size.
wantSplit := [][]*route53.Change{
wantChanges[:4],
- wantChanges[4:8],
+ wantChanges[4:6],
+ wantChanges[6:],
}
- split := splitChanges(changes, 600)
+ split := splitChanges(changes, 600, 4000)
+ if !reflect.DeepEqual(split, wantSplit) {
+ t.Fatalf("wrong split batches: got %d, want %d", len(split), len(wantSplit))
+ }
+
+ // Check splitting according to count.
+ wantSplit = [][]*route53.Change{
+ wantChanges[:5],
+ wantChanges[5:],
+ }
+ split = splitChanges(changes, 10000, 6)
if !reflect.DeepEqual(split, wantSplit) {
t.Fatalf("wrong split batches: got %d, want %d", len(split), len(wantSplit))
}
diff --git a/cmd/devp2p/dnscmd.go b/cmd/devp2p/dnscmd.go
index 7c9ccd31f4..8ca31504d3 100644
--- a/cmd/devp2p/dnscmd.go
+++ b/cmd/devp2p/dnscmd.go
@@ -97,8 +97,8 @@ var (
)
const (
- rootTTL = 1
- treeNodeTTL = 2147483647
+ rootTTL = 30 * 60 // 30 min
+ treeNodeTTL = 4 * 7 * 24 * 60 * 60 // 4 weeks
)
// dnsSync performs dnsSyncCommand.
diff --git a/metrics/cpu.go b/metrics/cpu.go
index 3278d81616..72ece16e07 100644
--- a/metrics/cpu.go
+++ b/metrics/cpu.go
@@ -16,21 +16,9 @@
package metrics
-import "github.com/elastic/gosigar"
-
// CPUStats is the system and process CPU stats.
type CPUStats struct {
GlobalTime int64 // Time spent by the CPU working on all processes
GlobalWait int64 // Time spent by waiting on disk for all processes
LocalTime int64 // Time spent by the CPU working on this process
}
-
-// ReadCPUStats retrieves the current CPU stats.
-func ReadCPUStats(stats *CPUStats) {
- global := gosigar.Cpu{}
- global.Get()
-
- stats.GlobalTime = int64(global.User + global.Nice + global.Sys)
- stats.GlobalWait = int64(global.Wait)
- stats.LocalTime = getProcessCPUTime()
-}
diff --git a/metrics/cpu_disabled.go b/metrics/cpu_disabled.go
new file mode 100644
index 0000000000..6c3428993f
--- /dev/null
+++ b/metrics/cpu_disabled.go
@@ -0,0 +1,23 @@
+// Copyright 2020 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build ios
+
+package metrics
+
+// ReadCPUStats retrieves the current CPU stats. Internally this uses `gosigar`,
+// which is not supported on the platforms in this file.
+func ReadCPUStats(stats *CPUStats) {}
diff --git a/metrics/cpu_enabled.go b/metrics/cpu_enabled.go
new file mode 100644
index 0000000000..99d44e4002
--- /dev/null
+++ b/metrics/cpu_enabled.go
@@ -0,0 +1,31 @@
+// Copyright 2020 The go-ethereum Authors
+// This file is part of the go-ethereum library.
+//
+// The go-ethereum library is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// The go-ethereum library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with the go-ethereum library. If not, see .
+
+// +build !ios
+
+package metrics
+
+import "github.com/elastic/gosigar"
+
+// ReadCPUStats retrieves the current CPU stats.
+func ReadCPUStats(stats *CPUStats) {
+ global := gosigar.Cpu{}
+ global.Get()
+
+ stats.GlobalTime = int64(global.User + global.Nice + global.Sys)
+ stats.GlobalWait = int64(global.Wait)
+ stats.LocalTime = getProcessCPUTime()
+}