Problem: I cannot seem to call another transaction processor function using the Factory from within a transaction processor function.
Scenario: I have a transaction processor function as follows:
/**
* Perform a deposit or withdrawal from a bank account
* #param {org.acme.auctionnetwork.AccountTrx} transaction
* #transaction
*/
function execTrx(transaction) {
// do stuff
}
I want to call the above function in another transaction processor function:
/**
* The buyer pays the listing price agreed to the seller and ownership of the vehicle transfers
* #param {org.acme.auctionnetwork.PayListing} payment - pay the listing
* #transaction
*/
function payListing(payment) {
var factory = getFactory();
var debitBuyer = factory.newResource('org.acme.auctionnetwork', 'AccountTrx', '##INSERTRANDOMTRXIDHERE##');
debitBuyer.amount = payment.vehicleListing.buyerPrice;
debitBuyer.operation = 'W';
debitBuyer.account = buyerAccount;
debitBuyer.party = buyerAccount.owner;
var creditSeller = factory.newResource('org.acme.auctionnetwork', 'AccountTrx', '##INSERTRANDOMTRXIDHERE##');
creditSeller.amount = payment.vehicleListing.buyerPrice;
creditSeller.operation = 'D';
creditSeller.account = sellerAccount;
creditSeller.party = sellerAccount.owner;
return getTransactionRegistry('org.acme.auctionnetwork.AccountTrx')
.then(function(regTransactions) {
return regTransactions.add(debitBuyer)
.then(function() {
return regTransactions.add(creditSeller);
})
});
}
However, the above complains that getTransactionRegistry() is not defined. I'm aware when you typically create assets and participants that you would call the corresponding getAssetRegistry() or getParticipantRegistry() functions and call the add() function to update the registry with these new assets and participants. The problem is I can't find how to call a transaction.
For research, I referenced https://hyperledger.github.io/composer/jsdoc/module-composer-runtime.Factory.html. The newResource() function claims it works for assets, participants and transactions but I can't find sample code to execute transactions (looked in the default Hyperledger Composer demos as well).
I also did some troubleshooting and noted that even though I created a new instance of the AccountTrx transaction, the execTrx() function wasn't being called at all.
Update: On further inspection, there appears to be a TransactionHandler class detailed here https://hyperledger.github.io/composer/jsdoc/TransactionHandler.html but for the life of me, I can't find any documentation on how to use it, or sample code.
Maybe its too late to answer this, but now, we can use getNativeAPI() to use some of the API's of Hyperledger fabric inside composer. We can use that inside one function to invoke the same network but it is another transaction.
In the below given link procedure, change the chaincode name (other-tutorial-network) to the same network name to call itself.
https://hyperledger.github.io/composer/v0.19/tutorials/invoke-composer-network
API's available to be used with getNativeAPI() : https://fabric-shim.github.io/release-1.3/fabric-shim.ChaincodeStub.html?redirect=true
Related
I was learning how to develop a front end for dApps by going through the code for Uniswap interface.
Then I found that there are two Web3Providers used in the app like below.
<Web3ReactProvider getLibrary={getLibrary}> // 1st
<Web3ProviderNetwork getLibrary={getLibrary}> // 2nd
<Blocklist>
// some other child nodes
</Blocklist>
<Web3ProviderNetwork>
</Web3ReactProvider>
As for Web3ReactProvider, it uses the component provided by the web3-react package, while Web3ProviderNetwork is created with a key "NETWORK" on the same file those providers are written.
Uniswap has a method useActiveWeb3React which returns web3context values depending on its active variable value.
In other words, default web3Context is returned if active variable is true, otherwise Web3Context with Network is returned. (code below)
export default function useActiveWeb3React() {
const interfaceContext = useWeb3React<Web3Provider>()
const interfaceNetworkContext = useWeb3React<Web3Provider>(
process.env.REACT_APP_IS_WIDGET ? undefined : NetworkContextName
)
if (interfaceContext.active) {
return interfaceContext
}
return interfaceNetworkContext
}
Does anyone know why they switch providers depending on the active variable?
Does it make any difference?
In this codpiece, I am finding it hard to figure out what is msg.sender is and how it works internally.
What I am understanding is, we have a mapping favoriteNumber, and the key is an address and the value is a uint.
What is the meaning of comment - "Update our favoriteNumber mapping to store _myNumber under msg.sender, I am understanding that we are updating favoriteNumber, but what does it mean that under msg.sender. What is the role of this method, how it's working?
mapping (address => uint) favoriteNumber;
function setMyNumber(uint _myNumber) public {
// Update our `favoriteNumber` mapping to store `_myNumber` under `msg.sender`
favoriteNumber[msg.sender] = _myNumber;
// ^ The syntax for storing data in a mapping is just like with arrays
}
function whatIsMyNumber() public view returns (uint) {
// Retrieve the value stored in the sender's address
// Will be `0` if the sender hasn't called `setMyNumber` yet
return favoriteNumber[msg.sender];
}
Every smart contract invocation has a caller address. Each EVM (Ethereum Virtual Machine that executes the code) knows which
account carries out each action. In Solidity, you can access the calling account by
referencing msg.sender
So when you call a function of solidity contract, your contract already gets the information of your account, so your account is the msg.sender
favoriteNumber is a mapping. think it like a javascript object. It maps the account addresses to their favourite number.
0x9C6520Dd9F8d0af1DA494C37b64D4Cea9A65243C -> 10
So when you call setMyNumber(_myNumber), you are passing your favourite number. so this number will be stored in favoriteNumber mapping like this:
yourAccountAdress -> yourFavouriteNumber
So when you call whatIsMyNumber function, since EVM already gets your account number, checks in the mappings and returns you your favourite number.
In solidity exists 3 types of variables: state, local and global.
example of global variables:
msg.sender (sender of the message)
msg.value (number of wei sent with the message)
pseudocode from favoriteNumber[msg.sender] = _myNumber;
given a favoriteNumber list,
select the address of the account calling this function,
assign _myNumber to that address
note: global variables are available in all contracts by default. see more info here: solidity docs - global variable
I want to pass an amount of storage units in one step. I need all storage units at once in the CREATE_ENTITY method in my OData service implementation (CREATE_ENTITY, or CREATE_DEEP_ENTITY, or...?), because I have to make a comparison of some values.
I tried a batch request. This doesn't work, because the CREATE_ENTITY method was called for each storage unit. So I could access only one storage unit in each call.
I also searched for tutorials concerning deep_entities. But I only find some with deep structures (head - items). But I have a flat structure (key: storage Unit) and want to pass this as table/array to my CREATE_ENTITY method. It should be possible to do this in SAPUI5.
As workaround I could pass all storage units into a string and pass this to the CREATE_ENTITY method. But that seems quite amateurish to me.
Here is how I invoke CREATE method:
onStartVert: function () {
this.oContext = this.getModel().createEntry("/LenumIPunktSet", {
success: this._successSave.bind(this),
error: this._errorSave.bind(this)
});
var oBindingPath = {
path: this.oContext.getPath()
};
this.getView().bindObject(oBindingPath);
var sLenum;
for (var i = 0; i < this._data.LePool.length; i++) {
sLenum = this._data.LePool[i].lenum;
this.getModel().create("/LenumIPunktSet", {
lenum: sLenum
});
}
this.getModel().submitChanges();
this.getRouter().navTo("iPunkt02");
},
The signature for the CHANGESET_PROCESS method is:
CT_CHANGESET_DATA TYPE /IWBEP/IF_MGW_CORE_SRV_RUNTIME=>TY_T_CHANGESET_DATA
/IWBEP/CX_MGW_BUSI_EXCEPTION Business Exception
/IWBEP/CX_MGW_TECH_EXCEPTION Technical Exception
So, by now there is no table IT_CHANGESET_REQUEST available.
My entity type has only this one field (lenum) I need as key.
The key is to implement a changeset.
In your DPC_EXT redefine the following three methods:
The method CHANGESET_BEGIN will activate the batch processing.
METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_begin.
cv_defer_mode = 'X'.
ENDMETHOD.
METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_end.
* empty
ENDMETHOD.
The method changeset_process will contain the logic. it_changeset_request contains all entities which are part of this batch request.
METHOD /iwbep/if_mgw_appl_srv_runtime~changeset_process.
LOOP AT it_changeset_request ASSIGNING FIELD-SYMBOL(<fs_changeset_request>).
" <fs_changeset_request>-request_context->get_request_details( ) << which entity is it?
" <fs_changeset_request>-operation_type << is it CREATE, UPDATE or DELETE?
" <fs_changeset_request>-entry_provider->read_entry_data( ... ) << read entity into structure
ENDLOOP.
ENDMETHOD.
See this blog for some details.
I'm having a weird issue with the configureMetadataStore.
My model:
class SourceMaterial {
List<Job> Jobs {get; set;}
}
class Job {
public SourceMaterial SourceMaterial {get; set;}
}
class JobEditing : Job {}
class JobTranslation: Job {}
Module for configuring Job entities:
angular.module('cdt.request.model').factory('jobModel', ['breeze', 'dataService', 'entityService', modelFunc]);
function modelFunc(breeze, dataService, entityService) {
function Ctor() {
}
Ctor.extend = function (modelCtor) {
modelCtor.prototype = new Ctor();
modelCtor.prototype.constructor = modelCtor;
};
Ctor.prototype._configureMetadataStore = _configureMetadataStore;
return Ctor;
// constructor
function jobCtor() {
this.isScreenDeleted = null;
}
function _configureMetadataStore(entityName, metadataStore) {
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
}
function jobInitializer(job) { /* do stuff here */ }
}
Module for configuring JobEditing entities:
angular.module('cdt.request.model').factory(jobEditingModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobEditing', metadataStore)
}
}
Module for configuring JobTranslation entities:
angular.module('cdt.request.model').factory(jobTranslationModel, ['jobModel', modelFunc]);
function modelFunc(jobModel) {
function Ctor() {
this.configureMetadataStore = configureMetadataStore;
}
jobModel.extend(Ctor);
return Ctor;
function configureMetadataStore(metadataStore) {
return this._configureMetadataStore('JobTranslation', metadataStore)
}
}
Then Models are configured like this :
JobEditingModel.configureMetadataStore(dataService.manager.metadataStore);
JobTranslationModel.configureMetadataStore(dataService.manager.metadataStore);
Now when I call createEntity for a JobEditing, the instance is created and at some point, breeze calls setNpValue and adds the newly created Job to the np SourceMaterial.
That's all fine, except that it is added twice !
It happens when rawAccessorFn(newValue); is called. In fact it is called twice.
And if I add a new type of job (hence I register a new type with the metadataStore), then the new Job is added three times to the np.
I can't see what I'm doing wrong. Can anyone help ?
EDIT
I've noticed that if I change:
metadataStore.registerEntityTypeCtor(entityName, jobCtor, jobInitializer);
to
metadataStore.registerEntityTypeCtor(entityName, null, jobInitializer);
Then everything works fine again ! So the problem is registering the same jobCtor function. Should that not be possible ?
Our Bad
Let's start with a Breeze bug, recently discovered, in the Breeze "backingStore" model library adapter.
There's a part of that adapter which is responsible for rewriting data properties of the entity constructor so that they become observable and self-validating and it kicks in when register a type with registerEntityTypeCtor.
It tries to keep track of which properties it has rewritten. The bug is that it records the fact of rewrite on the EntityType rather than on the constructor function. Consequently, every time you registered a new type, it failed to realize that it had already rewritten the properties of the base Job type and re-wrapped the property.
This was happening to you. Every derived type that you registered re-wrapped/re-wrote the properties of the base type (and of its base type, etc).
In your example, a base class Job property would be re-written 3 times and its inner logic executed 3 times if you registered three of its sub-types. And the problem disappeared when you stopped registering constructors of sub-types.
We're working on a revised Breeze "backingStore" model library adapter that won't have this problem and, coincidentally, will behave better in test scenarios (that's how we found the bug in the first place).
Your Bad?
Wow that's some hairy code you've got there. Why so complicated? In particular, why are you adding a one-time MetadataStore configuration to the prototypes of entity constructor functions?
I must be missing something. The code to register types is usually much smaller and simpler. I get that you want to put each type in its own file and have it self-register. The cost of that (as you've written it) is enormous bulk and complexity. Please reconsider your approach. Take a look at other Breeze samples, Zza-Node-Mongo for example.
Thanks for reporting the issue. Hang in there with us. A fix should be arriving soon ... I hope in the next release.
for Mach kernel API emulation on Linux, I need for my kernel module to get called when a task has been just created or is being terminated.
In my kernel module, this could most nicely be done via Linux Security Modules, but a couple of years ago, they prevented external modules from acting as a LSM by unexporting the needed symbols.
The only other way I could find was to make my module act like a rootkit. Find the syscall table and hook it in there.
Patching the kernel is out of the question. I need my app to be installed easily. Is there any other way?
You can use Kprobes, which enables you to dynamically hook into code in the kernel. You will need to find the right function among the ones involves in creating and destroying processes that give you the information you need. For instance, for tasks created, do_fork() in fork.c would be a good place to start. For tasks destroyed, do_exit. You would want to write a retprobe, which is a kind of kprobe that additionally gives you control at the end of the execution of the function, before it returns. The reason you want control before the function returns is to check if it succeeded in creating the process by checking the return value. If there was an error, then the function will return a negative value or in some cases possibly 0.
You would do this by creating a kretprobe struct:
static struct kretprobe do_fork_probe = {
.entry_handler = (kprobe_opcode_t *) my_do_fork_entry,
.handler = (kprobe_opcode_t *) my_do_fork_ret,
.maxactive = 20,
.data_size = sizeof(struct do_fork_ctx)
};
my_do_fork_entry gets executed when control enters the hooked function, and my_do_fork_ret gets executed just before it returns. You would hook it in as follows:
do_fork_probe.kp.addr =
(kprobe_opcode_t *) kallsyms_lookup_name("do_fork");
if ((ret = register_kretprobe(&do_fork_probe)) <0) {
// handle error
}
In the implementation of your hooks, it's a bit unwieldy to get the arguments and return value. You get these via the saved registers pt_regs data structure. Let's look at the return hook, where on x86 you get the return value via regs->ax.
static int my_do_fork_ret(struct kretprobe_instance *ri, struct pt_regs *regs)
{
struct do_fork_ctx *ctx = (struct do_fork_ctx *) ri->data;
int ret = regs->ax; // This is on x86
if (ret > 0) {
// It's not an error, probably a valid process
}
}
In the entry point, you can get access to the arguments via the registers. e.g. on x86, regs->di is the first argument, regs->si is the second etc. You can google to get the full list. Note that you shouldn't rely on these registers for the arguments in the return hook as the registers may have been overwritten for other computations.
You will surely have to jump many hoops in getting this working, but hopefully this note should set you off in the right direction.