-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Contract Loader: should be able to load a contract & trigger recipients at the same time#866 #900
Merged
Neylix
merged 1 commit into
archethic-foundation:develop
from
apoorv-2204:contract_Loader_should_be_able_to_load_a_contract_
Feb 14, 2023
Merged
Contract Loader: should be able to load a contract & trigger recipients at the same time#866 #900
Neylix
merged 1 commit into
archethic-foundation:develop
from
apoorv-2204:contract_Loader_should_be_able_to_load_a_contract_
Feb 14, 2023
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
samuelmanzanera
requested changes
Feb 9, 2023
I think you can simplify a lot by reducing it in one function using a condition: @doc """
Load the smart contracts based on transaction involving smart contract code
"""
@spec load_transaction(Transaction.t(), list()) :: :ok
def load_transaction(
tx = %Transaction{
address: address,
type: type,
data: %TransactionData{code: code},
validation_stamp: %ValidationStamp{
recipients: recipients,
timestamp: timestamp,
protocol_version: protocol_version
}
},
opts \\ []
) do
from_db? = Keyword.get(opts, :from_db, false)
from_self_repair? = Keyword.get(opts, :from_self_repair, false)
if from_db? and from_self_repair?, do: raise("Cant have tx with db and self repair flag")
# Stop previous transaction contract
unless from_db? do
stop_contract(Transaction.previous_address(tx))
end
# If transaction contains code, start a new worker for it
if code != "" do
%Contract{triggers: triggers} = Contracts.parse!(code)
triggers = Enum.reject(triggers, fn {_, actions} -> actions == {:__block__, [], []} end)
# Create worker only load smart contract which are expecting interactions and where the actions are not empty
if length(triggers) > 0 do
{:ok, _} =
DynamicSupervisor.start_child(
ContractSupervisor,
{Worker, Contract.from_transaction!(tx)}
)
Logger.info("Smart contract loaded",
transaction_address: Base.encode16(address),
transaction_type: type
)
end
end
# For each recipients, load the transaction in lookup and execute the contract
Enum.each(recipients, fn contract_address ->
TransactionLookup.add_contract_transaction(
contract_address,
address,
timestamp,
protocol_version
)
unless from_db? or from_self_repair? do
# execute contract asynchronously only if we are in live replication
Logger.info(
"Execute transaction on contract #{Base.encode16(contract_address)}",
transaction_address: Base.encode16(address),
transaction_type: type
)
Worker.execute(contract_address, tx)
end
Logger.info("Transaction towards contract ingested",
transaction_address: Base.encode16(address),
transaction_type: type
)
end)
end |
Okay I will remove this code defp do_load_transaction(
%Transaction{
data: %TransactionData{code: ""},
validation_stamp: %ValidationStamp{recipients: []}
},
_from_db?,
_from_self_repair?
) do
# tx does not interact with contract: no recipients
# tx does not have contract/code
# not a contract type tx
true
end
defp do_load_transaction(
tx = %Transaction{
data: %TransactionData{code: code},
validation_stamp: %ValidationStamp{recipients: []}
},
_from_db?,
_from_self_repair?
)
when code != "" do
# no recipients: tx does not interact with contract
# code true: tx contains contract with no(recipients)
stop_contract(Transaction.previous_address(tx))
process_triggers(tx)
end
defp do_load_transaction(
tx = %Transaction{
data: %TransactionData{code: code},
validation_stamp: %ValidationStamp{recipients: recipients}
},
_from_db?,
_from_self_repair?
)
when code != "" and recipients != [] do
# tx contains contract with recipients
stop_contract(Transaction.previous_address(tx))
process_triggers(tx)
# contract a triggers contract b
process_recipients(tx, _execute = true)
end
defp do_load_transaction(
tx = %Transaction{
data: %TransactionData{code: ""},
validation_stamp: %ValidationStamp{recipients: recipients}
},
_from_db? = true,
_from_self_repair? = false
)
when recipients != [] do
# tx being loaded from db
# tx does not contains contract but have destination as contract
# tx meant to be processed by a contract
process_recipients(tx, _execute = false)
Logger.info("Transaction towards contract ingested",
transaction_address: Base.encode16(tx.address),
transaction_type: tx.type
)
end
defp do_load_transaction(
tx = %Transaction{
data: %TransactionData{code: ""},
validation_stamp: %ValidationStamp{recipients: recipients}
},
_from_db? = false,
_from_self_repair? = false
)
when recipients != [] do
# new tx from replication
# tx to interact with contract
# ??
process_recipients(tx)
end
defp do_load_transaction(
tx = %Transaction{
data: %TransactionData{code: ""},
validation_stamp: %ValidationStamp{recipients: recipients}
},
_from_db? = false,
_from_self_repair? = true
)
when recipients != [] do
# tx replicated during self repair
# do not execute tx, but process recipients
process_recipients(tx, _execute = false)
end
defp do_load_transaction(_tx, _from_db?, _from_self_repair?) do
# self repair with tx with code?
# db with tx with code?
# we dont want to ingest tx
# tx belong to other type
true
end
def process_triggers(
tx = %Transaction{
address: address,
type: type,
data: %TransactionData{code: code}
}
) do
%Contract{triggers: triggers} = Contracts.parse!(code)
triggers = Enum.reject(triggers, fn {_, actions} -> actions == {:__block__, [], []} end)
# Create worker only load smart contract which are expecting interactions and where the actions are not empty
if length(triggers) > 0 do
{:ok, _} =
DynamicSupervisor.start_child(
ContractSupervisor,
{Worker, Contract.from_transaction!(tx)}
)
Logger.info("Smart contract loaded",
transaction_address: Base.encode16(address),
transaction_type: type
)
end
:ok
end
def process_recipients(
tx = %Transaction{
address: tx_address,
type: tx_type,
validation_stamp: %ValidationStamp{
timestamp: tx_timestamp,
recipients: recipients,
protocol_version: protocol_version
}
},
execute? \\ false
) do
Enum.each(
recipients,
fn reciever_contract_address ->
if execute? do
# if not from self repair execute
# execute asynchronously the contract
Logger.info(
"Execute transaction on contract #{Base.encode16(reciever_contract_address)}",
transaction_address: Base.encode16(tx_address),
transaction_type: tx_type
)
Worker.execute(reciever_contract_address, tx)
end
TransactionLookup.add_contract_transaction(
reciever_contract_address,
tx_address,
tx_timestamp,
protocol_version
)
Logger.info("Transaction towards contract ingested",
transaction_address: Base.encode16(tx_address),
transaction_type: tx_type
)
end
)
end |
done 👍 |
- maintainability,readability - addition of new condtions Contract A trigger Contract B co-authored-by: Julien <julien@uniris.io>
Neylix
approved these changes
Feb 14, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Fixes
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Checklist: