Less circuitous way to get network fee in raw transaction I have my code working correctly now to create and send a transaction with the correct network fee. Here is my pseudo-code using the json rpc:


Estimate network fee using estimatesmartfee "ECONOMICAL" based on a typical transaction size
Adjust payout amount based on fee estimate
createrawtransaction using estimated payout amount
signrawtransaction
read size of decoded raw transaction from step 2
Recalculate network fee using estimatesmartfee "ECONOMICAL" based on a actual transaction size from last step
Adjust payout amount based on actual network fee 
createrawtransaction using actual payout amount
signrawtransaction
sendrawtransaction


Steps 6-9 repeats Steps 1-4.

Is there a way to do this without having to call everything twice?
If the inputs to the transaction are known to the Bitcoin Core wallet, then you can use the fundrawtransaction command to skip fee estimation and input selection. The process then becomes:


createrawtransaction with only the outputs you want (i.e. no change, only the recipients).
fundrawtransaction
signrawtransaction
sendrawtransaction




If you are not using Bitcoin Core's wallet, you can use effective values.

Presumably you know the amounts in the inputs before you actual create the transaction. So you can then calculate how large the inputs will be, calculate how much in fees that will cost based on the output of estimatesmartfee, and subtract that fee amount from the actual value of the input. This is your effective value.

When you create the outputs, you calculate the total size of the non-input data and calculate the fees for those data. Now you have how much total value your inputs must cover. You can then select coins that way.

So the process is:


estimatesmartfee
For each potential input, calculate the fee for that input and compute the effective value.
For each output (including change if you assume that there will be change) and for the extra fixed size transaction overhead, calculate the non-input fees.
Add the non-input fees to the amount you want to send, this is the amount that your inputs will need to cover the total cost.
Choose the inputs you want to spend based upon their effective values.
createrawtransaction, signrawtransaction, sendrawtransaction.




The size of inputs in vbytes are as follows:

P2PKH: 148 vbytes

P2WPKH: 37 vbytes

P2SH-P2WPKH: 60 vbytes

For P2SH and P2WSH inputs, it depends on the script that you are using. Most people though will be using P2PKH, P2WPKH, or P2SH-P2WPKH.