-
Notifications
You must be signed in to change notification settings - Fork 29
/
mtxval.c
68 lines (62 loc) · 2.32 KB
/
mtxval.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/* mtxval.c Multi-dst transaction validator
*
* Copyright (c) 2019 by Adequate Systems, LLC. All Rights Reserved.
* **** NO WARRANTY ****
*
* Date: 6 May 2019
*/
#define BAIL(m) { message = m; goto bail; }
/* Validates a multi-dst transaction MTX.
* (Does all tag checking as well.)
* tx->src_addr is already checked in ledger.dat and totals tally.
* tx_val() sets fee parameter to Myfee and bval.c sets fee to Mfee.
* Returns 0 on valid, else error code.
*/
int mtx_val(MTX *mtx, word32 *fee)
{
int j, message;
byte total[8], mfees[8], *bp, *limit;
static byte addr[TXADDRLEN];
limit = &mtx->zeros[0];
/* Check that src and chg have tags.
* Check that src and chg have same tag.
* tx_val() or bval.c has already checked src != chg, src exists,
* sig is good, and totals are good.
*/
if(!HAS_TAG(mtx->src_addr)) BAIL(1);
if(memcmp(ADDR_TAG_PTR(mtx->src_addr),
ADDR_TAG_PTR(mtx->chg_addr), ADDR_TAG_LEN) != 0) BAIL(2);
if(cmp64(mtx->change_total, Mfee) <= 0) BAIL(3);
memset(total, 0, 8);
memset(mfees, 0, 8);
/* Tally each dst[] amount and mfees... */
for(j = 0; j < NR_DST; j++) {
/* zero dst[] tag marks end of list. */
if(iszero(mtx->dst[j].tag, ADDR_TAG_LEN)) {
for(bp = mtx->dst[j].amount; bp < limit; bp++) {
if(*bp) BAIL(4); /* Check that rest of dst[] list is zeros. */
}
break;
}
if(iszero(mtx->dst[j].amount, 8)) BAIL(5); /* bad send amount */
/* no dst to src */
if(memcmp(mtx->dst[j].tag,
ADDR_TAG_PTR(mtx->src_addr), ADDR_TAG_LEN) == 0) BAIL(6);
/* tally fees and send_total */
if(add64(total, mtx->dst[j].amount, total)) BAIL(7);
if(add64(mfees, fee, mfees)) BAIL(8); /* Mfee or Myfee */
if(get32(Cblocknum) >= MTXTRIGGER) {
memcpy(ADDR_TAG_PTR(addr), mtx->dst[j].tag, ADDR_TAG_LEN);
mtx->zeros[j] = 0;
/* If dst[j] tag not found, put error code in zeros[] array. */
if(tag_find(addr, NULL, NULL) != VEOK) mtx->zeros[j] = 1;
}
} /* end for j */
/* Check tallies... */
if(cmp64(total, mtx->send_total) != 0) BAIL(9);
if(cmp64(mtx->tx_fee, mfees) < 0) BAIL(10);
return 0; /* valid */
bail:
if(message && Trace) plog("mtx_val(): %d", message);
return message; /* bad */
} /* end mtx_val() */