transaction_summary transaction_validator::on_evaluate( transaction_evaluation_state& state, const block_evaluation_state_ptr& block_state ) { transaction_summary sum; state.inputs = _db->fetch_inputs( state.trx.inputs ); auto trx_delegate = _db->lookup_delegate( state.trx.vote ); FC_ASSERT( !!trx_delegate, "unable to find delegate id ${id}", ("id",state.trx.vote) ); /** make sure inputs are unique */ std::unordered_set<output_reference> unique_inputs; for( auto in : state.trx.inputs ) { FC_ASSERT( unique_inputs.insert( in.output_ref ).second, "transaction references same output more than once.", ("trx",state.trx) ) } /** validate all inputs */ for( auto in : state.inputs ) { FC_ASSERT( !in.meta_output.is_spent(), "", ("trx",state.trx) ); validate_input( in, state, block_state ); } /** validate all inputs */ for( auto out : state.trx.outputs ) validate_output( out, state, block_state ); state.balance_assets(); sum.valid_votes = state.valid_votes; sum.invalid_votes = state.invalid_votes; sum.spent = state.spent; sum.fees = state.get_total_in(0) - state.get_total_out(0); if( state.get_required_fees() >= 0 ) { FC_ASSERT( sum.fees >= state.get_required_fees(0), "", ("fees",sum.fees)("required",state.get_required_fees())); } return sum; }
int main(int argc, char *argv[]) { char *user = NULL; char *input = NULL; char *output = NULL; int input_location = 0; bool multiple_input = false; bool one_passed = false; bool output_is_dir = false; struct config cfg; int c; while((c=getopt(argc, argv, "hdu:")) != -1) { switch(c) { case 'u': user = optarg; break; case 'h': usage(argv[0]); exit(NO_ERROR); case 'd': _debug = 1; break; case '?': if(strchr("u", optopt) == NULL) fprintf(stderr, "Unknown option -%c encountered\n", optopt); else fprintf(stderr, "Option -%c requires an argument\n", optopt); exit(USAGE_ERROR); default: abort(); } } debug("optind: %d, argc: %d", optind, argc); if(optind + 2 == argc) { input = argv[optind]; output = argv[optind + 1]; multiple_input = false; } else if (optind + 2 < argc) { input_location = optind; output = argv[argc - 1]; multiple_input = true; } else { fprintf(stderr, "Invalid number of arguments\n"); usage(argv[0]); exit(USAGE_ERROR); } if(user == NULL) { fprintf(stderr, "Error, user must be supplied with -u <user> argument\n" "\tRerun with -h to see usage-details\n"); exit(USAGE_ERROR); } /* All of these functions exit the program unless everything is A-OK */ read_config(CONFIG_PATH, &cfg); /* If the user running the program doesn't match the config-file, exit */ die_unless_user(cfg.required_user); /* Try to become target user iff. they are a member of the right group */ if_valid_become(user, cfg.required_group); /* Append a '/' if the output is a dir and it doesn't have one */ output = dirify_output(output, &output_is_dir); debug("output now: %s (%d)", output, output_is_dir); /* If the output path isn't in the list of allowed outputs, exit */ validate_output(output, cfg.allowed_paths); destroy_config(&cfg); /* Do the actual copy, failing on any error condition */ if(!multiple_input) { copy_file(input, output); } else { struct stat sb; char *p; int i; if(!output_is_dir) log_exit(USAGE_ERROR, "Error: destination %s must be a directory", output); debug("Multiple inputs, %d files to %s", argc - input_location - 1, output); for(i = input_location; i < argc - 1; i++) { p = argv[i]; if(stat(p, &sb) < 0) log_exit_perror(FILEPERM_ERROR, "stat input: %s", p); switch(sb.st_mode & S_IFMT) { case S_IFREG: debug("************** Copy file %d ****************", i - input_location + 1); copy_file(p, output); one_passed = true; break; case S_IFDIR: log_msg("%s is a directory, skipping", p); break; default: log_msg("%s is not a regular file, skip", p); break; } } } /* changed by dirify() above */ free(output); if(multiple_input && !one_passed) { debug("No files copied, exit NO_ACTION_ERROR"); return NO_ACTION_ERROR; } else { debug("Finished, exit OK"); return NO_ERROR; } }