diff --git a/config/consensus.go b/config/consensus.go
index ffa7dadaa3..566451d2b2 100644
--- a/config/consensus.go
+++ b/config/consensus.go
@@ -342,6 +342,10 @@ type ConsensusParams struct {
// CompactCertSecKQ is the security parameter (k+q) for the compact
// certificate scheme.
CompactCertSecKQ uint64
+
+ // EnableAssetCloseAmount adds an extra field to the ApplyData. The field contains the amount of the remaining
+ // asset that were sent to the close-to address.
+ EnableAssetCloseAmount bool
}
// ConsensusProtocols defines a set of supported protocol versions and their
@@ -827,6 +831,9 @@ func initConsensusProtocols() {
vFuture.CompactCertWeightThreshold = (1 << 32) * 30 / 100
vFuture.CompactCertSecKQ = 128
+ // Enable AssetCloseAmount field
+ vFuture.EnableAssetCloseAmount = true
+
Consensus[protocol.ConsensusFuture] = vFuture
}
diff --git a/daemon/algod/api/algod.oas2.json b/daemon/algod/api/algod.oas2.json
index 87a98306ae..595cd752fd 100644
--- a/daemon/algod/api/algod.oas2.json
+++ b/daemon/algod/api/algod.oas2.json
@@ -2148,6 +2148,10 @@
"description": "Closing amount for the transaction.",
"type": "integer"
},
+ "asset-closing-amount": {
+ "description": "The number of the asset's unit that were transferred to the close-to address.",
+ "type": "integer"
+ },
"confirmed-round": {
"description": "The round where this transaction was confirmed, if present.",
"type": "integer"
diff --git a/daemon/algod/api/algod.oas3.yml b/daemon/algod/api/algod.oas3.yml
index b38d27985f..78fe01e8a6 100644
--- a/daemon/algod/api/algod.oas3.yml
+++ b/daemon/algod/api/algod.oas3.yml
@@ -463,6 +463,10 @@
"description": "The application index if the transaction was found and it created an application.",
"type": "integer"
},
+ "asset-closing-amount": {
+ "description": "The number of the asset's unit that were transferred to the close-to address.",
+ "type": "integer"
+ },
"asset-index": {
"description": "The asset index if the transaction was found and it created an asset.",
"type": "integer"
@@ -3129,6 +3133,10 @@
"description": "The application index if the transaction was found and it created an application.",
"type": "integer"
},
+ "asset-closing-amount": {
+ "description": "The number of the asset's unit that were transferred to the close-to address.",
+ "type": "integer"
+ },
"asset-index": {
"description": "The asset index if the transaction was found and it created an asset.",
"type": "integer"
@@ -3189,6 +3197,10 @@
"description": "The application index if the transaction was found and it created an application.",
"type": "integer"
},
+ "asset-closing-amount": {
+ "description": "The number of the asset's unit that were transferred to the close-to address.",
+ "type": "integer"
+ },
"asset-index": {
"description": "The asset index if the transaction was found and it created an asset.",
"type": "integer"
diff --git a/daemon/algod/api/server/v1/handlers/handlers.go b/daemon/algod/api/server/v1/handlers/handlers.go
index 1d9e8fe68a..1e3b0f634d 100644
--- a/daemon/algod/api/server/v1/handlers/handlers.go
+++ b/daemon/algod/api/server/v1/handlers/handlers.go
@@ -315,6 +315,10 @@ func assetTransferTxEncode(tx transactions.Transaction, ad transactions.ApplyDat
xfer.CloseTo = tx.AssetTransferTxnFields.AssetCloseTo.String()
}
+ if ad.AssetClosingAmount != 0 {
+ xfer.CloseToAmount = ad.AssetClosingAmount
+ }
+
return v1.Transaction{
AssetTransfer: &xfer,
}
diff --git a/daemon/algod/api/server/v2/generated/private/routes.go b/daemon/algod/api/server/v2/generated/private/routes.go
index 8c3a30f411..2f3dce9817 100644
--- a/daemon/algod/api/server/v2/generated/private/routes.go
+++ b/daemon/algod/api/server/v2/generated/private/routes.go
@@ -272,95 +272,95 @@ var swaggerSpec = []string{
"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",
- "KrjkVeZ7DE9LwWISITO4imtX3omNZHDFRBzpZTOzMCz1V04yBDCLCrq7xNuCgguK3GZyHBqf1l5RWSrp",
- "2OUlNaAAFCKtFLd3krgYa89Nc+1WQcERO7odc+Z2fE4hV4m9Ao2YR9vur0h9aDrkmThczyejkt2wxuUa",
- "6NYF1XWPiCG34ZESNIwtZJWrBc8TdLQhySA3O0Ne6MDDS+qJdlKlw+FdlM/O3ufZ2dkH9hr7kk8P7Bw2",
- "c7opZumayxW04fuQT623DleQ1qFK75FxrwOYi1F2se8ewaaTUqk8aY6a/euGgZrv0/1cpOeQMdQT5GA5",
- "63Ovu0M4CbuPLK6bC5nL9ca7bmUJErIHM8aOJIOiNBsX1+h5Gr3J5T2zbf4rmjWr6W6YS0aLnJ3JeEjB",
- "3ix/okx5MNslyaZafeJUFsj2icyVHBEnfkkXIwguKp9bo5InNDIwOQNLGjCVxWKfs/s3lH/EO7ssMjoG",
- "tFZF14tCUBJS0G2KmtPfCw9P1sLMGDsl3YEHGw0XUPGcMiy0D9gKzQqBB2RdpylAdngmkw4mqSrcxPfb",
- "/1q1dFYfHDwBdvCgP0YbdBPdGc7KQH/sl+xgapuIXOxLdjY5mwwgVVCoC8jsOSjkaztqJ9j/08A9kz8M",
- "FDMr+MaeoLwsMl0vlyIVlui5Qr2+Uj1vTypqgQrRAzyzaSbMlEwZUZS8ZLsvrQBOol7LXcRaIlDRP0ZT",
- "itrO3wZ2eUczuOIprpKTktmwS2SUhs+GzodRZRICiIZ+t8zogu+6o8dvKXdDfW4P/tvxO+0d/TvkCNh1",
- "tttnHhAjisE+4n/ESoW7Llzej08OyYU2AyRdGIBuXhqGjBidGfsPVbOUk/yWtYHmTKUqOqjQARZnIBvr",
- "53SeWkshyKEAG5mhlocP+wt/+NDtudBsCZc+WQ479snx8KEVAqXNJ0tAjzWvjiMOFAXE0ZpGEpzXXK9n",
- "O4PjBHevmHgA+viln5CESWsyMdfTCR51880dCLwFxCpw/p7uhIi0bVXLMDHP7Z/eaAPFMMpqh/484om+",
- "8ye0gaVVMhcSkkJJ2ERz0YWE76kxaqeJRUYGk7COje2fYDv499DqzrPPbn4qfWm3A5Z426QJ3sHm9+H2",
- "AuxhSiJ5mZCXjLM0FxQ+VFKbqk7NmeQUoOi5QT228GGX8ZDVC98lHiOLhLAcqDPJNdKwCVtEL16WEAlI",
- "fg3gI1e6Xq1A99witgQ4k66XkKyWwtBc5FUmdsNKqOiGbGZ7oiew5DlF2H6HSrFFbbqqlzKnrGdjo/04",
- "DVPLM8kNy4Frw74X8vSKwPkTjucZCeZSVecNFUZOaCBBC53ELxG/sa3fcr32y8eOXtm4wTaejfDb9KqN",
- "gU5q9n/e/9vh+6Pk7zz5/SB5/n/nHz4+vX7wcPDj4+svv/yv7k9Prr988Lc/x3bK4x7L63GYH790bsnx",
- "S7I9bZx/gPtnC/4WQiZRJsPjQiEkpYf2eIvdRwvqGehBe2Pgdv1MmiuJjHTBc5HhEfg27NBXcQNZtNLR",
- "45rORvRieX6tH2LHnZVKSp6e0x38ZCXMul7MUlXMvTs2X6nGNZtnHAolqS2b81LM8Xg7v3i0wzR+gr5i",
- "EXV1PZ04raPvPNvHAY4tqD9nE0X3fxvF7n3z6pTN3U7pezbJz4IOsrMiHrR7Y9Y5zOHi7SMVm+WIh5mX",
- "sBRSYPvhmcy44fMF1yLV81pD9RXPuUxhtlLskDmQL7nhFAPoRRTH3pFRfMZhU9aLXKTsPDTFrWiOBcbO",
- "zt4jg5ydfRjcuQ0Np5sqHmykCZJLYdaqNomLyo7HEdpYC0G2cblts06Zg2050kV9HfyRAGhZ6iSIiMWX",
- "X5Y5Lj9gQ81oEOVsMW1U5ZUgakYX08D9faPcrWPFL33mfI3n9l8KXr4X0nxgiTt/H5Ulhdso3vWL0zXI",
- "k5sS9o+ZtSi2wGLnLFq4dahunMdHQE/sKB9E1nHKYRORjvqgVmhjgrelE4L6VuW4ubcmUwAjSp3arBOU",
- "qeiqNLIWyUPw3pGvUBf6uzc8NiPzufc3C2DpGtJzyOjigWKE085wf73rLIsXWaHtkxmbrkd53XQcXACr",
- "y4w728vlpp9gq8EYn1X8Ds5hc6ratPCbZNReTycuqJ8gz4wJSIn0CIyAWnbFxV8M9Dbf3a1Q4L0smY1t",
- "20xIzxaHDV/4MeMCZC3THQhPjCkaMmzh95JXEUJY5h8hwS0WivA+ifWjkXReGZGK0q5/v9j8284YBLJL",
- "qUfVuFr2tfVAmUa1t+2cLLiOK27AFtwPlKF+JoWfyUZW7CUZo2fXjnEXOQS3StpJNq/I2fHLtu9Ix1CL",
- "cwlUsrWmHo0uRUKzvXbXkuKivYyka+d9DNzOSynkIp8vILrhZ4Hz5nDBR28CRt87HAdJAMEzuuY1g1ds",
- "fWGYNi9b7It2/+rBP3Xw7xsm0xu9VZhOXF5abDuUJOueQQ4r7gLflPHmGMWhdk8HG4R4/LBc5kICS2L5",
- "BFxrlQp7F9rqcjcHoPP3kDEbWGF7Q4ixcYA2RQwJMHujQtmUq5sgKUFQiJF72BRrDP6G3RG3trSAcyt3",
- "un9D3dEK0bR9+mO3cRj9mU6iKmnMM+/0YrbLAgZHmRiLomoaxkOGURcNOZA5TjqaNTmPRcnQqwBiwxM/",
- "LHDX2X2xRCP/IAgcV7DCs3d7XkVp9QGYzxszuFAGkqWotEnoqBxdHnb6WpMz+DV2jaufDqmYfZsssrj2",
- "oWnPYZNkIq/ju+3m/e4lTvumObfoenEOGzIywNM1W9BberRCnemxz5apbU7N1gW/tgt+ze9svfvxEnbF",
- "iSulTG+OPwhX9fTJNmGKMGCMOYa7NkrSLeolyEYY6pYgD8LmTFB+xWzbaX0gTDfO6BjVvBZSdC2Bo7t1",
- "FTbxx+b2BE/Rh/ndIzLAy1JkV72zs4Ua53Ga4iaOuvX4B1Sg3XXAdlAgOCfHUggr8Gd9u6WBzbRFBQZp",
- "Vrsp00/uChRCOJXQviTOkFDI2pSNs4tWp8Dz72DzE/al5Uyup5NPO/LHaO0g7qD122Z7o3SmGLI9AnYi",
- "ZzckOS/LSl3wPHFPaMZYs1IXjjWpu39x85lVXfz4ffrq6PVbhz5lrwGvXNLWtlVRv/IPsyo8Eccyt06D",
- "yAh5q/7sbB2xYPObd4xhMMUn2nV8OdRijrmseDUGLhRFF1xZxq+ydoZKwuS8W0lmJ7vvUyNzYarfnYr8",
- "QMLiHNru8A69EM61pQhCYet8aKZkP8EB3Tg6ZRK7FHyDu2gDs0MFIesiQRFIdC7SeOhALjRKkawLelyy",
- "McCo84hDiBBrMRI+l7UIYGE3vcdNUQ/JYI4oMSmss4V2C+UKtNVS/FYDExlIg02VS3jqCAvKhs/hHZq0",
- "eL6wA+xShhvwn2LnEdSYhSckthv5MMobyRL3hz6/0CY8jT8EwbkbXNKEMw7M0pYLFscfjpvtTfe6G60N",
- "66kNdRAyhq29sbuYmw8drC2iI3NEi7ONauyjcW1NeeD76+lWLRO6oUK2uXk81yoCppaXXNpaSzjO0tCN",
- "1mDP7TjqUlX0aElD9IZa6GRZqd8hfppc4kZFcrAcKcllo9GzyGOQvhJtIiNtFT1P3xCPUdYe86aCRta9",
- "RBuRcOLyIHxNSaU+yMSlZWtbF6pzdRsXjjDdYm7ht8LhcB6kqOT8csFjJRLQqUGcjtqLkk44zCjmB/td",
- "0E0uteO94M6l6SvsS58SqjZRcviq9JYOyh+L5TNIRcHzeHQ0I+p33zVmYiVsca1aQ1C9yQGyVQktF7kK",
- "WPYqqiXN8ZIdTIP6cG43MnEhtFjkQD0e2R4LrslqNSHPZgguD6RZa+r+eI/u61pmFWRmrS1htWKNE2kf",
- "N/j48wLMJYBkB9Tv0XN2nyLvWlzAA6Si80Umh4+eU0qG/eMgZuxcFb1teiUjxfJvTrHE+ZiuHiwMNFIO",
- "6iz66syWPh1XYVukyQ7dR5aop9N6u2Wp4JKvIH6jWuzAyY6l3aTAXY8uMrN1+7Sp1IYJE58fDEf9NJKW",
- "herPouFy5QsUIKOYVgXyU1uayU7qwdkigK5cisfLN9I1R+nfPPQOrZ83SGtteWzVdBn1hhfQJeuUcfs4",
- "k55tuEe9TiHORupaQHURn6Qa2WBvN91Ydl8qmRQoO9mDNuEv4L9oWQdleB6d1njd1c9c2Q56X1cLoSSj",
- "hK07hOWBTro1iesqvk5e41Q/vnvtDEOhqliNhlYbOiNRgakEXEQltp+41ngmjbnwlI85KF/VIs9+atNN",
- "e+WQKi7TdTT+ucCBP7f12xqyW6pHn+CtuZSQR8FZWf7Zy3xEK/2q9p2nEHLPvv0yR3a5vcW1iHfR9Ej5",
- "CZG8wuQ4QUjVbv5dkziSr1TGaJ72kXXLCMM3UkHJl99q0Cb2nosabK4TnbHRX7EVRxjIjKz9jNn3T4hL",
- "5wULWVlR1Ll9DQHZCioXgKnLXPFsyhDO6auj18zOqt0bWnp3QxVPVvYtXWcVvbNVUJHhJo8Lx1Kj9oez",
- "PWcEV60NPcnWhhdlLOsVe5z6DpRae8FF7tMPyPyE1Jmxl9bya29X7CTtG1LWTOd0DfEE/scYnq7JpHYM",
- "0DjL71+qx3OlDkpWNtX/mqIK9lmkUb5ajy3WM2UK/Z5LoW3ZXbiAbqJtk3XuXDqfeNtdXlVLaTklbp+2",
- "vIq4Ddk9cvZiz4ekopj1CH9DM6NVXaVw08pFJzQq+saqXwZpUKtSQnZ6JZtacb6cesqlkiKlF05Bod8G",
- "ZVfCd5+Y6R6PwfrHZS/iTkIjwhUtvtSkDjgqjpZj8orQEW4YMApacVMtd9g/DdWKxYPgCox2mg2yqS+w",
- "5c5xQmpwRTKomnOgJ/E43r8/jF5ttM/1b8hGlP434q58jW3kqgiXsnMuJD1edWRz2UH2pEUVRg0e74Rh",
- "KwXaraf7OEu/xzGz0yt5jBh/mPmKpATDhpBx2fbOYgjqyN9guBsD7PsC+zIKF7c/d1IN7aRHZekmjWkC",
- "3exwrETYKIEjUfDEhyED4jbwQ2hb2G3r1SPZU2Q0uKCLCyjJDg8YY+QJ/Cs81FqOsi9p7ZV/9GmGkBE0",
- "XgsJbb3ciIFIoyaBNobkdWScTiturAu4l047BZ7TTUlMoWnjQkefCqq3wUQSWqOfY3wb20JxI4qj6dA6",
- "blxumjK9yN2BM/GC6oM7Qg7LvpFX5ZyojJK6eoXgYooDFbcvodg1AEMxGPpEdripuJWcm1iisST0TGg8",
- "jhSLPJLG8rJpDIohUr7cYkP/xh4gj6/AXazdumAGDbyxf7m9eEWOe59osbrlrrTj73BbejIQ7lGM+1+h",
- "Wgnf7QzeklvF0zyroSt85UvT0qGiSUzv8iwpuuihra0yuv3QOl4vdEqqcSSR5137YpRb7Wtjg2PpPOlo",
- "9hk3LrXUcLatiowt8hmDYO8hbXFR+6GOaGBg7O7RXj1i82D0fn7DwAsj2FsJ6i+1hwh957NWWMmFC3y3",
- "IjKkrMtvG2Yc7pP50m5wfxEua4yAxFZyyySvvWRvSKWIYIepATvY87xDUvsapOdJqgrumLSBCb0haYdJ",
- "D/suj9ZBHFNrGK5z7w3o0HaE9vsQvtULQ+KOi7NZ7CPO8aR6HE76xBLEP/sYapPPpg06tYndvLFd/2ks",
- "emBPyCOBqh5Na5Fnuza3E3ZsnzNTYO3nxRdPO9G7z/mg+md7IT8UN/e29CaGv78JRJjIWjuTB1MFAcU9",
- "YoluWCRySLWg0roSZkO5O97TFD9H85K/AekqNLuC980NqLuAs99acaHpVdO7/TzGN8qWrC7Q/SVX0FCR",
- "lFdXvChzcHLx5b3FX+DJX59mB08e/WXx14NnByk8ffb84IA/f8ofPX/yCB7/9dnTA3i0/OL54nH2+Onj",
- "xdPHT7949jx98vTR4ukXz/9yz3+bwiLafvfh36nqQHL09jg5RWRbmvBSfAcb+84Y2di/YOYpSSIUXOST",
- "Q//T//MSNktVEXxOz/06cZH+ydqYUh/O55eXl7NwyHxFZfsSo+p0PffzDGvSvD1uArT2wp921MbekBVo",
- "Ux0rHFHbu1cnp+zo7fGsZZjJ4eRgdjB7RIVCSpC8FJPDyRP6iaRnTfs+d8w2Ofx4PZ3M18Bzs3Z/FGAq",
- "kfomfclXK6hm7ik3/nTxeO7jO/OP7pL7eltbN8vAPR0JBgRvD+cfO/UWsxAuvcybf/QZGEGTrSc8/0jh",
- "o+B3V2Vz/rEte3tteT2H2DnelwVru1O5L/oagLa/Inv7W0Khu1WSm706znCPcNSLpgRw+NHT9/+knwj8",
- "0PtiyuODg3+ybz88veGKt3qnndNcpGrCVzxj/qaI5n70+eY+lvRuA9UTs+r3ejp59jlXfyyR5XnOqGeQ",
- "2zHc+h/luVSX0vdEW1kXBa82Xox1Ryn4wt6kkflKUxnCSlzgEf0D1bmMXc2NKBf6yMaNlQt9OeRfyuVz",
- "KZc/xidVHt9QwP/4K/6XOv2jqdMTq+72V6fOlbPJCHNbCK718PwbyOHDwK5vOqaT3cGF3aeop4TLBy6h",
- "wYKNPDJtLo9VZiMcvlCQT5Nys84GOvudA9p5z/wdbPQuBX66BvZL+5n7XyiZk64SpkxV7Bee58Fv9LVS",
- "74TPRr6Z3zw83PeD+dfX0xhaSwCfWkoppK6WKRqyc/BPVC0NOteNwxv6tqzcEka/m2urb4UazLHgo4OD",
- "g1hqTx9nF42xGFMq76VKcriAfLjVY0j0Xqpu+8rk6Hc4hg+Mw1N0hOv8R5mbN8ejH93svpq9CXYvlbxn",
- "2CUXrqR6UKXGfpilEMZ/j9am/Lh0wMZGxL9hmiDI7Z84/lTj/cerTXq9RdnpdW0ydSnHFRe9FeK5S7al",
- "9NcmeGAU8wAaTTVj/gOD+cZ/IZdxSj5Stel+uNoXn+iVYG7KI62EpAlIymkWm1XOg5xN9yGMoRI8cZi9",
- "sd8N6em96Pc7LY5xuY8J/afy0tDR2LpXvlhJ5+85sjy6q/a7SAlRaBigMMDzuUs76f1qL4eDH7tlliO/",
- "zpuHWtHGftgl1jr/aK6CyEob7wzjh7RTTeTw/QckOGUEu01sw2GH8zldyK6VNvMJKpxuqCxs/NDQ+KPf",
- "eU/r6w/X/x0AAP//DI8H3kOGAAA=",
+ "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",
}
// GetSwagger returns the Swagger specification corresponding to the generated code
diff --git a/daemon/algod/api/server/v2/generated/private/types.go b/daemon/algod/api/server/v2/generated/private/types.go
index e8a30a9289..9ec60c2cbd 100644
--- a/daemon/algod/api/server/v2/generated/private/types.go
+++ b/daemon/algod/api/server/v2/generated/private/types.go
@@ -529,6 +529,9 @@ type PendingTransactionResponse struct {
// The application index if the transaction was found and it created an application.
ApplicationIndex *uint64 `json:"application-index,omitempty"`
+ // The number of the asset's unit that were transferred to the close-to address.
+ AssetClosingAmount *uint64 `json:"asset-closing-amount,omitempty"`
+
// The asset index if the transaction was found and it created an asset.
AssetIndex *uint64 `json:"asset-index,omitempty"`
diff --git a/daemon/algod/api/server/v2/generated/routes.go b/daemon/algod/api/server/v2/generated/routes.go
index a84f3ce68e..32f6e331d4 100644
--- a/daemon/algod/api/server/v2/generated/routes.go
+++ b/daemon/algod/api/server/v2/generated/routes.go
@@ -561,170 +561,171 @@ func RegisterHandlers(router interface {
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
- "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",
+ "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",
}
// GetSwagger returns the Swagger specification corresponding to the generated code
diff --git a/daemon/algod/api/server/v2/generated/types.go b/daemon/algod/api/server/v2/generated/types.go
index ea289a1a74..0dfe5b7b8d 100644
--- a/daemon/algod/api/server/v2/generated/types.go
+++ b/daemon/algod/api/server/v2/generated/types.go
@@ -529,6 +529,9 @@ type PendingTransactionResponse struct {
// The application index if the transaction was found and it created an application.
ApplicationIndex *uint64 `json:"application-index,omitempty"`
+ // The number of the asset's unit that were transferred to the close-to address.
+ AssetClosingAmount *uint64 `json:"asset-closing-amount,omitempty"`
+
// The asset index if the transaction was found and it created an asset.
AssetIndex *uint64 `json:"asset-index,omitempty"`
diff --git a/daemon/algod/api/server/v2/handlers.go b/daemon/algod/api/server/v2/handlers.go
index 58925aafc9..acc5605c98 100644
--- a/daemon/algod/api/server/v2/handlers.go
+++ b/daemon/algod/api/server/v2/handlers.go
@@ -442,17 +442,18 @@ func (v2 *Handlers) PendingTransactionInformation(ctx echo.Context, txid string,
// Encoding wasn't working well without embedding "real" objects.
response := struct {
- AssetIndex *uint64 `codec:"asset-index,omitempty"`
- ApplicationIndex *uint64 `codec:"application-index,omitempty"`
- CloseRewards *uint64 `codec:"close-rewards,omitempty"`
- ClosingAmount *uint64 `codec:"closing-amount,omitempty"`
- ConfirmedRound *uint64 `codec:"confirmed-round,omitempty"`
- GlobalStateDelta *generated.StateDelta `codec:"global-state-delta,omitempty"`
- LocalStateDelta *[]generated.AccountStateDelta `codec:"local-state-delta,omitempty"`
- PoolError string `codec:"pool-error"`
- ReceiverRewards *uint64 `codec:"receiver-rewards,omitempty"`
- SenderRewards *uint64 `codec:"sender-rewards,omitempty"`
- Txn transactions.SignedTxn `codec:"txn"`
+ AssetIndex *uint64 `codec:"asset-index,omitempty"`
+ AssetClosingAmount *uint64 `codec:"asset-closing-amount,omitempty"`
+ ApplicationIndex *uint64 `codec:"application-index,omitempty"`
+ CloseRewards *uint64 `codec:"close-rewards,omitempty"`
+ ClosingAmount *uint64 `codec:"closing-amount,omitempty"`
+ ConfirmedRound *uint64 `codec:"confirmed-round,omitempty"`
+ GlobalStateDelta *generated.StateDelta `codec:"global-state-delta,omitempty"`
+ LocalStateDelta *[]generated.AccountStateDelta `codec:"local-state-delta,omitempty"`
+ PoolError string `codec:"pool-error"`
+ ReceiverRewards *uint64 `codec:"receiver-rewards,omitempty"`
+ SenderRewards *uint64 `codec:"sender-rewards,omitempty"`
+ Txn transactions.SignedTxn `codec:"txn"`
}{
Txn: txn.Txn,
}
@@ -467,6 +468,7 @@ func (v2 *Handlers) PendingTransactionInformation(ctx echo.Context, txid string,
response.ConfirmedRound = &r
response.ClosingAmount = &txn.ApplyData.ClosingAmount.Raw
+ response.AssetClosingAmount = &txn.ApplyData.AssetClosingAmount
response.SenderRewards = &txn.ApplyData.SenderRewards.Raw
response.ReceiverRewards = &txn.ApplyData.ReceiverRewards.Raw
response.CloseRewards = &txn.ApplyData.CloseRewards.Raw
diff --git a/daemon/algod/api/spec/v1/model.go b/daemon/algod/api/spec/v1/model.go
index b337752241..0219603c09 100644
--- a/daemon/algod/api/spec/v1/model.go
+++ b/daemon/algod/api/spec/v1/model.go
@@ -675,6 +675,11 @@ type AssetTransferTransactionType struct {
//
// required: false
CloseTo string `json:"closeto"`
+
+ // CloseToAmount is amount of the remaining funds that were transferred to the close to address (if closing).
+ //
+ // required: false
+ CloseToAmount uint64 `json:"closetoamount"`
}
// AssetFreezeTransactionType contains the additional fields for an asset freeze transaction
diff --git a/data/transactions/msgp_gen.go b/data/transactions/msgp_gen.go
index 2fa9abe868..98c1b86f9c 100644
--- a/data/transactions/msgp_gen.go
+++ b/data/transactions/msgp_gen.go
@@ -740,52 +740,61 @@ func (z *ApplicationCallTxnFields) MsgIsZero() bool {
func (z *ApplyData) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0001Len := uint32(5)
- var zb0001Mask uint8 /* 6 bits */
- if (*z).ClosingAmount.MsgIsZero() {
+ zb0001Len := uint32(6)
+ var zb0001Mask uint8 /* 7 bits */
+ if (*z).AssetClosingAmount == 0 {
zb0001Len--
zb0001Mask |= 0x2
}
- if (*z).EvalDelta.MsgIsZero() {
+ if (*z).ClosingAmount.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x4
}
- if (*z).CloseRewards.MsgIsZero() {
+ if (*z).EvalDelta.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x8
}
- if (*z).ReceiverRewards.MsgIsZero() {
+ if (*z).CloseRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x10
}
- if (*z).SenderRewards.MsgIsZero() {
+ if (*z).ReceiverRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x20
}
+ if (*z).SenderRewards.MsgIsZero() {
+ zb0001Len--
+ zb0001Mask |= 0x40
+ }
// variable map header, size zb0001Len
o = append(o, 0x80|uint8(zb0001Len))
if zb0001Len != 0 {
if (zb0001Mask & 0x2) == 0 { // if not empty
+ // string "aca"
+ o = append(o, 0xa3, 0x61, 0x63, 0x61)
+ o = msgp.AppendUint64(o, (*z).AssetClosingAmount)
+ }
+ if (zb0001Mask & 0x4) == 0 { // if not empty
// string "ca"
o = append(o, 0xa2, 0x63, 0x61)
o = (*z).ClosingAmount.MarshalMsg(o)
}
- if (zb0001Mask & 0x4) == 0 { // if not empty
+ if (zb0001Mask & 0x8) == 0 { // if not empty
// string "dt"
o = append(o, 0xa2, 0x64, 0x74)
o = (*z).EvalDelta.MarshalMsg(o)
}
- if (zb0001Mask & 0x8) == 0 { // if not empty
+ if (zb0001Mask & 0x10) == 0 { // if not empty
// string "rc"
o = append(o, 0xa2, 0x72, 0x63)
o = (*z).CloseRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x10) == 0 { // if not empty
+ if (zb0001Mask & 0x20) == 0 { // if not empty
// string "rr"
o = append(o, 0xa2, 0x72, 0x72)
o = (*z).ReceiverRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x20) == 0 { // if not empty
+ if (zb0001Mask & 0x40) == 0 { // if not empty
// string "rs"
o = append(o, 0xa2, 0x72, 0x73)
o = (*z).SenderRewards.MarshalMsg(o)
@@ -820,6 +829,14 @@ func (z *ApplyData) UnmarshalMsg(bts []byte) (o []byte, err error) {
return
}
}
+ if zb0001 > 0 {
+ zb0001--
+ (*z).AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AssetClosingAmount")
+ return
+ }
+ }
if zb0001 > 0 {
zb0001--
bts, err = (*z).SenderRewards.UnmarshalMsg(bts)
@@ -881,6 +898,12 @@ func (z *ApplyData) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "ClosingAmount")
return
}
+ case "aca":
+ (*z).AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AssetClosingAmount")
+ return
+ }
case "rs":
bts, err = (*z).SenderRewards.UnmarshalMsg(bts)
if err != nil {
@@ -925,13 +948,13 @@ func (_ *ApplyData) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *ApplyData) Msgsize() (s int) {
- s = 1 + 3 + (*z).ClosingAmount.Msgsize() + 3 + (*z).SenderRewards.Msgsize() + 3 + (*z).ReceiverRewards.Msgsize() + 3 + (*z).CloseRewards.Msgsize() + 3 + (*z).EvalDelta.Msgsize()
+ s = 1 + 3 + (*z).ClosingAmount.Msgsize() + 4 + msgp.Uint64Size + 3 + (*z).SenderRewards.Msgsize() + 3 + (*z).ReceiverRewards.Msgsize() + 3 + (*z).CloseRewards.Msgsize() + 3 + (*z).EvalDelta.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *ApplyData) MsgIsZero() bool {
- return ((*z).ClosingAmount.MsgIsZero()) && ((*z).SenderRewards.MsgIsZero()) && ((*z).ReceiverRewards.MsgIsZero()) && ((*z).CloseRewards.MsgIsZero()) && ((*z).EvalDelta.MsgIsZero())
+ return ((*z).ClosingAmount.MsgIsZero()) && ((*z).AssetClosingAmount == 0) && ((*z).SenderRewards.MsgIsZero()) && ((*z).ReceiverRewards.MsgIsZero()) && ((*z).CloseRewards.MsgIsZero()) && ((*z).EvalDelta.MsgIsZero())
}
// MarshalMsg implements msgp.Marshaler
@@ -2905,115 +2928,124 @@ func (z *SignedTxn) MsgIsZero() bool {
func (z *SignedTxnInBlock) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0001Len := uint32(12)
- var zb0001Mask uint16 /* 16 bits */
- if (*z).SignedTxnWithAD.ApplyData.ClosingAmount.MsgIsZero() {
+ zb0001Len := uint32(13)
+ var zb0001Mask uint32 /* 17 bits */
+ if (*z).SignedTxnWithAD.ApplyData.AssetClosingAmount == 0 {
zb0001Len--
zb0001Mask |= 0x10
}
- if (*z).SignedTxnWithAD.ApplyData.EvalDelta.MsgIsZero() {
+ if (*z).SignedTxnWithAD.ApplyData.ClosingAmount.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x20
}
- if (*z).HasGenesisHash == false {
+ if (*z).SignedTxnWithAD.ApplyData.EvalDelta.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x40
}
- if (*z).HasGenesisID == false {
+ if (*z).HasGenesisHash == false {
zb0001Len--
zb0001Mask |= 0x80
}
- if (*z).SignedTxnWithAD.SignedTxn.Lsig.MsgIsZero() {
+ if (*z).HasGenesisID == false {
zb0001Len--
zb0001Mask |= 0x100
}
- if (*z).SignedTxnWithAD.SignedTxn.Msig.MsgIsZero() {
+ if (*z).SignedTxnWithAD.SignedTxn.Lsig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x200
}
- if (*z).SignedTxnWithAD.ApplyData.CloseRewards.MsgIsZero() {
+ if (*z).SignedTxnWithAD.SignedTxn.Msig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x400
}
- if (*z).SignedTxnWithAD.ApplyData.ReceiverRewards.MsgIsZero() {
+ if (*z).SignedTxnWithAD.ApplyData.CloseRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x800
}
- if (*z).SignedTxnWithAD.ApplyData.SenderRewards.MsgIsZero() {
+ if (*z).SignedTxnWithAD.ApplyData.ReceiverRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x1000
}
- if (*z).SignedTxnWithAD.SignedTxn.AuthAddr.MsgIsZero() {
+ if (*z).SignedTxnWithAD.ApplyData.SenderRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x2000
}
- if (*z).SignedTxnWithAD.SignedTxn.Sig.MsgIsZero() {
+ if (*z).SignedTxnWithAD.SignedTxn.AuthAddr.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x4000
}
- if (*z).SignedTxnWithAD.SignedTxn.Txn.MsgIsZero() {
+ if (*z).SignedTxnWithAD.SignedTxn.Sig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x8000
}
+ if (*z).SignedTxnWithAD.SignedTxn.Txn.MsgIsZero() {
+ zb0001Len--
+ zb0001Mask |= 0x10000
+ }
// variable map header, size zb0001Len
o = append(o, 0x80|uint8(zb0001Len))
if zb0001Len != 0 {
if (zb0001Mask & 0x10) == 0 { // if not empty
+ // string "aca"
+ o = append(o, 0xa3, 0x61, 0x63, 0x61)
+ o = msgp.AppendUint64(o, (*z).SignedTxnWithAD.ApplyData.AssetClosingAmount)
+ }
+ if (zb0001Mask & 0x20) == 0 { // if not empty
// string "ca"
o = append(o, 0xa2, 0x63, 0x61)
o = (*z).SignedTxnWithAD.ApplyData.ClosingAmount.MarshalMsg(o)
}
- if (zb0001Mask & 0x20) == 0 { // if not empty
+ if (zb0001Mask & 0x40) == 0 { // if not empty
// string "dt"
o = append(o, 0xa2, 0x64, 0x74)
o = (*z).SignedTxnWithAD.ApplyData.EvalDelta.MarshalMsg(o)
}
- if (zb0001Mask & 0x40) == 0 { // if not empty
+ if (zb0001Mask & 0x80) == 0 { // if not empty
// string "hgh"
o = append(o, 0xa3, 0x68, 0x67, 0x68)
o = msgp.AppendBool(o, (*z).HasGenesisHash)
}
- if (zb0001Mask & 0x80) == 0 { // if not empty
+ if (zb0001Mask & 0x100) == 0 { // if not empty
// string "hgi"
o = append(o, 0xa3, 0x68, 0x67, 0x69)
o = msgp.AppendBool(o, (*z).HasGenesisID)
}
- if (zb0001Mask & 0x100) == 0 { // if not empty
+ if (zb0001Mask & 0x200) == 0 { // if not empty
// string "lsig"
o = append(o, 0xa4, 0x6c, 0x73, 0x69, 0x67)
o = (*z).SignedTxnWithAD.SignedTxn.Lsig.MarshalMsg(o)
}
- if (zb0001Mask & 0x200) == 0 { // if not empty
+ if (zb0001Mask & 0x400) == 0 { // if not empty
// string "msig"
o = append(o, 0xa4, 0x6d, 0x73, 0x69, 0x67)
o = (*z).SignedTxnWithAD.SignedTxn.Msig.MarshalMsg(o)
}
- if (zb0001Mask & 0x400) == 0 { // if not empty
+ if (zb0001Mask & 0x800) == 0 { // if not empty
// string "rc"
o = append(o, 0xa2, 0x72, 0x63)
o = (*z).SignedTxnWithAD.ApplyData.CloseRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x800) == 0 { // if not empty
+ if (zb0001Mask & 0x1000) == 0 { // if not empty
// string "rr"
o = append(o, 0xa2, 0x72, 0x72)
o = (*z).SignedTxnWithAD.ApplyData.ReceiverRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x1000) == 0 { // if not empty
+ if (zb0001Mask & 0x2000) == 0 { // if not empty
// string "rs"
o = append(o, 0xa2, 0x72, 0x73)
o = (*z).SignedTxnWithAD.ApplyData.SenderRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x2000) == 0 { // if not empty
+ if (zb0001Mask & 0x4000) == 0 { // if not empty
// string "sgnr"
o = append(o, 0xa4, 0x73, 0x67, 0x6e, 0x72)
o = (*z).SignedTxnWithAD.SignedTxn.AuthAddr.MarshalMsg(o)
}
- if (zb0001Mask & 0x4000) == 0 { // if not empty
+ if (zb0001Mask & 0x8000) == 0 { // if not empty
// string "sig"
o = append(o, 0xa3, 0x73, 0x69, 0x67)
o = (*z).SignedTxnWithAD.SignedTxn.Sig.MarshalMsg(o)
}
- if (zb0001Mask & 0x8000) == 0 { // if not empty
+ if (zb0001Mask & 0x10000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).SignedTxnWithAD.SignedTxn.Txn.MarshalMsg(o)
@@ -3088,6 +3120,14 @@ func (z *SignedTxnInBlock) UnmarshalMsg(bts []byte) (o []byte, err error) {
return
}
}
+ if zb0001 > 0 {
+ zb0001--
+ (*z).SignedTxnWithAD.ApplyData.AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AssetClosingAmount")
+ return
+ }
+ }
if zb0001 > 0 {
zb0001--
bts, err = (*z).SignedTxnWithAD.ApplyData.SenderRewards.UnmarshalMsg(bts)
@@ -3195,6 +3235,12 @@ func (z *SignedTxnInBlock) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "ClosingAmount")
return
}
+ case "aca":
+ (*z).SignedTxnWithAD.ApplyData.AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AssetClosingAmount")
+ return
+ }
case "rs":
bts, err = (*z).SignedTxnWithAD.ApplyData.SenderRewards.UnmarshalMsg(bts)
if err != nil {
@@ -3251,110 +3297,119 @@ func (_ *SignedTxnInBlock) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *SignedTxnInBlock) Msgsize() (s int) {
- s = 1 + 4 + (*z).SignedTxnWithAD.SignedTxn.Sig.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.Msig.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.Lsig.Msgsize() + 4 + (*z).SignedTxnWithAD.SignedTxn.Txn.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.AuthAddr.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.ClosingAmount.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.SenderRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.ReceiverRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.CloseRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.EvalDelta.Msgsize() + 4 + msgp.BoolSize + 4 + msgp.BoolSize
+ s = 1 + 4 + (*z).SignedTxnWithAD.SignedTxn.Sig.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.Msig.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.Lsig.Msgsize() + 4 + (*z).SignedTxnWithAD.SignedTxn.Txn.Msgsize() + 5 + (*z).SignedTxnWithAD.SignedTxn.AuthAddr.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.ClosingAmount.Msgsize() + 4 + msgp.Uint64Size + 3 + (*z).SignedTxnWithAD.ApplyData.SenderRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.ReceiverRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.CloseRewards.Msgsize() + 3 + (*z).SignedTxnWithAD.ApplyData.EvalDelta.Msgsize() + 4 + msgp.BoolSize + 4 + msgp.BoolSize
return
}
// MsgIsZero returns whether this is a zero value
func (z *SignedTxnInBlock) MsgIsZero() bool {
- return ((*z).SignedTxnWithAD.SignedTxn.Sig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Msig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Lsig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Txn.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.AuthAddr.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.ClosingAmount.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.SenderRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.ReceiverRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.CloseRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.EvalDelta.MsgIsZero()) && ((*z).HasGenesisID == false) && ((*z).HasGenesisHash == false)
+ return ((*z).SignedTxnWithAD.SignedTxn.Sig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Msig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Lsig.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.Txn.MsgIsZero()) && ((*z).SignedTxnWithAD.SignedTxn.AuthAddr.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.ClosingAmount.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.AssetClosingAmount == 0) && ((*z).SignedTxnWithAD.ApplyData.SenderRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.ReceiverRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.CloseRewards.MsgIsZero()) && ((*z).SignedTxnWithAD.ApplyData.EvalDelta.MsgIsZero()) && ((*z).HasGenesisID == false) && ((*z).HasGenesisHash == false)
}
// MarshalMsg implements msgp.Marshaler
func (z *SignedTxnWithAD) MarshalMsg(b []byte) (o []byte) {
o = msgp.Require(b, z.Msgsize())
// omitempty: check for empty values
- zb0001Len := uint32(10)
- var zb0001Mask uint16 /* 13 bits */
- if (*z).ApplyData.ClosingAmount.MsgIsZero() {
+ zb0001Len := uint32(11)
+ var zb0001Mask uint16 /* 14 bits */
+ if (*z).ApplyData.AssetClosingAmount == 0 {
zb0001Len--
zb0001Mask |= 0x8
}
- if (*z).ApplyData.EvalDelta.MsgIsZero() {
+ if (*z).ApplyData.ClosingAmount.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x10
}
- if (*z).SignedTxn.Lsig.MsgIsZero() {
+ if (*z).ApplyData.EvalDelta.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x20
}
- if (*z).SignedTxn.Msig.MsgIsZero() {
+ if (*z).SignedTxn.Lsig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x40
}
- if (*z).ApplyData.CloseRewards.MsgIsZero() {
+ if (*z).SignedTxn.Msig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x80
}
- if (*z).ApplyData.ReceiverRewards.MsgIsZero() {
+ if (*z).ApplyData.CloseRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x100
}
- if (*z).ApplyData.SenderRewards.MsgIsZero() {
+ if (*z).ApplyData.ReceiverRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x200
}
- if (*z).SignedTxn.AuthAddr.MsgIsZero() {
+ if (*z).ApplyData.SenderRewards.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x400
}
- if (*z).SignedTxn.Sig.MsgIsZero() {
+ if (*z).SignedTxn.AuthAddr.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x800
}
- if (*z).SignedTxn.Txn.MsgIsZero() {
+ if (*z).SignedTxn.Sig.MsgIsZero() {
zb0001Len--
zb0001Mask |= 0x1000
}
+ if (*z).SignedTxn.Txn.MsgIsZero() {
+ zb0001Len--
+ zb0001Mask |= 0x2000
+ }
// variable map header, size zb0001Len
o = append(o, 0x80|uint8(zb0001Len))
if zb0001Len != 0 {
if (zb0001Mask & 0x8) == 0 { // if not empty
+ // string "aca"
+ o = append(o, 0xa3, 0x61, 0x63, 0x61)
+ o = msgp.AppendUint64(o, (*z).ApplyData.AssetClosingAmount)
+ }
+ if (zb0001Mask & 0x10) == 0 { // if not empty
// string "ca"
o = append(o, 0xa2, 0x63, 0x61)
o = (*z).ApplyData.ClosingAmount.MarshalMsg(o)
}
- if (zb0001Mask & 0x10) == 0 { // if not empty
+ if (zb0001Mask & 0x20) == 0 { // if not empty
// string "dt"
o = append(o, 0xa2, 0x64, 0x74)
o = (*z).ApplyData.EvalDelta.MarshalMsg(o)
}
- if (zb0001Mask & 0x20) == 0 { // if not empty
+ if (zb0001Mask & 0x40) == 0 { // if not empty
// string "lsig"
o = append(o, 0xa4, 0x6c, 0x73, 0x69, 0x67)
o = (*z).SignedTxn.Lsig.MarshalMsg(o)
}
- if (zb0001Mask & 0x40) == 0 { // if not empty
+ if (zb0001Mask & 0x80) == 0 { // if not empty
// string "msig"
o = append(o, 0xa4, 0x6d, 0x73, 0x69, 0x67)
o = (*z).SignedTxn.Msig.MarshalMsg(o)
}
- if (zb0001Mask & 0x80) == 0 { // if not empty
+ if (zb0001Mask & 0x100) == 0 { // if not empty
// string "rc"
o = append(o, 0xa2, 0x72, 0x63)
o = (*z).ApplyData.CloseRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x100) == 0 { // if not empty
+ if (zb0001Mask & 0x200) == 0 { // if not empty
// string "rr"
o = append(o, 0xa2, 0x72, 0x72)
o = (*z).ApplyData.ReceiverRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x200) == 0 { // if not empty
+ if (zb0001Mask & 0x400) == 0 { // if not empty
// string "rs"
o = append(o, 0xa2, 0x72, 0x73)
o = (*z).ApplyData.SenderRewards.MarshalMsg(o)
}
- if (zb0001Mask & 0x400) == 0 { // if not empty
+ if (zb0001Mask & 0x800) == 0 { // if not empty
// string "sgnr"
o = append(o, 0xa4, 0x73, 0x67, 0x6e, 0x72)
o = (*z).SignedTxn.AuthAddr.MarshalMsg(o)
}
- if (zb0001Mask & 0x800) == 0 { // if not empty
+ if (zb0001Mask & 0x1000) == 0 { // if not empty
// string "sig"
o = append(o, 0xa3, 0x73, 0x69, 0x67)
o = (*z).SignedTxn.Sig.MarshalMsg(o)
}
- if (zb0001Mask & 0x1000) == 0 { // if not empty
+ if (zb0001Mask & 0x2000) == 0 { // if not empty
// string "txn"
o = append(o, 0xa3, 0x74, 0x78, 0x6e)
o = (*z).SignedTxn.Txn.MarshalMsg(o)
@@ -3429,6 +3484,14 @@ func (z *SignedTxnWithAD) UnmarshalMsg(bts []byte) (o []byte, err error) {
return
}
}
+ if zb0001 > 0 {
+ zb0001--
+ (*z).ApplyData.AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "struct-from-array", "AssetClosingAmount")
+ return
+ }
+ }
if zb0001 > 0 {
zb0001--
bts, err = (*z).ApplyData.SenderRewards.UnmarshalMsg(bts)
@@ -3520,6 +3583,12 @@ func (z *SignedTxnWithAD) UnmarshalMsg(bts []byte) (o []byte, err error) {
err = msgp.WrapError(err, "ClosingAmount")
return
}
+ case "aca":
+ (*z).ApplyData.AssetClosingAmount, bts, err = msgp.ReadUint64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AssetClosingAmount")
+ return
+ }
case "rs":
bts, err = (*z).ApplyData.SenderRewards.UnmarshalMsg(bts)
if err != nil {
@@ -3564,13 +3633,13 @@ func (_ *SignedTxnWithAD) CanUnmarshalMsg(z interface{}) bool {
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
func (z *SignedTxnWithAD) Msgsize() (s int) {
- s = 1 + 4 + (*z).SignedTxn.Sig.Msgsize() + 5 + (*z).SignedTxn.Msig.Msgsize() + 5 + (*z).SignedTxn.Lsig.Msgsize() + 4 + (*z).SignedTxn.Txn.Msgsize() + 5 + (*z).SignedTxn.AuthAddr.Msgsize() + 3 + (*z).ApplyData.ClosingAmount.Msgsize() + 3 + (*z).ApplyData.SenderRewards.Msgsize() + 3 + (*z).ApplyData.ReceiverRewards.Msgsize() + 3 + (*z).ApplyData.CloseRewards.Msgsize() + 3 + (*z).ApplyData.EvalDelta.Msgsize()
+ s = 1 + 4 + (*z).SignedTxn.Sig.Msgsize() + 5 + (*z).SignedTxn.Msig.Msgsize() + 5 + (*z).SignedTxn.Lsig.Msgsize() + 4 + (*z).SignedTxn.Txn.Msgsize() + 5 + (*z).SignedTxn.AuthAddr.Msgsize() + 3 + (*z).ApplyData.ClosingAmount.Msgsize() + 4 + msgp.Uint64Size + 3 + (*z).ApplyData.SenderRewards.Msgsize() + 3 + (*z).ApplyData.ReceiverRewards.Msgsize() + 3 + (*z).ApplyData.CloseRewards.Msgsize() + 3 + (*z).ApplyData.EvalDelta.Msgsize()
return
}
// MsgIsZero returns whether this is a zero value
func (z *SignedTxnWithAD) MsgIsZero() bool {
- return ((*z).SignedTxn.Sig.MsgIsZero()) && ((*z).SignedTxn.Msig.MsgIsZero()) && ((*z).SignedTxn.Lsig.MsgIsZero()) && ((*z).SignedTxn.Txn.MsgIsZero()) && ((*z).SignedTxn.AuthAddr.MsgIsZero()) && ((*z).ApplyData.ClosingAmount.MsgIsZero()) && ((*z).ApplyData.SenderRewards.MsgIsZero()) && ((*z).ApplyData.ReceiverRewards.MsgIsZero()) && ((*z).ApplyData.CloseRewards.MsgIsZero()) && ((*z).ApplyData.EvalDelta.MsgIsZero())
+ return ((*z).SignedTxn.Sig.MsgIsZero()) && ((*z).SignedTxn.Msig.MsgIsZero()) && ((*z).SignedTxn.Lsig.MsgIsZero()) && ((*z).SignedTxn.Txn.MsgIsZero()) && ((*z).SignedTxn.AuthAddr.MsgIsZero()) && ((*z).ApplyData.ClosingAmount.MsgIsZero()) && ((*z).ApplyData.AssetClosingAmount == 0) && ((*z).ApplyData.SenderRewards.MsgIsZero()) && ((*z).ApplyData.ReceiverRewards.MsgIsZero()) && ((*z).ApplyData.CloseRewards.MsgIsZero()) && ((*z).ApplyData.EvalDelta.MsgIsZero())
}
// MarshalMsg implements msgp.Marshaler
diff --git a/data/transactions/transaction.go b/data/transactions/transaction.go
index 03270d7d68..4c30d1c3bc 100644
--- a/data/transactions/transaction.go
+++ b/data/transactions/transaction.go
@@ -104,6 +104,9 @@ type ApplyData struct {
// Closing amount for transaction.
ClosingAmount basics.MicroAlgos `codec:"ca"`
+ // Closing amount for asset transaction.
+ AssetClosingAmount uint64 `codec:"aca"`
+
// Rewards applied to the Sender, Receiver, and CloseRemainderTo accounts.
SenderRewards basics.MicroAlgos `codec:"rs"`
ReceiverRewards basics.MicroAlgos `codec:"rr"`
@@ -117,6 +120,9 @@ func (ad ApplyData) Equal(o ApplyData) bool {
if ad.ClosingAmount != o.ClosingAmount {
return false
}
+ if ad.AssetClosingAmount != o.AssetClosingAmount {
+ return false
+ }
if ad.SenderRewards != o.SenderRewards {
return false
}
diff --git a/ledger/apply/asset.go b/ledger/apply/asset.go
index fa31a9ec2a..7f745bda03 100644
--- a/ledger/apply/asset.go
+++ b/ledger/apply/asset.go
@@ -330,6 +330,13 @@ func AssetTransfer(ct transactions.AssetTransferTxnFields, header transactions.H
// and putIn will short circuit (so bypassFreeze doesn't matter)
_, bypassFreeze := dst.AssetParams[ct.XferAsset]
+ // AssetCloseAmount was a late addition, checking that the current protocol version supports it.
+ if balances.ConsensusParams().EnableAssetCloseAmount {
+ // Add the close amount to ApplyData.
+ closeAmount := sndHolding.Amount
+ ad.AssetClosingAmount = closeAmount
+ }
+
// Move the balance out.
err = takeOut(balances, source, ct.XferAsset, sndHolding.Amount, bypassFreeze)
if err != nil {
diff --git a/ledger/apply/asset_test.go b/ledger/apply/asset_test.go
new file mode 100644
index 0000000000..44b6ab665b
--- /dev/null
+++ b/ledger/apply/asset_test.go
@@ -0,0 +1,99 @@
+// Copyright (C) 2019-2021 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package apply
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/data/basics"
+ "github.com/algorand/go-algorand/data/transactions"
+ "github.com/algorand/go-algorand/protocol"
+)
+
+func TestAssetTransfer(t *testing.T) {
+ // Creator
+ secretSrc := keypair()
+ src := basics.Address(secretSrc.SignatureVerifier)
+
+ secretDst := keypair()
+ dst := basics.Address(secretDst.SignatureVerifier)
+
+ secretCls := keypair()
+ cls := basics.Address(secretCls.SignatureVerifier)
+
+ var total, toSend, dstAmount uint64
+ total = 1000000
+ dstAmount = 500
+ toSend = 200
+
+ // prepare data
+ var addrs = map[basics.Address]basics.AccountData{
+ src: {
+ MicroAlgos: basics.MicroAlgos{Raw: 10000000},
+ AssetParams: map[basics.AssetIndex]basics.AssetParams{
+ 1: {Total: total},
+ },
+ Assets: map[basics.AssetIndex]basics.AssetHolding{
+ 1: {Amount: total - dstAmount},
+ },
+ },
+ dst: {
+ MicroAlgos: basics.MicroAlgos{Raw: 10000000},
+ Assets: map[basics.AssetIndex]basics.AssetHolding{
+ 1: {Amount: dstAmount},
+ },
+ },
+ cls: {
+ MicroAlgos: basics.MicroAlgos{Raw: 10000000},
+ Assets: map[basics.AssetIndex]basics.AssetHolding{
+ 1: {Amount: 0},
+ },
+ },
+ }
+
+ mockBal := makeMockBalancesWithAccounts(protocol.ConsensusCurrentVersion, addrs)
+
+ tx := transactions.Transaction{
+ Type: protocol.AssetTransferTx,
+ Header: transactions.Header{
+ Sender: dst,
+ Fee: basics.MicroAlgos{Raw: 1},
+ FirstValid: basics.Round(100),
+ LastValid: basics.Round(1000),
+ },
+ AssetTransferTxnFields: transactions.AssetTransferTxnFields{
+ XferAsset: 1,
+ AssetAmount: toSend,
+ AssetReceiver: src,
+ AssetCloseTo: cls,
+ },
+ }
+
+ var ad transactions.ApplyData
+ err := AssetTransfer(tx.AssetTransferTxnFields, tx.Header, mockBal, transactions.SpecialAddresses{FeeSink: feeSink}, &ad)
+ require.NoError(t, err)
+
+ if config.Consensus[protocol.ConsensusCurrentVersion].EnableAssetCloseAmount {
+ require.Equal(t, uint64(0), addrs[dst].Assets[1].Amount)
+ require.Equal(t, dstAmount-toSend, ad.AssetClosingAmount)
+ require.Equal(t, total-dstAmount+toSend, addrs[src].Assets[1].Amount)
+ require.Equal(t, dstAmount-toSend, addrs[cls].Assets[1].Amount)
+ }
+}
diff --git a/ledger/apply/keyreg_test.go b/ledger/apply/keyreg_test.go
index dfd794f857..044d587a5f 100644
--- a/ledger/apply/keyreg_test.go
+++ b/ledger/apply/keyreg_test.go
@@ -95,11 +95,11 @@ func TestKeyregApply(t *testing.T) {
SelectionPK: vrfSecrets.PK,
},
}
- err := Keyreg(tx.KeyregTxnFields, tx.Header, mockBalances{protocol.ConsensusCurrentVersion}, transactions.SpecialAddresses{FeeSink: feeSink}, nil)
+ err := Keyreg(tx.KeyregTxnFields, tx.Header, makeMockBalances(protocol.ConsensusCurrentVersion), transactions.SpecialAddresses{FeeSink: feeSink}, nil)
require.NoError(t, err)
tx.Sender = feeSink
- err = Keyreg(tx.KeyregTxnFields, tx.Header, mockBalances{protocol.ConsensusCurrentVersion}, transactions.SpecialAddresses{FeeSink: feeSink}, nil)
+ err = Keyreg(tx.KeyregTxnFields, tx.Header, makeMockBalances(protocol.ConsensusCurrentVersion), transactions.SpecialAddresses{FeeSink: feeSink}, nil)
require.Error(t, err)
tx.Sender = src
diff --git a/ledger/apply/mockBalances.go b/ledger/apply/mockBalances.go
new file mode 100644
index 0000000000..89f5f68b8f
--- /dev/null
+++ b/ledger/apply/mockBalances.go
@@ -0,0 +1,84 @@
+// Copyright (C) 2019-2021 Algorand, Inc.
+// This file is part of go-algorand
+//
+// go-algorand is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// go-algorand is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with go-algorand. If not, see .
+
+package apply
+
+import (
+ "github.com/algorand/go-algorand/config"
+ "github.com/algorand/go-algorand/data/basics"
+ "github.com/algorand/go-algorand/data/transactions/logic"
+ "github.com/algorand/go-algorand/protocol"
+)
+
+type mockBalances struct {
+ protocol.ConsensusVersion
+ b map[basics.Address]basics.AccountData
+}
+
+func makeMockBalances(cv protocol.ConsensusVersion) *mockBalances {
+ return &mockBalances{
+ ConsensusVersion: cv,
+ b: map[basics.Address]basics.AccountData{},
+ }
+}
+
+func makeMockBalancesWithAccounts(cv protocol.ConsensusVersion, b map[basics.Address]basics.AccountData) *mockBalances {
+ return &mockBalances{
+ ConsensusVersion: cv,
+ b: b,
+ }
+}
+
+func (balances mockBalances) Round() basics.Round {
+ return basics.Round(8675309)
+}
+
+func (balances mockBalances) Allocate(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
+ return nil
+}
+
+func (balances mockBalances) Deallocate(basics.Address, basics.AppIndex, bool) error {
+ return nil
+}
+
+func (balances mockBalances) StatefulEval(logic.EvalParams, basics.AppIndex, []byte) (bool, basics.EvalDelta, error) {
+ return false, basics.EvalDelta{}, nil
+}
+
+func (balances mockBalances) PutWithCreatable(basics.Address, basics.AccountData, *basics.CreatableLocator, *basics.CreatableLocator) error {
+ return nil
+}
+
+func (balances mockBalances) Get(addr basics.Address, withPendingRewards bool) (basics.AccountData, error) {
+ return balances.b[addr], nil
+}
+
+func (balances mockBalances) GetCreator(idx basics.CreatableIndex, ctype basics.CreatableType) (basics.Address, bool, error) {
+ return basics.Address{}, true, nil
+}
+
+func (balances mockBalances) Put(addr basics.Address, ad basics.AccountData) error {
+ balances.b[addr] = ad
+ return nil
+}
+
+func (balances mockBalances) Move(src, dst basics.Address, amount basics.MicroAlgos, srcRewards, dstRewards *basics.MicroAlgos) error {
+ return nil
+}
+
+func (balances mockBalances) ConsensusParams() config.ConsensusParams {
+ return config.Consensus[balances.ConsensusVersion]
+}
diff --git a/ledger/apply/payment_test.go b/ledger/apply/payment_test.go
index 11371f3af0..c54dd8f334 100644
--- a/ledger/apply/payment_test.go
+++ b/ledger/apply/payment_test.go
@@ -26,7 +26,6 @@ import (
"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/data/transactions"
- "github.com/algorand/go-algorand/data/transactions/logic"
"github.com/algorand/go-algorand/protocol"
)
@@ -77,52 +76,8 @@ func TestAlgosEncoding(t *testing.T) {
}
}
-type mockBalances struct {
- protocol.ConsensusVersion
-}
-
-func (balances mockBalances) Round() basics.Round {
- return basics.Round(8675309)
-}
-
-func (balances mockBalances) Allocate(basics.Address, basics.AppIndex, bool, basics.StateSchema) error {
- return nil
-}
-
-func (balances mockBalances) Deallocate(basics.Address, basics.AppIndex, bool) error {
- return nil
-}
-
-func (balances mockBalances) StatefulEval(logic.EvalParams, basics.AppIndex, []byte) (bool, basics.EvalDelta, error) {
- return false, basics.EvalDelta{}, nil
-}
-
-func (balances mockBalances) PutWithCreatable(basics.Address, basics.AccountData, *basics.CreatableLocator, *basics.CreatableLocator) error {
- return nil
-}
-
-func (balances mockBalances) Get(basics.Address, bool) (basics.AccountData, error) {
- return basics.AccountData{}, nil
-}
-
-func (balances mockBalances) GetCreator(idx basics.CreatableIndex, ctype basics.CreatableType) (basics.Address, bool, error) {
- return basics.Address{}, true, nil
-}
-
-func (balances mockBalances) Put(basics.Address, basics.AccountData) error {
- return nil
-}
-
-func (balances mockBalances) Move(src, dst basics.Address, amount basics.MicroAlgos, srcRewards, dstRewards *basics.MicroAlgos) error {
- return nil
-}
-
-func (balances mockBalances) ConsensusParams() config.ConsensusParams {
- return config.Consensus[balances.ConsensusVersion]
-}
-
func TestPaymentApply(t *testing.T) {
- mockBalV0 := mockBalances{protocol.ConsensusCurrentVersion}
+ mockBalV0 := makeMockBalances(protocol.ConsensusCurrentVersion)
secretSrc := keypair()
src := basics.Address(secretSrc.SignatureVerifier)
@@ -149,8 +104,8 @@ func TestPaymentApply(t *testing.T) {
}
func TestCheckSpender(t *testing.T) {
- mockBalV0 := mockBalances{protocol.ConsensusCurrentVersion}
- mockBalV7 := mockBalances{protocol.ConsensusV7}
+ mockBalV0 := makeMockBalances(protocol.ConsensusCurrentVersion)
+ mockBalV7 := makeMockBalances(protocol.ConsensusV7)
secretSrc := keypair()
src := basics.Address(secretSrc.SignatureVerifier)