mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00

* Add windows to the CI * Cast syscall.Stdin into an integer * DataDir -> AppDir in service_windows.go * Rename mempool-limits package to something non-main * Close database after re-assigining to it * Up rpcTimout to 10 seconds
375 lines
12 KiB
Go
375 lines
12 KiB
Go
// Copyright (c) 2013-2014 The btcsuite developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package addressmanager
|
|
|
|
import (
|
|
"net"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/kaspanet/kaspad/app/appmessage"
|
|
"github.com/kaspanet/kaspad/infrastructure/config"
|
|
"github.com/kaspanet/kaspad/infrastructure/db/database/ldb"
|
|
"github.com/kaspanet/kaspad/util/mstime"
|
|
)
|
|
|
|
func newAddressManagerForTest(t *testing.T, testName string) (addressManager *AddressManager, teardown func()) {
|
|
cfg := config.DefaultConfig()
|
|
|
|
datadir := t.TempDir()
|
|
database, err := ldb.NewLevelDB(datadir, 8)
|
|
if err != nil {
|
|
t.Fatalf("%s: could not create a database: %s", testName, err)
|
|
}
|
|
|
|
addressManager, err = New(NewConfig(cfg), database)
|
|
if err != nil {
|
|
t.Fatalf("%s: error creating address manager: %s", testName, err)
|
|
}
|
|
|
|
return addressManager, func() {
|
|
database.Close()
|
|
}
|
|
}
|
|
|
|
func TestBestLocalAddress(t *testing.T) {
|
|
localAddrs := []appmessage.NetAddress{
|
|
{IP: net.ParseIP("192.168.0.100")},
|
|
{IP: net.ParseIP("::1")},
|
|
{IP: net.ParseIP("fe80::1")},
|
|
{IP: net.ParseIP("2001:470::1")},
|
|
}
|
|
|
|
var tests = []struct {
|
|
remoteAddr appmessage.NetAddress
|
|
want0 appmessage.NetAddress
|
|
want1 appmessage.NetAddress
|
|
want2 appmessage.NetAddress
|
|
want3 appmessage.NetAddress
|
|
}{
|
|
{
|
|
// Remote connection from public IPv4
|
|
appmessage.NetAddress{IP: net.ParseIP("204.124.8.1")},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
appmessage.NetAddress{IP: net.ParseIP("204.124.8.100")},
|
|
appmessage.NetAddress{IP: net.ParseIP("fd87:d87e:eb43:25::1")},
|
|
},
|
|
{
|
|
// Remote connection from private IPv4
|
|
appmessage.NetAddress{IP: net.ParseIP("172.16.0.254")},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
appmessage.NetAddress{IP: net.IPv4zero},
|
|
},
|
|
{
|
|
// Remote connection from public IPv6
|
|
appmessage.NetAddress{IP: net.ParseIP("2602:100:abcd::102")},
|
|
appmessage.NetAddress{IP: net.IPv6zero},
|
|
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
|
|
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
|
|
appmessage.NetAddress{IP: net.ParseIP("2001:470::1")},
|
|
},
|
|
}
|
|
|
|
amgr, teardown := newAddressManagerForTest(t, "TestGetBestLocalAddress")
|
|
defer teardown()
|
|
|
|
// Test against default when there's no address
|
|
for x, test := range tests {
|
|
got := amgr.BestLocalAddress(&test.remoteAddr)
|
|
if !test.want0.IP.Equal(got.IP) {
|
|
t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
|
|
x, test.remoteAddr.IP, test.want1.IP, got.IP)
|
|
continue
|
|
}
|
|
}
|
|
|
|
for _, localAddr := range localAddrs {
|
|
amgr.localAddresses.addLocalNetAddress(&localAddr, InterfacePrio)
|
|
}
|
|
|
|
// Test against want1
|
|
for x, test := range tests {
|
|
got := amgr.BestLocalAddress(&test.remoteAddr)
|
|
if !test.want1.IP.Equal(got.IP) {
|
|
t.Errorf("TestGetBestLocalAddress test1 #%d failed for remote address %s: want %s got %s",
|
|
x, test.remoteAddr.IP, test.want1.IP, got.IP)
|
|
continue
|
|
}
|
|
}
|
|
|
|
// Add a public IP to the list of local addresses.
|
|
localAddr := appmessage.NetAddress{IP: net.ParseIP("204.124.8.100")}
|
|
amgr.localAddresses.addLocalNetAddress(&localAddr, InterfacePrio)
|
|
|
|
// Test against want2
|
|
for x, test := range tests {
|
|
got := amgr.BestLocalAddress(&test.remoteAddr)
|
|
if !test.want2.IP.Equal(got.IP) {
|
|
t.Errorf("TestGetBestLocalAddress test2 #%d failed for remote address %s: want %s got %s",
|
|
x, test.remoteAddr.IP, test.want2.IP, got.IP)
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAddressManager(t *testing.T) {
|
|
addressManager, teardown := newAddressManagerForTest(t, "TestAddressManager")
|
|
defer teardown()
|
|
|
|
testAddress1 := &appmessage.NetAddress{IP: net.ParseIP("1.2.3.4"), Timestamp: mstime.Now()}
|
|
testAddress2 := &appmessage.NetAddress{IP: net.ParseIP("5.6.8.8"), Timestamp: mstime.Now()}
|
|
testAddress3 := &appmessage.NetAddress{IP: net.ParseIP("9.0.1.2"), Timestamp: mstime.Now()}
|
|
testAddresses := []*appmessage.NetAddress{testAddress1, testAddress2, testAddress3}
|
|
|
|
// Add a few addresses
|
|
err := addressManager.AddAddresses(testAddresses...)
|
|
if err != nil {
|
|
t.Fatalf("AddAddresses() failed: %s", err)
|
|
}
|
|
|
|
// Make sure that all the addresses are returned
|
|
addresses := addressManager.Addresses()
|
|
if len(testAddresses) != len(addresses) {
|
|
t.Fatalf("Unexpected amount of addresses returned from Addresses. "+
|
|
"Want: %d, got: %d", len(testAddresses), len(addresses))
|
|
}
|
|
for _, testAddress := range testAddresses {
|
|
found := false
|
|
for _, address := range addresses {
|
|
if reflect.DeepEqual(testAddress, address) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatalf("Address %s not returned from Addresses().", testAddress.IP)
|
|
}
|
|
}
|
|
|
|
// Remove an address
|
|
addressToRemove := testAddress2
|
|
err = addressManager.RemoveAddress(addressToRemove)
|
|
if err != nil {
|
|
t.Fatalf("RemoveAddress() failed: %s", err)
|
|
}
|
|
|
|
// Make sure that the removed address is not returned
|
|
addresses = addressManager.Addresses()
|
|
if len(addresses) != len(testAddresses)-1 {
|
|
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
|
|
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
|
|
}
|
|
for _, address := range addresses {
|
|
if reflect.DeepEqual(addressToRemove, address) {
|
|
t.Fatalf("Removed addresses %s returned from Addresses()", addressToRemove.IP)
|
|
}
|
|
}
|
|
|
|
// Add that address back
|
|
err = addressManager.AddAddress(addressToRemove)
|
|
if err != nil {
|
|
t.Fatalf("AddAddress() failed: %s", err)
|
|
}
|
|
|
|
// Ban a different address
|
|
addressToBan := testAddress3
|
|
err = addressManager.Ban(addressToBan)
|
|
if err != nil {
|
|
t.Fatalf("Ban() failed: %s", err)
|
|
}
|
|
|
|
// Make sure that the banned address is not returned
|
|
addresses = addressManager.Addresses()
|
|
if len(addresses) != len(testAddresses)-1 {
|
|
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
|
|
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
|
|
}
|
|
for _, address := range addresses {
|
|
if reflect.DeepEqual(addressToBan, address) {
|
|
t.Fatalf("Banned addresses %s returned from Addresses()", addressToBan.IP)
|
|
}
|
|
}
|
|
|
|
// Check that the address is banned
|
|
isBanned, err := addressManager.IsBanned(addressToBan)
|
|
if err != nil {
|
|
t.Fatalf("IsBanned() failed: %s", err)
|
|
}
|
|
if !isBanned {
|
|
t.Fatalf("Adderss %s is unexpectedly not banned", addressToBan.IP)
|
|
}
|
|
|
|
// Check that BannedAddresses() returns the banned address
|
|
bannedAddresses := addressManager.BannedAddresses()
|
|
if len(bannedAddresses) != 1 {
|
|
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
|
|
"Want: %d, got: %d", 1, len(bannedAddresses))
|
|
}
|
|
if !reflect.DeepEqual(addressToBan, bannedAddresses[0]) {
|
|
t.Fatalf("Banned address %s not returned from BannedAddresses()", addressToBan.IP)
|
|
}
|
|
|
|
// Unban the address
|
|
err = addressManager.Unban(addressToBan)
|
|
if err != nil {
|
|
t.Fatalf("Unban() failed: %s", err)
|
|
}
|
|
|
|
// Check that BannedAddresses() not longer returns the banned address
|
|
bannedAddresses = addressManager.BannedAddresses()
|
|
if len(bannedAddresses) != 0 {
|
|
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
|
|
"Want: %d, got: %d", 0, len(bannedAddresses))
|
|
}
|
|
}
|
|
|
|
func TestRestoreAddressManager(t *testing.T) {
|
|
cfg := config.DefaultConfig()
|
|
|
|
// Create an empty database
|
|
datadir := t.TempDir()
|
|
database, err := ldb.NewLevelDB(datadir, 8)
|
|
if err != nil {
|
|
t.Fatalf("Could not create a database: %s", err)
|
|
}
|
|
defer database.Close()
|
|
|
|
// Create an addressManager with the empty database
|
|
addressManager, err := New(NewConfig(cfg), database)
|
|
if err != nil {
|
|
t.Fatalf("Error creating address manager: %s", err)
|
|
}
|
|
|
|
testAddress1 := &appmessage.NetAddress{IP: net.ParseIP("1.2.3.4"), Timestamp: mstime.Now()}
|
|
testAddress2 := &appmessage.NetAddress{IP: net.ParseIP("5.6.8.8"), Timestamp: mstime.Now()}
|
|
testAddress3 := &appmessage.NetAddress{IP: net.ParseIP("9.0.1.2"), Timestamp: mstime.Now()}
|
|
testAddresses := []*appmessage.NetAddress{testAddress1, testAddress2, testAddress3}
|
|
|
|
// Add some addresses
|
|
err = addressManager.AddAddresses(testAddresses...)
|
|
if err != nil {
|
|
t.Fatalf("AddAddresses() failed: %s", err)
|
|
}
|
|
|
|
// Ban one of the addresses
|
|
addressToBan := testAddress1
|
|
err = addressManager.Ban(addressToBan)
|
|
if err != nil {
|
|
t.Fatalf("Ban() failed: %s", err)
|
|
}
|
|
|
|
// Close the database
|
|
err = database.Close()
|
|
if err != nil {
|
|
t.Fatalf("Close() failed: %s", err)
|
|
}
|
|
|
|
// Reopen the database
|
|
database, err = ldb.NewLevelDB(datadir, 8)
|
|
if err != nil {
|
|
t.Fatalf("Could not create a database: %s", err)
|
|
}
|
|
defer database.Close()
|
|
|
|
// Recreate an addressManager with a the previous database
|
|
addressManager, err = New(NewConfig(cfg), database)
|
|
if err != nil {
|
|
t.Fatalf("Error creating address manager: %s", err)
|
|
}
|
|
|
|
// Make sure that Addresses() returns the correct addresses
|
|
addresses := addressManager.Addresses()
|
|
if len(addresses) != len(testAddresses)-1 {
|
|
t.Fatalf("Unexpected amount of addresses returned from Addresses(). "+
|
|
"Want: %d, got: %d", len(addresses), len(testAddresses)-1)
|
|
}
|
|
for _, address := range addresses {
|
|
if reflect.DeepEqual(addressToBan, address) {
|
|
t.Fatalf("Banned addresses %s returned from Addresses()", addressToBan.IP)
|
|
}
|
|
}
|
|
|
|
// Make sure that BannedAddresses() returns the correct addresses
|
|
bannedAddresses := addressManager.BannedAddresses()
|
|
if len(bannedAddresses) != 1 {
|
|
t.Fatalf("Unexpected amount of addresses returned from BannedAddresses(). "+
|
|
"Want: %d, got: %d", 1, len(bannedAddresses))
|
|
}
|
|
if !reflect.DeepEqual(addressToBan, bannedAddresses[0]) {
|
|
t.Fatalf("Banned address %s not returned from BannedAddresses()", addressToBan.IP)
|
|
}
|
|
}
|
|
|
|
func TestOverfillAddressManager(t *testing.T) {
|
|
addressManager, teardown := newAddressManagerForTest(t, "TestAddressManager")
|
|
defer teardown()
|
|
|
|
generateTestAddresses := func(amount int) []*appmessage.NetAddress {
|
|
testAddresses := make([]*appmessage.NetAddress, 0, amount)
|
|
for i := byte(0); i < 128; i++ {
|
|
for j := byte(0); j < 128; j++ {
|
|
testAddress := &appmessage.NetAddress{IP: net.IP{1, 2, i, j}, Timestamp: mstime.Now()}
|
|
testAddresses = append(testAddresses, testAddress)
|
|
if len(testAddresses) == amount {
|
|
break
|
|
}
|
|
}
|
|
if len(testAddresses) == amount {
|
|
break
|
|
}
|
|
}
|
|
return testAddresses
|
|
}
|
|
|
|
// Add a single test address to the address manager
|
|
testAddress := &appmessage.NetAddress{IP: net.IP{5, 6, 0, 0}, Timestamp: mstime.Now()}
|
|
err := addressManager.AddAddress(testAddress)
|
|
if err != nil {
|
|
t.Fatalf("AddAddress: %s", err)
|
|
}
|
|
|
|
// Add `maxAddresses-1` addresses to the address manager
|
|
addresses := generateTestAddresses(maxAddresses - 1)
|
|
err = addressManager.AddAddresses(addresses...)
|
|
if err != nil {
|
|
t.Fatalf("AddAddresses: %s", err)
|
|
}
|
|
|
|
// Make sure that it now contains exactly `maxAddresses` entries
|
|
returnedAddresses := addressManager.Addresses()
|
|
if len(returnedAddresses) != maxAddresses {
|
|
t.Fatalf("Unexpected address amount. Want: %d, got: %d", maxAddresses, len(returnedAddresses))
|
|
}
|
|
|
|
// Mark the first test address as a connection failure
|
|
err = addressManager.MarkConnectionFailure(testAddress)
|
|
if err != nil {
|
|
t.Fatalf("MarkConnectionFailure: %s", err)
|
|
}
|
|
|
|
// Add one more address to the address manager
|
|
err = addressManager.AddAddress(&appmessage.NetAddress{IP: net.IP{7, 8, 0, 0}, Timestamp: mstime.Now()})
|
|
if err != nil {
|
|
t.Fatalf("AddAddress: %s", err)
|
|
}
|
|
|
|
// Make sure that it now still contains exactly `maxAddresses` entries
|
|
returnedAddresses = addressManager.Addresses()
|
|
if len(returnedAddresses) != maxAddresses {
|
|
t.Fatalf("Unexpected address amount. Want: %d, got: %d", maxAddresses, len(returnedAddresses))
|
|
}
|
|
|
|
// Make sure that the first address is no longer in the
|
|
// connection manager
|
|
for _, address := range returnedAddresses {
|
|
if address.IP.Equal(testAddress.IP) {
|
|
t.Fatalf("Unexpectedly found testAddress returned addresses")
|
|
}
|
|
}
|
|
}
|