[contracts] Make contract interactions optional in the node (#91)

Adds --eth-deployment parameter.
Does not crash when deployment json is missing or incorrect.
This commit is contained in:
markspanbroek 2022-04-25 17:12:37 +04:00 committed by GitHub
parent c93e015e43
commit d8ed4257df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 20 deletions

View File

@ -154,6 +154,12 @@ type
name: "eth-account"
.}: EthAddress
ethDeployment* {.
desc: "The json file describing the contract deployment"
defaultValue: string.default
name: "eth-deployment"
.}: string
of initNode:
discard

View File

@ -16,5 +16,11 @@ proc deployment*(file = defaultFile): Deployment =
Deployment(json: parseFile(file))
proc address*(deployment: Deployment, Contract: typedesc): ?Address =
let address = deployment.json["contracts"][$Contract]["address"].getStr()
Address.init(address)
if deployment.json == nil:
return none Address
try:
let address = deployment.json["contracts"][$Contract]["address"].getStr()
Address.init(address)
except KeyError:
none Address

View File

@ -1,4 +1,5 @@
import pkg/ethers
import pkg/chronicles
import ../purchasing
import ../sales
import ../proving
@ -10,6 +11,7 @@ import ./proofs
export purchasing
export sales
export proving
export chronicles
type
ContractInteractions* = ref object
@ -19,11 +21,16 @@ type
proc new*(_: type ContractInteractions,
signer: Signer,
deployment: Deployment): ContractInteractions =
let contract = Storage.new(!deployment.address(Storage), signer)
deployment: Deployment): ?ContractInteractions =
without address =? deployment.address(Storage):
error "Unable to determine address of the Storage smart contract"
return none ContractInteractions
let contract = Storage.new(address, signer)
let market = OnChainMarket.new(contract)
let proofs = OnChainProofs.new(contract)
ContractInteractions(
some ContractInteractions(
purchasing: Purchasing.new(market),
sales: Sales.new(market),
proving: Proving.new(proofs)
@ -31,16 +38,30 @@ proc new*(_: type ContractInteractions,
proc new*(_: type ContractInteractions,
providerUrl: string,
account = Address.default): ContractInteractions =
deploymentFile: string = string.default,
account = Address.default): ?ContractInteractions =
let provider = JsonRpcProvider.new(providerUrl)
var signer: Signer
if account == Address.default:
signer = provider.getSigner()
else:
signer = provider.getSigner(account)
ContractInteractions.new(signer, deployment())
proc new*(_: type ContractInteractions): ContractInteractions =
var deploy: Deployment
try:
if deploymentFile == string.default:
deploy = deployment()
else:
deploy = deployment(deploymentFile)
except IOError as e:
error "Unable to read deployment json", msg = e.msg
return none ContractInteractions
ContractInteractions.new(signer, deploy)
proc new*(_: type ContractInteractions): ?ContractInteractions =
ContractInteractions.new("ws://localhost:8545")
proc start*(interactions: ContractInteractions) {.async.} =

View File

@ -122,7 +122,11 @@ proc new*(T: type DaggerServer, config: DaggerConf): T =
engine = BlockExcEngine.new(localStore, wallet, network, discovery)
store = NetworkStore.new(engine, localStore)
erasure = Erasure.new(store, leoEncoderProvider, leoDecoderProvider)
contracts = ContractInteractions.new(config.ethProvider, config.ethAccount)
contracts = ContractInteractions.new(
config.ethProvider,
config.ethDeployment,
config.ethAccount
)
daggerNode = DaggerNodeRef.new(switch, store, engine, erasure, discovery, contracts)
restServer = RestServerRef.new(
daggerNode.initRestApi(),

View File

@ -43,7 +43,7 @@ type
engine*: BlockExcEngine
erasure*: Erasure
discovery*: Discovery
contracts*: ContractInteractions
contracts*: ?ContractInteractions
proc start*(node: DaggerNodeRef) {.async.} =
await node.switch.start()
@ -51,8 +51,8 @@ proc start*(node: DaggerNodeRef) {.async.} =
await node.erasure.start()
await node.discovery.start()
if not node.contracts.isNil:
await node.contracts.start()
if contracts =? node.contracts:
await contracts.start()
node.networkId = node.switch.peerInfo.peerId
notice "Started dagger node", id = $node.networkId, addrs = node.switch.peerInfo.addrs
@ -65,8 +65,8 @@ proc stop*(node: DaggerNodeRef) {.async.} =
await node.erasure.stop()
await node.discovery.stop()
if not node.contracts.isNil:
await node.contracts.stop()
if contracts =? node.contracts:
await contracts.stop()
proc findPeer*(
node: DaggerNodeRef,
@ -244,7 +244,7 @@ proc new*(
engine: BlockExcEngine,
erasure: Erasure,
discovery: Discovery,
contracts: ContractInteractions): T =
contracts: ?ContractInteractions): T =
T(
switch: switch,
blockStore: store,

View File

@ -1,3 +1,4 @@
import std/os
import ./ethertest
import dagger/contracts
import ./examples
@ -7,18 +8,20 @@ ethersuite "Storage Contract Interactions":
var contracts: ContractInteractions
setup:
contracts = ContractInteractions.new()
contracts = !ContractInteractions.new()
test "can be instantiated with a signer and deployment info":
let signer = provider.getSigner()
let deployment = deployment()
check ContractInteractions.new(signer, deployment) != nil
check ContractInteractions.new(signer, deployment).isSome
test "can be instantiated with a provider url and account":
let url = "http://localhost:8545"
let account = Address.example
check ContractInteractions.new(url) != nil
check ContractInteractions.new(url, account) != nil
let deployment = "vendor" / "dagger-contracts" / "deployment-localhost.json"
check ContractInteractions.new(url).isSome
check ContractInteractions.new(url, account = account).isSome
check ContractInteractions.new(url, deploymentFile = deployment).isSome
test "provides purchasing":
check contracts.purchasing != nil

View File

@ -36,7 +36,7 @@ suite "Test Node":
store: NetworkStore
node: DaggerNodeRef
discovery: Discovery
contracts: ContractInteractions
contracts: ?ContractInteractions
setup:
file = open(path.splitFile().dir /../ "fixtures" / "test.jpg")