-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAtomicAwareNodeBlockingServiceFactory.kt
122 lines (111 loc) · 5.59 KB
/
AtomicAwareNodeBlockingServiceFactory.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package com.wavesenterprise.sdk.atomic
import com.wavesenterprise.sdk.atomic.manager.AtomicAwareContextManager
import com.wavesenterprise.sdk.atomic.manager.ContractInfoCacheManager
import com.wavesenterprise.sdk.node.client.blocking.contract.ContractService
import com.wavesenterprise.sdk.node.client.blocking.node.NodeBlockingServiceFactory
import com.wavesenterprise.sdk.node.client.blocking.privacy.PrivacyService
import com.wavesenterprise.sdk.node.client.blocking.tx.TxService
import com.wavesenterprise.sdk.node.domain.atomic.AtomicBadge
import com.wavesenterprise.sdk.node.domain.contract.ContractId
import com.wavesenterprise.sdk.node.domain.contract.ContractInfo
import com.wavesenterprise.sdk.node.domain.contract.ContractVersion
import com.wavesenterprise.sdk.node.domain.contract.ContractVersion.Companion.update
import com.wavesenterprise.sdk.node.domain.privacy.SendDataRequest
import com.wavesenterprise.sdk.node.domain.sign.AtomicInnerSignRequest
import com.wavesenterprise.sdk.node.domain.sign.SignRequest
import com.wavesenterprise.sdk.node.domain.tx.AtomicTx
import com.wavesenterprise.sdk.node.domain.tx.CallContractTx
import com.wavesenterprise.sdk.node.domain.tx.ContractTx.Companion.contractId
import com.wavesenterprise.sdk.node.domain.tx.CreateContractTx
import com.wavesenterprise.sdk.node.domain.tx.ExecutableTx
import com.wavesenterprise.sdk.node.domain.tx.PolicyDataHashTx
import com.wavesenterprise.sdk.node.domain.tx.Tx
import com.wavesenterprise.sdk.node.domain.tx.UpdateContractTx
import com.wavesenterprise.sdk.tx.signer.TxSigner
import java.util.Optional
class AtomicAwareNodeBlockingServiceFactory(
private val nodeBlockingServiceFactory: NodeBlockingServiceFactory,
private val atomicAwareContextManager: AtomicAwareContextManager,
private val contractInfoCacheManager: ContractInfoCacheManager,
private val txSigner: () -> TxSigner,
) : NodeBlockingServiceFactory by nodeBlockingServiceFactory {
private val txSignerFromContext: TxSigner by lazy { txSigner.invoke() }
override fun txService(): TxService = nodeBlockingServiceFactory.txService().let { txService ->
object : TxService by txService {
override fun <T : Tx> broadcast(tx: T): T =
with(atomicAwareContextManager.getContext()) {
if (isSentInAtomic() && tx !is AtomicTx) {
tx.also { tx ->
addTx(tx)
if (tx is ExecutableTx) cacheContractInfo(tx)
}
} else {
txService.broadcast(tx)
}
}
override fun <T : Tx> signAndBroadcast(request: SignRequest<T>): T =
with(atomicAwareContextManager.getContext()) {
if (isSentInAtomic() && request is AtomicInnerSignRequest) {
txSignerFromContext.sign(request).also { tx ->
addTx(tx)
if (tx is ExecutableTx) cacheContractInfo(tx)
}
} else {
txService.signAndBroadcast(request)
}
}
private fun cacheContractInfo(tx: ExecutableTx) {
when (tx) {
is CreateContractTx -> ContractInfo(
id = tx.contractId(),
image = tx.image,
imageHash = tx.imageHash,
version = ContractVersion(1),
active = true,
)
is UpdateContractTx ->
nodeBlockingServiceFactory
.contractService()
.getContractInfo(tx.contractId)
.get()
.run {
this.copy(
version = this.version.update(),
)
}
is CallContractTx -> null
}?.also {
contractInfoCacheManager.getCache().put(
contractId = it.id,
contractInfo = it,
)
}
}
}
}
override fun privacyService(): PrivacyService = nodeBlockingServiceFactory.privacyService().let { privacyService ->
object : PrivacyService by privacyService {
override fun sendData(request: SendDataRequest): PolicyDataHashTx =
privacyService.sendData(request.withAtomicBadgeIfNecessary())
private fun SendDataRequest.withAtomicBadgeIfNecessary() =
withAtomicBadge(
atomicBadge = if (!broadcastTx && senderAddress != txSignerFromContext.getSignerAddress()) {
AtomicBadge(
trustedSender = txSignerFromContext.getSignerAddress(),
)
} else {
AtomicBadge(trustedSender = null)
},
)
}
}
override fun contractService(): ContractService =
nodeBlockingServiceFactory.contractService().let { contractService ->
object : ContractService by contractService {
override fun getContractInfo(contractId: ContractId): Optional<ContractInfo> =
contractInfoCacheManager.getCache().get(contractId)?.let { contractInfo ->
Optional.of(contractInfo)
} ?: contractService.getContractInfo(contractId)
}
}
}