The way I have found to get input values is
if self.inputs['inY'].is_linked and self.inputs['inY'].links.is_valid:
iny = self.inputs['inY'].links.from_socket.default_value
iny = self.inputs['inY'].default_value
Add calculations in the middle here then pass on output values -
self.outputs['result'].default_value = res
The key point being read inputs from a connecting node socket default value and write to our output default value for other nodes to read.
You don't need dummy sockets to store values, sockets are for connecting other nodes to pass on values. You can use property definitions to add properties to your nodes. These can be shown on your node in it's draw() without having input connections available.
If your concern is that updates don't just happen, then you've found that pynodes don't just automatically update yet. The solution is manual updates, sverchok adds a panel with update buttons and has a 'Bake' button on some nodes to do the updating, it also implements a caching system. Another consideration is to register a function as a handler for frame changes so that animations aren't an issue.
for n in node_tree.nodes:
There is also a nodes
internal_links property to consider, it's for "Internal input-to-output connections for muting". It is a collection of NodeLinks and I guess we use something like -
self.internal_links.from_node = self
self.internal_links.from_socket = self.input['inY']
self.internal_links.to_node = self
self.internal_links.to_socket = self.outputs['result']
I have got this far from this pynodes tutorial and looking through some of the sverchok source (luxblend is another project using pynodes) with this blender wiki page about the only other helpful source of info so far.