Refactored BitmessageContext creation

This commit is contained in:
Christian Basler 2017-11-25 20:34:11 +01:00
parent a5c78fd8cf
commit ddb2073c2f
12 changed files with 187 additions and 221 deletions

View File

@ -1,5 +1,5 @@
buildscript { buildscript {
ext.kotlin_version = '1.1.60' ext.kotlin_version = '1.1.61'
repositories { repositories {
mavenCentral() mavenCentral()
} }

View File

@ -16,6 +16,7 @@
package ch.dissem.bitmessage package ch.dissem.bitmessage
import ch.dissem.bitmessage.BitmessageContext.Companion.version
import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_EXTRA_BYTES import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_EXTRA_BYTES
import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_NONCE_TRIALS_PER_BYTE import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_NONCE_TRIALS_PER_BYTE
import ch.dissem.bitmessage.entity.BitmessageAddress import ch.dissem.bitmessage.entity.BitmessageAddress
@ -33,7 +34,6 @@ import ch.dissem.bitmessage.exception.DecryptionFailedException
import ch.dissem.bitmessage.factory.Factory import ch.dissem.bitmessage.factory.Factory
import ch.dissem.bitmessage.ports.* import ch.dissem.bitmessage.ports.*
import ch.dissem.bitmessage.utils.Property import ch.dissem.bitmessage.utils.Property
import ch.dissem.bitmessage.utils.UnixTime.HOUR
import ch.dissem.bitmessage.utils.UnixTime.MINUTE import ch.dissem.bitmessage.utils.UnixTime.MINUTE
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import java.net.InetAddress import java.net.InetAddress
@ -58,57 +58,7 @@ import kotlin.properties.Delegates
* *
* The port defaults to 8444 (the default Bitmessage port) * The port defaults to 8444 (the default Bitmessage port)
*/ */
class BitmessageContext( class BitmessageContext private constructor(builder: BitmessageContext.Builder) {
cryptography: Cryptography,
inventory: Inventory,
nodeRegistry: NodeRegistry,
networkHandler: NetworkHandler,
addressRepository: AddressRepository,
messageRepository: MessageRepository,
proofOfWorkRepository: ProofOfWorkRepository,
proofOfWorkEngine: ProofOfWorkEngine = MultiThreadedPOWEngine(),
customCommandHandler: CustomCommandHandler = object : CustomCommandHandler {
override fun handle(request: CustomMessage): MessagePayload? {
BitmessageContext.LOG.debug("Received custom request, but no custom command handler configured.")
return null
}
},
listener: Listener,
labeler: Labeler = DefaultLabeler(),
userAgent: String? = null,
port: Int = 8444,
connectionTTL: Long = 30 * MINUTE,
connectionLimit: Int = 150,
sendPubkeyOnIdentityCreation: Boolean = true,
doMissingProofOfWorkDelayInSeconds: Int = 30
) {
private constructor(builder: BitmessageContext.Builder) : this(
builder.cryptography,
builder.inventory,
builder.nodeRegistry,
builder.networkHandler,
builder.addressRepo,
builder.messageRepo,
builder.proofOfWorkRepository,
builder.proofOfWorkEngine ?: MultiThreadedPOWEngine(),
builder.customCommandHandler ?: object : CustomCommandHandler {
override fun handle(request: CustomMessage): MessagePayload? {
BitmessageContext.LOG.debug("Received custom request, but no custom command handler configured.")
return null
}
},
builder.listener,
builder.labeler ?: DefaultLabeler(),
builder.userAgent,
builder.port,
builder.connectionTTL,
builder.connectionLimit,
builder.sendPubkeyOnIdentityCreation,
builder.doMissingProofOfWorkDelay
)
private val sendPubkeyOnIdentityCreation: Boolean
/** /**
* The [InternalContext] - normally you wouldn't need it, * The [InternalContext] - normally you wouldn't need it,
@ -135,7 +85,7 @@ class BitmessageContext(
*features *features
)) ))
internals.addressRepository.save(identity) internals.addressRepository.save(identity)
if (sendPubkeyOnIdentityCreation) { if (internals.preferences.sendPubkeyOnIdentityCreation) {
internals.sendPubkey(identity, identity.stream) internals.sendPubkey(identity, identity.stream)
} }
return identity return identity
@ -262,9 +212,8 @@ class BitmessageContext(
* @param request the request * @param request the request
* @return the response * @return the response
*/ */
fun send(server: InetAddress, port: Int, request: CustomMessage): CustomMessage { fun send(server: InetAddress, port: Int, request: CustomMessage): CustomMessage =
return internals.networkHandler.send(server, port, request) internals.networkHandler.send(server, port, request)
}
/** /**
* Removes expired objects from the inventory. You should call this method regularly, * Removes expired objects from the inventory. You should call this method regularly,
@ -327,7 +276,7 @@ class BitmessageContext(
fun status(): Property { fun status(): Property {
return Property("status", return Property("status",
Property("user agent", internals.userAgent), Property("user agent", internals.preferences.userAgent),
internals.networkHandler.getNetworkStatus(), internals.networkHandler.getNetworkStatus(),
Property("unacknowledged", internals.messageRepository.findMessagesToResend().size) Property("unacknowledged", internals.messageRepository.findMessagesToResend().size)
) )
@ -344,29 +293,22 @@ class BitmessageContext(
} }
} }
/**
* Kotlin users: you might want to use [BitmessageContext.build] instead.
*/
class Builder { class Builder {
internal var port = 8444 var inventory by Delegates.notNull<Inventory>()
internal var inventory by Delegates.notNull<Inventory>() var nodeRegistry by Delegates.notNull<NodeRegistry>()
internal var nodeRegistry by Delegates.notNull<NodeRegistry>() var networkHandler by Delegates.notNull<NetworkHandler>()
internal var networkHandler by Delegates.notNull<NetworkHandler>() var addressRepo by Delegates.notNull<AddressRepository>()
internal var addressRepo by Delegates.notNull<AddressRepository>() var messageRepo by Delegates.notNull<MessageRepository>()
internal var messageRepo by Delegates.notNull<MessageRepository>() var proofOfWorkRepo by Delegates.notNull<ProofOfWorkRepository>()
internal var proofOfWorkRepository by Delegates.notNull<ProofOfWorkRepository>() var proofOfWorkEngine: ProofOfWorkEngine? = null
internal var proofOfWorkEngine: ProofOfWorkEngine? = null var cryptography by Delegates.notNull<Cryptography>()
internal var cryptography by Delegates.notNull<Cryptography>() var customCommandHandler: CustomCommandHandler? = null
internal var customCommandHandler: CustomCommandHandler? = null var labeler: Labeler? = null
internal var labeler: Labeler? = null var listener by Delegates.notNull<Listener>()
internal var userAgent: String? = null val preferences = Preferences()
internal var listener by Delegates.notNull<Listener>()
internal var connectionLimit = 150
internal var connectionTTL = 30 * MINUTE
internal var sendPubkeyOnIdentityCreation = true
internal var doMissingProofOfWorkDelay = 30
fun port(port: Int): Builder {
this.port = port
return this
}
fun inventory(inventory: Inventory): Builder { fun inventory(inventory: Inventory): Builder {
this.inventory = inventory this.inventory = inventory
@ -394,7 +336,7 @@ class BitmessageContext(
} }
fun powRepo(proofOfWorkRepository: ProofOfWorkRepository): Builder { fun powRepo(proofOfWorkRepository: ProofOfWorkRepository): Builder {
this.proofOfWorkRepository = proofOfWorkRepository this.proofOfWorkRepo = proofOfWorkRepository
return this return this
} }
@ -423,7 +365,7 @@ class BitmessageContext(
return this return this
} }
@JvmName("kotlinListener") @JvmSynthetic
fun listener(listener: (Plaintext) -> Unit): Builder { fun listener(listener: (Plaintext) -> Unit): Builder {
this.listener = object : Listener { this.listener = object : Listener {
override fun receive(plaintext: Plaintext) { override fun receive(plaintext: Plaintext) {
@ -433,63 +375,39 @@ class BitmessageContext(
return this return this
} }
fun connectionLimit(connectionLimit: Int): Builder { fun build() = BitmessageContext(this)
this.connectionLimit = connectionLimit
return this
} }
fun connectionTTL(hours: Int): Builder {
this.connectionTTL = hours * HOUR
return this
}
fun doMissingProofOfWorkDelay(seconds: Int) {
this.doMissingProofOfWorkDelay = seconds
}
/**
* By default a client will send the public key when an identity is being created. On weaker devices
* this behaviour might not be desirable.
*/
fun doNotSendPubkeyOnIdentityCreation(): Builder {
this.sendPubkeyOnIdentityCreation = false
return this
}
fun build(): BitmessageContext {
return BitmessageContext(this)
}
}
init { init {
this.labeler = labeler this.labeler = builder.labeler ?: DefaultLabeler()
this.internals = InternalContext( this.internals = InternalContext(
cryptography, builder.cryptography,
inventory, builder.inventory,
nodeRegistry, builder.nodeRegistry,
networkHandler, builder.networkHandler,
addressRepository, builder.addressRepo,
messageRepository, builder.messageRepo,
proofOfWorkRepository, builder.proofOfWorkRepo,
proofOfWorkEngine, builder.proofOfWorkEngine ?: MultiThreadedPOWEngine(),
customCommandHandler, builder.customCommandHandler ?: object : CustomCommandHandler {
listener, override fun handle(request: CustomMessage): MessagePayload? {
BitmessageContext.LOG.debug("Received custom request, but no custom command handler configured.")
return null
}
},
builder.listener,
labeler, labeler,
userAgent?.let { "/$it/Jabit:$version/" } ?: "/Jabit:$version/", builder.preferences
port,
connectionTTL,
connectionLimit
) )
this.addresses = addressRepository this.addresses = builder.addressRepo
this.messages = messageRepository this.messages = builder.messageRepo
this.sendPubkeyOnIdentityCreation = sendPubkeyOnIdentityCreation (builder.listener as? Listener.WithContext)?.setContext(this)
(listener as? Listener.WithContext)?.setContext(this) internals.proofOfWorkService.doMissingProofOfWork(builder.preferences.doMissingProofOfWorkDelayInSeconds * 1000L)
internals.proofOfWorkService.doMissingProofOfWork(doMissingProofOfWorkDelayInSeconds * 1000L)
} }
companion object { companion object {
@JvmField val CURRENT_VERSION = 3 @JvmField
val CURRENT_VERSION = 3
private val LOG = LoggerFactory.getLogger(BitmessageContext::class.java) private val LOG = LoggerFactory.getLogger(BitmessageContext::class.java)
val version: String by lazy { val version: String by lazy {
@ -497,5 +415,40 @@ class BitmessageContext(
} }
@JvmStatic get @JvmStatic get
@JvmSynthetic
inline fun build(block: Builder.() -> Unit): BitmessageContext {
val builder = Builder()
block(builder)
return builder.build()
}
} }
} }
class Preferences {
var port = 8444
/**
* Defaults to "/Jabit:<version>/", and whatever you set will be inserted into "/<your user agent>/Jabit:<version>/"
*/
var userAgent = "/Jabit:$version/"
set(value) {
field = "/$value/Jabit:$version/"
}
/**
* Time to live for any connection
*/
var connectionTTL = 30 * MINUTE
/**
* Maximum number of connections. Values below 8 would probably result in erratic behaviour, so you shouldn't do that.
*/
var connectionLimit = 150
/**
* By default a client will send the public key when an identity is being created. On weaker devices
* this behaviour might not be desirable.
*/
var sendPubkeyOnIdentityCreation = true
/**
* Delay in seconds before outstandinng proof of work is calculated.
*/
var doMissingProofOfWorkDelayInSeconds = 30
}

View File

@ -51,11 +51,7 @@ class InternalContext(
listener: BitmessageContext.Listener, listener: BitmessageContext.Listener,
val labeler: Labeler, val labeler: Labeler,
val userAgent: String, val preferences: Preferences
val port: Int,
val connectionTTL: Long,
val connectionLimit: Int
) { ) {
private val threadPool = Executors.newCachedThreadPool() private val threadPool = Executors.newCachedThreadPool()

View File

@ -47,8 +47,8 @@ import kotlin.concurrent.thread
* @author Christian Basler * @author Christian Basler
*/ */
class BitmessageContextTest { class BitmessageContextTest {
private var listener: BitmessageContext.Listener = mock() private var testListener: BitmessageContext.Listener = mock()
private val inventory = spy(TestInventory()) private val testInventory = spy(TestInventory())
private val testPowRepo = spy(object : ProofOfWorkRepository { private val testPowRepo = spy(object : ProofOfWorkRepository {
internal var items: MutableMap<InventoryVector, ProofOfWorkRepository.Item> = HashMap() internal var items: MutableMap<InventoryVector, ProofOfWorkRepository.Item> = HashMap()
internal var added = 0 internal var added = 0
@ -93,20 +93,20 @@ class BitmessageContextTest {
thread { callback.onNonceCalculated(initialHash, ByteArray(8)) } thread { callback.onNonceCalculated(initialHash, ByteArray(8)) }
} }
}) })
private var ctx = BitmessageContext.Builder() private var ctx = BitmessageContext.build {
.addressRepo(mock()) addressRepo = mock()
.cryptography(BouncyCryptography()) cryptography = BouncyCryptography()
.inventory(inventory) inventory = testInventory
.listener(listener) listener = testListener
.messageRepo(mock()) messageRepo = mock()
.networkHandler(mock { networkHandler = mock {
on { getNetworkStatus() } doReturn Property("test", "mocked") on { getNetworkStatus() } doReturn Property("test", "mocked")
}) }
.nodeRegistry(mock()) nodeRegistry = mock()
.labeler(spy(DefaultLabeler())) labeler = spy(DefaultLabeler())
.powRepo(testPowRepo) proofOfWorkRepo = testPowRepo
.proofOfWorkEngine(testPowEngine) proofOfWorkEngine = testPowEngine
.build() }
init { init {
TTL.msg = 2 * MINUTE TTL.msg = 2 * MINUTE
@ -143,7 +143,7 @@ class BitmessageContextTest {
@Test @Test
fun `ensure V2Pubkey is not requested if it exists in inventory`() { fun `ensure V2Pubkey is not requested if it exists in inventory`() {
inventory.init( testInventory.init(
"V1Msg.payload", "V1Msg.payload",
"V2GetPubkey.payload", "V2GetPubkey.payload",
"V2Pubkey.payload", "V2Pubkey.payload",
@ -166,7 +166,7 @@ class BitmessageContextTest {
@Test @Test
fun `ensure V4Pubkey is not requested if it exists in inventory`() { fun `ensure V4Pubkey is not requested if it exists in inventory`() {
inventory.init( testInventory.init(
"V1Msg.payload", "V1Msg.payload",
"V2GetPubkey.payload", "V2GetPubkey.payload",
"V2Pubkey.payload", "V2Pubkey.payload",
@ -192,7 +192,7 @@ class BitmessageContextTest {
fun `ensure subscription is added and existing broadcasts retrieved`() { fun `ensure subscription is added and existing broadcasts retrieved`() {
val address = BitmessageAddress("BM-2D9Vc5rFxxR5vTi53T9gkLfemViHRMVLQZ") val address = BitmessageAddress("BM-2D9Vc5rFxxR5vTi53T9gkLfemViHRMVLQZ")
inventory.init( testInventory.init(
"V4Broadcast.payload", "V4Broadcast.payload",
"V5Broadcast.payload" "V5Broadcast.payload"
) )
@ -203,7 +203,7 @@ class BitmessageContextTest {
verify(ctx.addresses, atLeastOnce()).save(address) verify(ctx.addresses, atLeastOnce()).save(address)
assertThat(address.isSubscribed, `is`(true)) assertThat(address.isSubscribed, `is`(true))
verify(ctx.internals.inventory).getObjects(eq(address.stream), any(), any()) verify(ctx.internals.inventory).getObjects(eq(address.stream), any(), any())
verify(listener).receive(any()) verify(testListener).receive(any())
} }
@Test @Test

View File

@ -18,6 +18,7 @@ package ch.dissem.bitmessage.utils
import ch.dissem.bitmessage.BitmessageContext import ch.dissem.bitmessage.BitmessageContext
import ch.dissem.bitmessage.InternalContext import ch.dissem.bitmessage.InternalContext
import ch.dissem.bitmessage.Preferences
import ch.dissem.bitmessage.entity.BitmessageAddress import ch.dissem.bitmessage.entity.BitmessageAddress
import ch.dissem.bitmessage.entity.ObjectMessage import ch.dissem.bitmessage.entity.ObjectMessage
import ch.dissem.bitmessage.entity.payload.V4Pubkey import ch.dissem.bitmessage.entity.payload.V4Pubkey
@ -39,21 +40,25 @@ import kotlin.NoSuchElementException
* If there's ever a need for this in production code, it should be rewritten to be more efficient. * If there's ever a need for this in production code, it should be rewritten to be more efficient.
*/ */
object TestUtils { object TestUtils {
@JvmField val RANDOM = Random() @JvmField
val RANDOM = Random()
@JvmStatic fun int16(number: Int): ByteArray { @JvmStatic
fun int16(number: Int): ByteArray {
val out = ByteArrayOutputStream() val out = ByteArrayOutputStream()
Encode.int16(number, out) Encode.int16(number, out)
return out.toByteArray() return out.toByteArray()
} }
@JvmStatic fun loadObjectMessage(version: Int, resourceName: String): ObjectMessage { @JvmStatic
fun loadObjectMessage(version: Int, resourceName: String): ObjectMessage {
val data = getBytes(resourceName) val data = getBytes(resourceName)
val input = ByteArrayInputStream(data) val input = ByteArrayInputStream(data)
return Factory.getObjectMessage(version, input, data.size) ?: throw NoSuchElementException("error loading object message") return Factory.getObjectMessage(version, input, data.size) ?: throw NoSuchElementException("error loading object message")
} }
@JvmStatic fun getBytes(resourceName: String): ByteArray { @JvmStatic
fun getBytes(resourceName: String): ByteArray {
val input = javaClass.classLoader.getResourceAsStream(resourceName) val input = javaClass.classLoader.getResourceAsStream(resourceName)
val out = ByteArrayOutputStream() val out = ByteArrayOutputStream()
val buffer = ByteArray(1024) val buffer = ByteArray(1024)
@ -65,16 +70,19 @@ object TestUtils {
return out.toByteArray() return out.toByteArray()
} }
@JvmStatic fun randomInventoryVector(): InventoryVector { @JvmStatic
fun randomInventoryVector(): InventoryVector {
val bytes = ByteArray(32) val bytes = ByteArray(32)
RANDOM.nextBytes(bytes) RANDOM.nextBytes(bytes)
return InventoryVector(bytes) return InventoryVector(bytes)
} }
@JvmStatic fun getResource(resourceName: String): InputStream = @JvmStatic
fun getResource(resourceName: String): InputStream =
javaClass.classLoader.getResourceAsStream(resourceName) javaClass.classLoader.getResourceAsStream(resourceName)
@JvmStatic fun loadIdentity(address: String): BitmessageAddress { @JvmStatic
fun loadIdentity(address: String): BitmessageAddress {
val privateKey = PrivateKey.read(TestUtils.getResource(address + ".privkey")) val privateKey = PrivateKey.read(TestUtils.getResource(address + ".privkey"))
val identity = BitmessageAddress(privateKey) val identity = BitmessageAddress(privateKey)
assertEquals(address, identity.address) assertEquals(address, identity.address)
@ -82,7 +90,8 @@ object TestUtils {
} }
@Throws(DecryptionFailedException::class) @Throws(DecryptionFailedException::class)
@JvmStatic fun loadContact(): BitmessageAddress { @JvmStatic
fun loadContact(): BitmessageAddress {
val address = BitmessageAddress("BM-2cXxfcSetKnbHJX2Y85rSkaVpsdNUZ5q9h") val address = BitmessageAddress("BM-2cXxfcSetKnbHJX2Y85rSkaVpsdNUZ5q9h")
val objectMessage = TestUtils.loadObjectMessage(3, "V4Pubkey.payload") val objectMessage = TestUtils.loadObjectMessage(3, "V4Pubkey.payload")
objectMessage.decrypt(address.publicDecryptionKey) objectMessage.decrypt(address.publicDecryptionKey)
@ -90,13 +99,15 @@ object TestUtils {
return address return address
} }
@JvmStatic fun loadPubkey(address: BitmessageAddress) { @JvmStatic
fun loadPubkey(address: BitmessageAddress) {
val bytes = getBytes(address.address + ".pubkey") val bytes = getBytes(address.address + ".pubkey")
val pubkey = Factory.readPubkey(address.version, address.stream, ByteArrayInputStream(bytes), bytes.size, false) val pubkey = Factory.readPubkey(address.version, address.stream, ByteArrayInputStream(bytes), bytes.size, false)
address.pubkey = pubkey address.pubkey = pubkey
} }
@JvmStatic fun mockedInternalContext( @JvmStatic
fun mockedInternalContext(
cryptography: Cryptography = mock {}, cryptography: Cryptography = mock {},
inventory: Inventory = mock {}, inventory: Inventory = mock {},
nodeRegistry: NodeRegistry = mock {}, nodeRegistry: NodeRegistry = mock {},
@ -124,10 +135,12 @@ object TestUtils {
customCommandHandler, customCommandHandler,
listener, listener,
labeler, labeler,
"/Jabit:TEST/", Preferences().apply {
port, this.userAgent = "/Jabit:TEST/"
connectionTTL, this.port = port
connectionLimit this.connectionTTL = connectionTTL
this.connectionLimit = connectionLimit
}
)) ))
} }
} }

View File

@ -64,8 +64,8 @@ public class Main {
.messageRepo(new JdbcMessageRepository(jdbcConfig)) .messageRepo(new JdbcMessageRepository(jdbcConfig))
.powRepo(new JdbcProofOfWorkRepository(jdbcConfig)) .powRepo(new JdbcProofOfWorkRepository(jdbcConfig))
.networkHandler(new NioNetworkHandler()) .networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography()) .cryptography(new BouncyCryptography());
.port(48444); ctxBuilder.getPreferences().setPort(48444);
if (options.localPort != null) { if (options.localPort != null) {
ctxBuilder.nodeRegistry(new NodeRegistry() { ctxBuilder.nodeRegistry(new NodeRegistry() {
@Override @Override

View File

@ -73,13 +73,13 @@ public class SystemTest {
.inventory(new JdbcInventory(aliceDB)) .inventory(new JdbcInventory(aliceDB))
.messageRepo(new JdbcMessageRepository(aliceDB)) .messageRepo(new JdbcMessageRepository(aliceDB))
.powRepo(new JdbcProofOfWorkRepository(aliceDB)) .powRepo(new JdbcProofOfWorkRepository(aliceDB))
.port(alicePort)
.nodeRegistry(new TestNodeRegistry(bobPort)) .nodeRegistry(new TestNodeRegistry(bobPort))
.networkHandler(new NioNetworkHandler()) .networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography()) .cryptography(new BouncyCryptography())
.listener(aliceListener) .listener(aliceListener)
.labeler(aliceLabeler) .labeler(aliceLabeler)
.build(); .build();
alice.internals().getPreferences().setPort(alicePort);
alice.startup(); alice.startup();
aliceIdentity = alice.createIdentity(false, DOES_ACK); aliceIdentity = alice.createIdentity(false, DOES_ACK);
} }
@ -91,13 +91,13 @@ public class SystemTest {
.inventory(new JdbcInventory(bobDB)) .inventory(new JdbcInventory(bobDB))
.messageRepo(new JdbcMessageRepository(bobDB)) .messageRepo(new JdbcMessageRepository(bobDB))
.powRepo(new JdbcProofOfWorkRepository(bobDB)) .powRepo(new JdbcProofOfWorkRepository(bobDB))
.port(bobPort)
.nodeRegistry(new TestNodeRegistry(alicePort)) .nodeRegistry(new TestNodeRegistry(alicePort))
.networkHandler(new NioNetworkHandler()) .networkHandler(new NioNetworkHandler())
.cryptography(new BouncyCryptography()) .cryptography(new BouncyCryptography())
.listener(bobListener) .listener(bobListener)
.labeler(new DebugLabeler("Bob")) .labeler(new DebugLabeler("Bob"))
.build(); .build();
bob.internals().getPreferences().setPort(bobPort);
bob.startup(); bob.startup();
bobIdentity = bob.createIdentity(false, DOES_ACK); bobIdentity = bob.createIdentity(false, DOES_ACK);
} }

View File

@ -41,7 +41,7 @@ class NetworkConnectionInitializer(
fun start() { fun start() {
if (mode == Connection.Mode.CLIENT || mode == Connection.Mode.SYNC) { if (mode == Connection.Mode.CLIENT || mode == Connection.Mode.SYNC) {
send(Version(nonce = ctx.clientNonce, addrFrom = NetworkAddress.ANY, addrRecv = node, userAgent = ctx.userAgent)) send(Version(nonce = ctx.clientNonce, addrFrom = NetworkAddress.ANY, addrRecv = node, userAgent = ctx.preferences.userAgent))
} }
} }

View File

@ -199,7 +199,7 @@ class NioNetworkHandler : NetworkHandler, InternalContext.ContextHolder {
val serverChannel = ServerSocketChannel.open() val serverChannel = ServerSocketChannel.open()
this.serverChannel = serverChannel this.serverChannel = serverChannel
serverChannel.configureBlocking(false) serverChannel.configureBlocking(false)
serverChannel.socket().bind(InetSocketAddress(ctx.port)) serverChannel.socket().bind(InetSocketAddress(ctx.preferences.port))
serverChannel.register(selector, OP_ACCEPT, null) serverChannel.register(selector, OP_ACCEPT, null)
while (selector.isOpen) { while (selector.isOpen) {

View File

@ -23,7 +23,8 @@ import ch.dissem.bitmessage.entity.MessagePayload
import ch.dissem.bitmessage.entity.valueobject.NetworkAddress import ch.dissem.bitmessage.entity.valueobject.NetworkAddress
import ch.dissem.bitmessage.exception.NodeException import ch.dissem.bitmessage.exception.NodeException
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler import ch.dissem.bitmessage.networking.nio.NioNetworkHandler
import ch.dissem.bitmessage.ports.* import ch.dissem.bitmessage.ports.CustomCommandHandler
import ch.dissem.bitmessage.ports.NetworkHandler
import ch.dissem.bitmessage.testutils.TestInventory import ch.dissem.bitmessage.testutils.TestInventory
import ch.dissem.bitmessage.utils.Property import ch.dissem.bitmessage.utils.Property
import ch.dissem.bitmessage.utils.Singleton.cryptography import ch.dissem.bitmessage.utils.Singleton.cryptography
@ -31,7 +32,8 @@ import com.nhaarman.mockito_kotlin.mock
import org.hamcrest.Matchers.`is` import org.hamcrest.Matchers.`is`
import org.hamcrest.Matchers.notNullValue import org.hamcrest.Matchers.notNullValue
import org.junit.After import org.junit.After
import org.junit.Assert.* import org.junit.Assert.assertEquals
import org.junit.Assert.assertThat
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -56,20 +58,22 @@ class NetworkHandlerTest {
private lateinit var peerNetworkHandler: NetworkHandler private lateinit var peerNetworkHandler: NetworkHandler
private lateinit var nodeNetworkHandler: NetworkHandler private lateinit var nodeNetworkHandler: NetworkHandler
@JvmField @Rule val timeout: TestRule = DisableOnDebug(Timeout.seconds(60)) @JvmField
@Rule
val timeout: TestRule = DisableOnDebug(Timeout.seconds(60))
@Before @Before
fun setUp() { fun setUp() {
peerInventory = TestInventory() peerInventory = TestInventory()
peerNetworkHandler = NioNetworkHandler() peerNetworkHandler = NioNetworkHandler()
peer = BitmessageContext( peer = BitmessageContext.build {
cryptography = BouncyCryptography(), cryptography = BouncyCryptography()
inventory = peerInventory, inventory = peerInventory
nodeRegistry = TestNodeRegistry(), nodeRegistry = TestNodeRegistry()
networkHandler = peerNetworkHandler, networkHandler = peerNetworkHandler
addressRepository = mock<AddressRepository>(), addressRepo = mock()
messageRepository = mock<MessageRepository>(), messageRepo = mock()
proofOfWorkRepository = mock<ProofOfWorkRepository>(), proofOfWorkRepo = mock()
customCommandHandler = object : CustomCommandHandler { customCommandHandler = object : CustomCommandHandler {
override fun handle(request: CustomMessage): MessagePayload? { override fun handle(request: CustomMessage): MessagePayload? {
val data = request.getData() val data = request.getData()
@ -83,23 +87,23 @@ class NetworkHandlerTest {
} }
return CustomMessage("test response", request.getData()) return CustomMessage("test response", request.getData())
} }
}, }
listener = mock<BitmessageContext.Listener>(), listener = mock()
port = peerAddress.port preferences.port = peerAddress.port
) }
peer.startup() peer.startup()
Thread.sleep(100) Thread.sleep(100)
nodeInventory = TestInventory() nodeInventory = TestInventory()
nodeNetworkHandler = NioNetworkHandler() nodeNetworkHandler = NioNetworkHandler()
node = BitmessageContext( node = BitmessageContext.build {
cryptography = BouncyCryptography(), cryptography = BouncyCryptography()
inventory = nodeInventory, inventory = nodeInventory
nodeRegistry = TestNodeRegistry(peerAddress), nodeRegistry = TestNodeRegistry(peerAddress)
networkHandler = nodeNetworkHandler, networkHandler = nodeNetworkHandler
addressRepository = mock<AddressRepository>(), addressRepo = mock()
messageRepository = mock<MessageRepository>(), messageRepo = mock()
proofOfWorkRepository = mock<ProofOfWorkRepository>(), proofOfWorkRepo = mock()
customCommandHandler = object : CustomCommandHandler { customCommandHandler = object : CustomCommandHandler {
override fun handle(request: CustomMessage): MessagePayload? { override fun handle(request: CustomMessage): MessagePayload? {
val data = request.getData() val data = request.getData()
@ -113,10 +117,10 @@ class NetworkHandlerTest {
} }
return CustomMessage("test response", request.getData()) return CustomMessage("test response", request.getData())
} }
}, }
listener = mock<BitmessageContext.Listener>(), listener = mock()
port = 6002 preferences.port = 6002
) }
} }
@After @After

View File

@ -49,16 +49,16 @@ class WifExporterTest {
@Before @Before
fun setUp() { fun setUp() {
ctx = BitmessageContext.Builder() ctx = BitmessageContext.build {
.cryptography(BouncyCryptography()) cryptography = BouncyCryptography()
.networkHandler(mock()) networkHandler = mock()
.inventory(mock()) inventory = mock()
.messageRepo(mock()) messageRepo = mock()
.powRepo(mock()) proofOfWorkRepo = mock()
.nodeRegistry(mock()) nodeRegistry = mock()
.addressRepo(repo) addressRepo = repo
.listener { } listener {}
.build() }
importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat")) importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat"))
assertEquals(81, importer.getIdentities().size) assertEquals(81, importer.getIdentities().size)
exporter = WifExporter(ctx) exporter = WifExporter(ctx)

View File

@ -50,16 +50,16 @@ class WifImporterTest {
@Before @Before
fun setUp() { fun setUp() {
ctx = BitmessageContext.Builder() ctx = BitmessageContext.build {
.cryptography(BouncyCryptography()) cryptography = BouncyCryptography()
.networkHandler(mock()) networkHandler = mock()
.inventory(mock()) inventory = mock()
.messageRepo(mock()) messageRepo = mock()
.powRepo(mock()) proofOfWorkRepo = mock()
.nodeRegistry(mock()) nodeRegistry = mock()
.addressRepo(repo) addressRepo = repo
.listener { } listener { }
.build() }
importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat")) importer = WifImporter(ctx, javaClass.classLoader.getResourceAsStream("nuked.dat"))
} }