int inittx_ref(tx_ref_t *ref, tx_t *tx, char *name, char *hash, int type) { shkey_t *tx_key; int err; memset(ref->ref.ref_name, 0, sizeof(ref->ref.ref_name)); memset(ref->ref.ref_hash, 0, sizeof(ref->ref.ref_hash)); /* attributes */ if (name) strncpy(ref->ref.ref_name, name, sizeof(ref->ref.ref_name)-1); if (hash) strncpy(ref->ref.ref_hash, hash, sizeof(ref->ref.ref_hash)-1); ref->ref.ref_type = type; ref->ref.ref_level = tx->tx_op; /* origin peer */ memcpy(&ref->ref.ref_peer, &tx->tx_peer, sizeof(ref->ref.ref_peer)); /* populate unique key into 'external hash reference' if none specified. */ if (!*ref->ref.ref_hash) { tx_key = get_tx_key(tx); if (tx_key) memcpy(&ref->ref.ref_hash, shkey_print(tx_key), sizeof(ref->ref.ref_hash)); } /* generate new reference */ err = tx_init(NULL, (tx_t *)ref, TX_REFERENCE); if (err) return (err); return (0); }
/** * Confirm a ward's application on a transaction. */ int txward_confirm(tx_t *tx) { tx_ward_t *ward; tx_context_t *ctx; shkey_t *tx_key; int err; tx_key = get_tx_key(tx); if (!tx_key) return (SHERR_INVAL); ward = (tx_ward_t *)tx_load(TX_WARD, tx_key); if (!ward) return (SHERR_NOKEY); /* incomplete scope */ ctx = (tx_context_t *)tx_load(TX_CONTEXT, tx_key); if (!ctx) return (SHERR_AGAIN); /* transaction ward is applied. */ /* validate context to invalidate ward. */ err = txward_context_confirm(ward, ctx); pstore_free(ctx); if (err) return (err); return (0); }
int txop_ward_confirm(shpeer_t *peer, tx_ward_t *ward) { tx_context_t *ctx; tx_t *tx; int err; #if 0 /* verify identity exists */ ctx = (tx_context_t *)tx_load(TX_CONTEXT, &ward->ward_ctx); if (!ctx) return (SHERR_NOKEY); /* .. */ pstore_free(ctx); err = confirm_signature(&ward->ward_sig, shpeer_kpriv(&ward->ward_peer), shkey_hex(&ward->ward_key)); pstore_free(tx); if (err) return (err); err = inittx_context(ctx, get_tx_key(ward), ashkey_uniq()); if (err) return (err); #endif return (0); }
int txop_ward_init(shpeer_t *cli_peer, tx_ward_t *ward) { unsigned char context[128]; shkey_t sig_key; tx_context_t ctx; tx_t *tx; int err; if (ward->ward_stamp == SHTIME_UNDEFINED) ward->ward_stamp = shtime(); if (ward->ward_expire == SHTIME_UNDEFINED) ward->ward_expire = shtime_adj(shtime(), MAX_SHARE_SESSION_TIME); memcpy(&ward->ward_tx.tx_peer, shpeer_kpriv(sharedaemon_peer()), sizeof(shpeer_t)); memset(&ctx, 0, sizeof(ctx)); err = inittx_context(&ctx, get_tx_key(ward), ashkey_uniq()); if (err) return (err); err = tx_save(&ctx); if (err) return (err); /* store key reference to generated context */ memcpy(&ward->ward_ctx, &ctx.ctx_tx.tx_key, sizeof(ward->ward_ctx)); return (0); }
int pstore_save(void *data, size_t data_len) { tx_t *tx; shkey_t *s_key; tx = (tx_t *)data; s_key = get_tx_key(tx); if (!s_key) return (SHERR_INVAL); pstore_write(tx->tx_op, (char *)shkey_hex(s_key), (unsigned char *)data, data_len); return (0); }
/** * Obtain the root transaction key of the transaction hierarchy. * @returns An unallocated tx key or NULL if tx is the root tx. */ shkey_t *get_tx_key_root(tx_t *tx) { static shkey_t ret_key; tx_t *t_tx; tx_t *p_tx; t_tx = tx; memcpy(&ret_key, ashkey_blank(), sizeof(ret_key)); while ((p_tx = get_tx_parent(t_tx))) { if (t_tx != tx) pstore_free(t_tx); t_tx = p_tx; memcpy(&ret_key, get_tx_key(t_tx), sizeof(ret_key)); } return (&ret_key); }
int pstore_delete_tx(tx_t *tx) { shkey_t *s_key; int err; if (!tx) return (SHERR_INVAL); s_key = get_tx_key(tx); if (!s_key) return (SHERR_INVAL); err = pstore_delete(tx->tx_op, (char *)shkey_hex(s_key)); if (err) return (err); return (0); }
int inittx_ward(tx_ward_t *ward, tx_t *tx, tx_context_t *ctx) { shkey_t *tx_key; int err; tx_key = get_tx_key(tx); if (!tx_key) return (SHERR_INVAL); memcpy(&ward->ward_ref, tx_key, sizeof(ward->ward_ref)); txward_context_sign(ward, ctx); err = tx_init(NULL, (tx_t *)ward, TX_WARD); if (err) return (err); return (0); }
int inittx_trust(tx_trust_t *trust, tx_t *ref_tx, shkey_t *context) { shkey_t *tx_key; int err; if (!trust) return (SHERR_INVAL); tx_key = get_tx_key(ref_tx); if (!tx_key) return (SHERR_INVAL); if (!context) context = ashkey_blank(); memcpy(&trust->trust_ref, tx_key, sizeof(shkey_t)); memcpy(&trust->trust_ctx, context, sizeof(shkey_t)); err = tx_init(NULL, trust, TX_TRUST); if (err) return (err); return (0); }
int tx_recv(shpeer_t *cli_peer, tx_t *tx) { tx_ledger_t *l; tx_t *rec_tx; txop_t *op; int err; if (!tx) return (SHERR_INVAL); #if 0 if (ledger_tx_load(shpeer_kpriv(cli_peer), tx->hash, tx->tx_stamp)) { fprintf(stderr, "DEBUG: tx_recv: skipping duplicate tx '%s'\n", tx->hash); return (SHERR_NOTUNIQ); } #endif op = get_tx_op(tx->tx_op); if (!op) return (SHERR_INVAL); if (tx->tx_flag & TXF_WARD) { err = txward_confirm(tx); if (err) return (err); } /* check for dup in ledger (?) */ rec_tx = (tx_t *)tx_load(tx->tx_op, get_tx_key(tx)); if (!rec_tx) { rec_tx = (tx_t *)calloc(1, op->op_size); if (!rec_tx) return (SHERR_NOMEM); memcpy(rec_tx, tx, op->op_size); #if 0 err = tx_init(cli_peer, rec_tx); if (err) { pstore_free(rec_tx); return (err); } #endif err = tx_save(rec_tx); if (err) { pstore_free(rec_tx); return (err); } } if (op->op_recv) { err = op->op_recv(cli_peer, tx); if (err) { pstore_free(rec_tx); return (err); } } pstore_free(rec_tx); if (is_tx_stored(tx->tx_op)) { l = ledger_load(shpeer_kpriv(cli_peer), shtime()); if (l) { ledger_tx_add(l, tx); ledger_close(l); } } return (0); }