Skip to content

Commit 6d6b79c

Browse files
committed
fix: rework 7 to 8 logic
1 parent 7376e6c commit 6d6b79c

File tree

2 files changed

+182
-45
lines changed

2 files changed

+182
-45
lines changed

ipfs-7-to-8/migration/config_conv.go

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"io/ioutil"
88
"os"
99
"strings"
10-
11-
"github.com/ipfs/go-cid"
1210
)
1311

1412
var (
@@ -94,17 +92,37 @@ func convert(in io.Reader, out io.Writer, convFunc convFunc) error {
9492
}
9593

9694
func ver7to8(bootstrap []string) []string {
95+
hasSmallKey := false
96+
for _, addr := range bootstrap {
97+
if ok, _ := isDNSBootstrapPeer(addr); ok {
98+
// Already has a dnsaddr key so assume the user has custom config
99+
// that we shouldn't override
100+
return bootstrap
101+
}
102+
if ok, _ := isSmallKeyPeer(addr); ok {
103+
hasSmallKey = true
104+
}
105+
}
106+
107+
if !hasSmallKey {
108+
// There are no peers with small keys in the bootstrap list so assume
109+
// the user has a custom config that we shouldn't override
110+
return bootstrap
111+
}
112+
97113
// Make sure the dnsaddrs bootstrap peers are included
98114
var res []string
99115
for _, p := range dnsBootstrapPeers {
100116
res = append(res, fmt.Sprintf("/dnsaddr/%s/p2p/%s", dnsAddr, p))
101117
}
102118

103-
// Filter out peers that we added above, or that have an ID known to belong
104-
// to a peer with a small key
119+
// Filter out dnsaddr peers that we added above, or that have an ID known
120+
// to belong to a peer with a small key.
121+
// If we don't recognize the address format (err != nil), assume that the
122+
// user changed it for a reason and leave it in there.
105123
for _, addr := range bootstrap {
106-
if ok, err := isDNSBootstrapPeer(addr); !ok && err == nil {
107-
if ok, err = isSmallKeyPeer(addr); !ok && err == nil {
124+
if isDNSAddr, err := isDNSBootstrapPeer(addr); !isDNSAddr || err != nil {
125+
if isSmall, err := isSmallKeyPeer(addr); !isSmall || err != nil {
108126
// Replace /ipfs with /p2p
109127
addr = strings.Replace(addr, "/ipfs", "/p2p", -1)
110128
res = append(res, addr)
@@ -116,51 +134,70 @@ func ver7to8(bootstrap []string) []string {
116134
}
117135

118136
func ver8to7(bootstrap []string) []string {
119-
// Make sure the old addresses are included
120-
res := append([]string{}, oldBootstrapAddrs...)
137+
// If the config doesn't have the new DNS addresses then assume it hasn't
138+
// been updated to version 8 and bail out
139+
hasDNSAddrs := false
140+
for _, addr := range bootstrap {
141+
if ok, _ := isDNSBootstrapPeer(addr); ok {
142+
hasDNSAddrs = true
143+
}
144+
}
145+
if !hasDNSAddrs {
146+
return bootstrap
147+
}
121148

122-
oldPeerIDs := make(map[string]struct{})
123-
for _, addr := range oldBootstrapAddrs {
124-
pid, err := getAddrPeerID(addr)
125-
if err != nil {
126-
panic(err)
149+
// Extract peer IDs from old bootstrap addresses
150+
var oldBootstrapPeerIDs []string
151+
for _, oldAddr := range oldBootstrapAddrs {
152+
if p, err := getAddrPeerID(oldAddr); err == nil {
153+
oldBootstrapPeerIDs = append(oldBootstrapPeerIDs, p)
127154
}
128-
oldPeerIDs[pid] = struct{}{}
129155
}
130156

131-
// Filter out old addresses added above, and addresses with the new DNS
132-
// addresses
133-
for _, btAddr := range bootstrap {
134-
pid, err := getAddrPeerID(btAddr)
135-
if err == nil {
136-
if _, ok := oldPeerIDs[pid]; !ok && !strings.Contains(btAddr, dnsAddr) {
137-
res = append(res, btAddr)
138-
}
157+
// Make sure the old addresses are included in the result
158+
res := append([]string{}, oldBootstrapAddrs...)
159+
160+
// Filter out old addresses added above
161+
for _, addr := range bootstrap {
162+
isOldPeer, err := addrPeerIDInList(oldBootstrapPeerIDs, addr)
163+
164+
// If we don't recognize the address format, just assume the user
165+
// has changed it on purpose and include it in the results
166+
if !isOldPeer || err != nil {
167+
res = append(res, addr)
139168
}
140169
}
141170

142171
return res
143172
}
144173

174+
func parseErr(addr string) error {
175+
return fmt.Errorf("Could not parse peer ID from addr '%s'", addr)
176+
}
177+
145178
func getAddrPeerID(addr string) (string, error) {
146179
// eg /ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ
147180
parts := strings.Split(addr, "/")
148-
if len(parts) == 0 {
149-
return "", fmt.Errorf("Could not parse peer ID from addr '%s'", addr)
181+
if len(parts) < 2 {
182+
return "", parseErr(addr)
150183
}
151-
last := parts[len(parts)-1]
152-
if _, err := cid.Decode(last); err != nil {
153-
return "", fmt.Errorf("Could not parse peer ID from addr '%s'", addr)
184+
185+
// Just verify that the address ends with /p2p/something or /ipfs/something
186+
peerType := parts[len(parts)-2]
187+
if peerType != "p2p" && peerType != "ipfs" {
188+
return "", parseErr(addr)
154189
}
190+
191+
last := parts[len(parts)-1]
155192
return last, nil
156193
}
157194

158-
func addrPeerIDInList(peers []string, addr string) (bool, error) {
195+
func addrPeerIDInList(peerIDs []string, addr string) (bool, error) {
159196
addrID, err := getAddrPeerID(addr)
160197
if err != nil {
161198
return false, err
162199
}
163-
for _, p := range peers {
200+
for _, p := range peerIDs {
164201
if p == addrID {
165202
return true, nil
166203
}

ipfs-7-to-8/migration/config_conv_test.go

Lines changed: 116 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ import (
88
"testing"
99
)
1010

11-
func arrayMatch(a []interface{}, b []string) bool {
11+
func arrayMatch(a []string, b []string) bool {
1212
if len(a) != len(b) {
1313
return false
1414
}
1515
am := make(map[string]struct{})
1616
for _, i := range a {
17-
am[i.(string)] = struct{}{}
17+
am[i] = struct{}{}
1818
}
1919
for _, i := range b {
2020
if _, ok := am[i]; !ok {
@@ -30,34 +30,130 @@ func matchesExpected(t *testing.T, res []byte, exp []string) bool {
3030
t.Fatal(err)
3131
}
3232

33-
return arrayMatch(confMap["Bootstrap"].([]interface{}), exp)
33+
var as []string
34+
for _, i := range confMap["Bootstrap"].([]interface{}) {
35+
as = append(as, i.(string))
36+
}
37+
38+
return arrayMatch(as, exp)
3439
}
3540

3641
func TestOldToNew(t *testing.T) {
37-
in := strings.NewReader(oldConfig)
42+
in := strings.NewReader(v7config)
3843
out := new(bytes.Buffer)
3944
if err := convert(in, out, ver7to8); err != nil {
4045
t.Fatal(err)
4146
}
4247

43-
if !matchesExpected(t, out.Bytes(), expectedMigrateForward) {
44-
t.Fatal(fmt.Errorf("Converted does not match expected result\n%s\n%s\n", out.String(), expectedMigrateForward))
48+
if !matchesExpected(t, out.Bytes(), expectedv7tov8) {
49+
t.Fatal(fmt.Errorf("Converted does not match expected result\n%s\n%s\n", out.String(), expectedv7tov8))
4550
}
4651
}
4752

4853
func TestNewToOld(t *testing.T) {
49-
in := strings.NewReader(newConfig)
54+
in := strings.NewReader(v8config)
5055
out := new(bytes.Buffer)
5156
if err := convert(in, out, ver8to7); err != nil {
5257
t.Fatal(err)
5358
}
5459

55-
if !matchesExpected(t, out.Bytes(), expectedMigrateBackward) {
56-
t.Fatal(fmt.Errorf("Converted does not match expected result\n%s\n%s\n", out.String(), expectedMigrateBackward))
60+
if !matchesExpected(t, out.Bytes(), expectedv8tov7) {
61+
t.Fatal(fmt.Errorf("Converted does not match expected result\n%s\n%s\n", out.String(), expectedv8tov7))
62+
}
63+
}
64+
65+
func TestForward(t *testing.T) {
66+
bootstrap := []string{
67+
// peer with old key (should be filtered out)
68+
"/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
69+
// peer with unknown key (should be included)
70+
"/ip4/178.62.158.248/tcp/4001/p2p/QmSomeNewKeygSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
71+
// unrecognized format (should be included)
72+
"/ip4/178.62.158.248/tcp/4001/wut/some-new-format",
73+
}
74+
exp := []string{
75+
// new dnsaddr peers
76+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
77+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
78+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
79+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
80+
// peer with unknown key
81+
"/ip4/178.62.158.248/tcp/4001/p2p/QmSomeNewKeygSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
82+
// unrecognized format
83+
"/ip4/178.62.158.248/tcp/4001/wut/some-new-format",
84+
}
85+
if res := ver7to8(bootstrap); !arrayMatch(exp, res) {
86+
fmt.Println(res)
87+
t.Fatal("Expected forward conversion to succeed")
5788
}
5889
}
5990

60-
var oldConfig = `{
91+
func TestForwardIgnoreConfWithDNSAddrsAlready(t *testing.T) {
92+
bootstrap := []string{
93+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
94+
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
95+
}
96+
if res := ver7to8(bootstrap); !arrayMatch(bootstrap, res) {
97+
t.Fatal("Expected conf with dnsaddr to be ignored")
98+
}
99+
}
100+
101+
func TestForwardIgnoreConfWithNoSmallKeys(t *testing.T) {
102+
bootstrap := []string{
103+
"/ip4/104.131.131.82/tcp/4001/p2p/QmBigKeyvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
104+
}
105+
if res := ver7to8(bootstrap); !arrayMatch(bootstrap, res) {
106+
t.Fatal("Expected conf with dnsaddr to be ignored")
107+
}
108+
}
109+
110+
func TestBackward(t *testing.T) {
111+
bootstrap := []string{
112+
// new dnsaddr peers (should be included)
113+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
114+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
115+
// peer with old key (should be included)
116+
"/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
117+
// peer with unknown key (should be included)
118+
"/ip4/178.62.158.248/tcp/4001/p2p/QmSomeNewKeygSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
119+
// unrecognized format (should be included)
120+
"/ip4/178.62.158.248/tcp/4001/wut/some-new-format",
121+
}
122+
exp := []string{
123+
// new dnsaddr peers
124+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
125+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
126+
// old addresses
127+
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
128+
"/ip4/104.236.179.241/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
129+
"/ip4/128.199.219.111/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
130+
"/ip4/104.236.76.40/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
131+
"/ip4/178.62.158.247/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
132+
"/ip6/2604:a880:1:20::203:d001/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",
133+
"/ip6/2400:6180:0:d0::151:6001/tcp/4001/p2p/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu",
134+
"/ip6/2604:a880:800:10::4a:5001/tcp/4001/p2p/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64",
135+
"/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/p2p/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
136+
// peer with unknown key
137+
"/ip4/178.62.158.248/tcp/4001/p2p/QmSomeNewKeygSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd",
138+
// unrecognized format
139+
"/ip4/178.62.158.248/tcp/4001/wut/some-new-format",
140+
}
141+
if res := ver8to7(bootstrap); !arrayMatch(exp, res) {
142+
fmt.Println(res)
143+
t.Fatal("Expected backward conversion to succeed")
144+
}
145+
}
146+
147+
func TestBackwardIgnoreConfWithNoDNSAddr(t *testing.T) {
148+
bootstrap := []string{
149+
"/ip4/104.131.131.82/tcp/4001/p2p/QmSomeKeyV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
150+
}
151+
if res := ver8to7(bootstrap); !arrayMatch(bootstrap, res) {
152+
t.Fatal("Expected conf with no dnsaddr to be ignored")
153+
}
154+
}
155+
156+
var v7config = `{
61157
"Some": {
62158
"Other": "Config"
63159
},
@@ -83,7 +179,15 @@ var oldConfig = `{
83179
}
84180
`
85181

86-
var newConfig = `{
182+
var expectedv7tov8 = []string{
183+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
184+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
185+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
186+
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
187+
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
188+
}
189+
190+
var v8config = `{
87191
"Some": {
88192
"Other": "Config"
89193
},
@@ -98,15 +202,11 @@ var newConfig = `{
98202
}
99203
`
100204

101-
var expectedMigrateForward = []string{
205+
var expectedv8tov7 = []string{
102206
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
103207
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
104208
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
105209
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
106-
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
107-
}
108-
109-
var expectedMigrateBackward = []string{
110210
"/ip4/104.131.131.83/tcp/4001/p2p/QmcafeMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLaaaa",
111211
"/ip4/104.131.131.82/tcp/4001/p2p/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
112212
"/ip4/104.236.179.241/tcp/4001/p2p/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM",

0 commit comments

Comments
 (0)