Open caivega opened 3 years ago
目前版本v0.5.3-dev-20201216-9f304bafe8618c2609901034a670797ad8962723中,发送交易的复合错误是这样的格式:
{
"error": "1 errors",
"id": 6,
"jsonrpc": "2.0",
"result": [
"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
{
"error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
"message": {
"engine_result": "tefALREADY",
"engine_result_code": -198,
"engine_result_message": "The exact transaction was already in this ledger.",
"tx_blob": "1200...",
"tx_json": {
}
},
"status": -278,
"type": "temINVALID"
}
],
"status": -278,
"type": "temINVALID"
}
其实有3组错误信息:
"status": -278,
"type": "temINVALID"
"status": -278,
"type": "temINVALID"
和message里面的:
"engine_result": "tefALREADY",
"engine_result_code": -198,
"engine_result_message": "The exact transaction was already in this ledger.",
这是因为jt_sendTransaction方法其实做了2个动作,先signTx,然后发送交易到区块链网络。因为sign的时候没有问题,但在发送时发现这个sequence已经被使用,因此发出了2个错误。
另外,如果jt_sendTransaction的两个交易,如果第二个交易在sign的时候就出错(比如secret错误),这种情况下,第一个交易返回的不是交易hash,而是签名后的signedTx内容,如下:
{
"error": "1 errors",
"id": 6,
"jsonrpc": "2.0",
"result": [
"1200002280000000240000000661400000000000000f68400000000000000a7321038d7e30fb992b9bee527295edb946fe9f8a7351a68ad6190a781dd8643872b7ea744630440220281c0f4fc6a1aaacb1fb33f262f5d18cb7eda790dcd4feeea551842d3b0b4e1c02205233c6d5baceecb2f1d0105070d50a1ed5b337c5e8176fe741769825f238e42d811426ee193806b471f9bc44e10811d89cb39aa8f7b783143516971a9e811a3397a1c44b6423d22ce1e773ebf9ea7d146175746f746573743a20746f6b656e2074657374e1f1",
{
"error": "Bad Base58 checksum: spxbRB1eW1vAJQo1z7mn3fXpzqa9X1 [9 127 225 126 188 165 3 58 60 187 255 8 134 111 101 199 171 93 116 217 177 12 201 231 168 71 188 20 164 108 177 72] expected [212 85 51 198]",
"message": {
"fee": "10",
"from": "jhYquCX969ir4ks7uoAnEU2UmaycYmZrpu",
"memos": [
"autotest: token test"
],
"sequence": 1,
"to": "jnq61m48pJHvBrDSqt7hzC14ATfYixh99b",
"value": "1"
},
"status": -278,
"type": "temINVALID"
}
],
"status": -278,
"type": "temINVALID"
}
合理的情况是接口调用中的每个交易,如果出错,应该只有一个错误信息。在上例中,result数组中第二个交易中只保留message里面的engine错误(这是真正的错误)即可。 另外sign成功的交易,无论一起发送的其他交易是否sign能成功,最后应该要发送出去并给出结果,而不是给签名后的signedTx。
东东和我觉得,把jt_sendTransaction改成每次只能发送一个交易可以避免这样的问题。大家讨论哈。
这段时间试用了一下新的错误信息,感觉新的格式还是比较合理的,也有了一些新的想法,和东东讨论完善后,在这里提出:
交易类接口目前的返回信息格式:
{
"error": "1 errors",
"id": 6,
"jsonrpc": "2.0",
"result": [
"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
{
"error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93",
"message": {
"engine_result": "tefALREADY",
"engine_result_code": -198,
"engine_result_message": "The exact transaction was already in this ledger.",
"tx_blob": "1200...",
"tx_json": {
}
},
"status": -278,
"type": "temINVALID"
}
],
"status": -278,
"type": "temINVALID"
}
建议变成:
{
"id": 6,
"jsonrpc": "2.0",
"results": [
{
"tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
},
{
"message": {
"tx_blob": "1200...",
"tx_json": {}
},
"type": "tefALREADY",
"status": -198,
"error": "The exact transaction was already in this ledger."
}
],
"error_count": 1
}
主要有这样几个变化: 1.最外层一定存在4个属性:id,jsonrpc,results(从result改名过来)和error_count(从error改名过来)。 2.results一定是数组,无论是一次发送一个交易,还是一次发送多个交易,最后所有的结果(包括错误信息)都作为一个result放在results里面。 3.error_count的作用是显示这次调用的交易一共有几个出错,这样app开发就不需要遍历results,马上能知道是否发生过错误(error_count是否为0),有几个错误。 4.如果交易出现错误,一个交易最多只有一个错误信息,因此每个错误只要放在对应的result中即可。目前的返回结果中,最多可以有3组错误信息,其实没有必要。 5.在result中,如果这个result是一个错误,应该有4个属性:type,status,error,message。 6.错误信息应该放在result中,而不是放在message中。原先message中的engine_result移动到result中变成result.type,相应地,engine_result_code对应result.status,engine_result_message对应result.error。 7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。
"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
===>
{
"tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
}
查询类接口目前的返回信息格式:
查询成功:
{
"id": 1,
"jsonrpc": "2.0",
"result": {
"balance": {
"value": "100000000",
"currency": "SWT",
"issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
}
}
}
查询失败:
{
"error": "address is not string",
"id": 1,
"jsonrpc": "2.0",
"result": "",
"status": -269,
"type": "temBAD_PARAMETER"
}
建议变成:
查询成功:
{
"id": 1,
"jsonrpc": "2.0",
"results": [
{
"balance": {
"value": "100000000",
"currency": "SWT",
"issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
}
}
],
"error_count": 0
}
查询失败:
{
"id": 6,
"jsonrpc": "2.0",
"results": [
{
"type": "temBAD_PARAMETER",
"status": -269,
"error": "address is not string"
}
],
"error_count": 1
}
主要的变化就是改成和交易类接口的返回格式一致,最外层一定存在4个属性:id,jsonrpc,results和error_count。 这样的改动有2个主要的考虑因素: 1.虽然目前查询基本都是单个查询,没有一次返回多个查询结果的情况,但还是建议把查询结果的格式改得和和交易类接口的返回格式一致。这样对app开发来说只需要写一套代码就能对应所有接口的结果。 2.如果以后有客户需求,需要增加批处理查询功能,那目前的这套结果格式已经能满足要求,无需大改。
7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。
目前的格式:
{
"id": 1,
"jsonrpc": "2.0",
"result": "v0.5.3-dev-20201216-be83b3f3cf9773881eb5fcf277e9b9afe8caaa8c"
}
建议改成:
{
"id": 1,
"jsonrpc": "2.0",
"results": [
{
"version": "v0.5.3-dev-20201216-be83b3f3cf9773881eb5fcf277e9b9afe8caaa8c"
}
],
"error_count": 0
}
目前版本v0.5.3-dev-20201216-9f304bafe8618c2609901034a670797ad8962723中,发送交易的复合错误是这样的格式:
{ "error": "1 errors", "id": 6, "jsonrpc": "2.0", "result": [ "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0", { "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93", "message": { "engine_result": "tefALREADY", "engine_result_code": -198, "engine_result_message": "The exact transaction was already in this ledger.", "tx_blob": "1200...", "tx_json": { } }, "status": -278, "type": "temINVALID" } ], "status": -278, "type": "temINVALID" }
其实有3组错误信息:
- 最外面的:
"status": -278, "type": "temINVALID"
- result数组中第二个交易包含了2组错误信息:
"status": -278, "type": "temINVALID"
和message里面的:
"engine_result": "tefALREADY", "engine_result_code": -198, "engine_result_message": "The exact transaction was already in this ledger.",
这是因为jt_sendTransaction方法其实做了2个动作,先signTx,然后发送交易到区块链网络。因为sign的时候没有问题,但在发送时发现这个sequence已经被使用,因此发出了2个错误。
另外,如果jt_sendTransaction的两个交易,如果第二个交易在sign的时候就出错(比如secret错误),这种情况下,第一个交易返回的不是交易hash,而是签名后的signedTx内容,如下:
{ "error": "1 errors", "id": 6, "jsonrpc": "2.0", "result": [ "1200002280000000240000000661400000000000000f68400000000000000a7321038d7e30fb992b9bee527295edb946fe9f8a7351a68ad6190a781dd8643872b7ea744630440220281c0f4fc6a1aaacb1fb33f262f5d18cb7eda790dcd4feeea551842d3b0b4e1c02205233c6d5baceecb2f1d0105070d50a1ed5b337c5e8176fe741769825f238e42d811426ee193806b471f9bc44e10811d89cb39aa8f7b783143516971a9e811a3397a1c44b6423d22ce1e773ebf9ea7d146175746f746573743a20746f6b656e2074657374e1f1", { "error": "Bad Base58 checksum: spxbRB1eW1vAJQo1z7mn3fXpzqa9X1 [9 127 225 126 188 165 3 58 60 187 255 8 134 111 101 199 171 93 116 217 177 12 201 231 168 71 188 20 164 108 177 72] expected [212 85 51 198]", "message": { "fee": "10", "from": "jhYquCX969ir4ks7uoAnEU2UmaycYmZrpu", "memos": [ "autotest: token test" ], "sequence": 1, "to": "jnq61m48pJHvBrDSqt7hzC14ATfYixh99b", "value": "1" }, "status": -278, "type": "temINVALID" } ], "status": -278, "type": "temINVALID" }
合理的情况是接口调用中的每个交易,如果出错,应该只有一个错误信息。在上例中,result数组中第二个交易中只保留message里面的engine错误(这是真正的错误)即可。 另外sign成功的交易,无论一起发送的其他交易是否sign能成功,最后应该要发送出去并给出结果,而不是给签名后的signedTx。
东东和我觉得,把jt_sendTransaction改成每次只能发送一个交易可以避免这样的问题。大家讨论哈。
里边第三层错误,实际上是以前老版本的交易错误返回格式,这两天更新的版本,已经把这个去掉了,只有我们现在试用的错误格式样子,交易相关的rpc是链主要的功能接口,增加一次提交多条,主要是为了提交处理效率考虑。。。现在有四个接口支持一次提交多条的,即jt_sign, jt_signTransaction, jt_sendRawTransaction, jt_sendTransaction, 除去jt_sign很少用,剩下三个,jt_sendTransaction = jt_signTransaction + jt_sendRawTransaction, jt_signTransaction及jt_sendRawTransaction已经支持一次提交多条,如果jt_sendTransaction不支持一次提交多条的话,一个不统一,虽然实际使用中节点的jt_sendTransaction, 包括jt_signTransaction都很少用,另外一个就是实际上也增加了后台实现的复杂度
这段时间试用了一下新的错误信息,感觉新的格式还是比较合理的,也有了一些新的想法,和东东讨论完善后,在这里提出:
交易类接口目前的返回信息格式:
{ "error": "1 errors", "id": 6, "jsonrpc": "2.0", "result": [ "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0", { "error": "failed to submit transaction AF823314CF7F58FDFA3635C3473053814C0FE0DD2DC2554802811E8CC46BEA93", "message": { "engine_result": "tefALREADY", "engine_result_code": -198, "engine_result_message": "The exact transaction was already in this ledger.", "tx_blob": "1200...", "tx_json": { } }, "status": -278, "type": "temINVALID" } ], "status": -278, "type": "temINVALID" }
建议变成:
{ "id": 6, "jsonrpc": "2.0", "results": [ { "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0" }, { "message": { "tx_blob": "1200...", "tx_json": {} }, "type": "tefALREADY", "status": -198, "error": "The exact transaction was already in this ledger." } ], "error_count": 1 }
主要有这样几个变化: 1.最外层一定存在4个属性:id,jsonrpc,results(从result改名过来)和error_count(从error改名过来)。 2.results一定是数组,无论是一次发送一个交易,还是一次发送多个交易,最后所有的结果(包括错误信息)都作为一个result放在results里面。 3.error_count的作用是显示这次调用的交易一共有几个出错,这样app开发就不需要遍历results,马上能知道是否发生过错误(error_count是否为0),有几个错误。 4.如果交易出现错误,一个交易最多只有一个错误信息,因此每个错误只要放在对应的result中即可。目前的返回结果中,最多可以有3组错误信息,其实没有必要。 5.在result中,如果这个result是一个错误,应该有4个属性:type,status,error,message。 6.错误信息应该放在result中,而不是放在message中。原先message中的engine_result移动到result中变成result.type,相应地,engine_result_code对应result.status,engine_result_message对应result.error。 7.如果交易成功,返回的是交易的hash,目前把这个hash的字符串直接放在results里面。建议也改成json格式,这样,一是results里面的result,无论成功还是错误,都是json格式,统一;二是可以增强整个返回结果的可读性。
"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0",
===>
{ "tx_hash":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0" }
这个问题,之前讨论的时候就提到,就是正确结果与错误结果在一起的时候,如果分辨问题,我现在只能通过反射判断item类型来分辨了,这个实际上还是不方便
根据引用的提到的,与其用tx_json, 不如与外边格式一致
正确的结果,
{
“result”: "771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
}
错误的结果是:
{
"message": {
"tx_blob": "1200...",
"tx_json": {}
},
"type": "tefALREADY",
"status": -198,
"error": "The exact transaction was already in this ledger."
}
这样的好处是,与外边的格式统一,判断方式与使用方式也统一,唯一不好的,就是正确结果,取的时候比以前麻烦些,以前直接是一个string类型,现在是一个object类型
查询类接口目前的返回信息格式:
查询成功: { "id": 1, "jsonrpc": "2.0", "result": { "balance": { "value": "100000000", "currency": "SWT", "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp" } } } 查询失败: { "error": "address is not string", "id": 1, "jsonrpc": "2.0", "result": "", "status": -269, "type": "temBAD_PARAMETER" }
建议变成:
查询成功: { "id": 1, "jsonrpc": "2.0", "results": [ { "balance": { "value": "100000000", "currency": "SWT", "issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp" } } ], "error_count": 0 } 查询失败: { "id": 6, "jsonrpc": "2.0", "results": [ { "type": "temBAD_PARAMETER", "status": -269, "error": "address is not string" } ], "error_count": 1 }
主要的变化就是改成和交易类接口的返回格式一致,最外层一定存在4个属性:id,jsonrpc,results和error_count。 这样的改动有2个主要的考虑因素: 1.虽然目前查询基本都是单个查询,没有一次返回多个查询结果的情况,但还是建议把查询结果的格式改得和和交易类接口的返回格式一致。这样对app开发来说只需要写一套代码就能对应所有接口的结果。 2.如果以后有客户需求,需要增加批处理查询功能,那目前的这套结果格式已经能满足要求,无需大改。
现在通过status或者type是可以判断出是否出错,以及出了啥错,这个现在是没问题了,你这个里边提到了一个很重要的问题,就是与错误相关的一些参数信息,除了你说的error_count这个错误参数没地方放,实际上还有一类信息,就是错误关联的对象,比如同样是BAD_PARAMETER, 可能是 请求参数中“from”出的错,也可能是请求参数"to"出的错,如果BAD_PARAMETER,from有一个,比如叫BAD_FROM_PARAMETER, to有一个,比如叫BAD_TO_PARAMETER, 这样的话,错误列表会很膨胀,没有很好的结构化,最后太多以致于没有办法维护,不行我们可以把message的具体格式再考虑考虑??
结论是,现在的错误格式,没有考虑,错误参数及错误关联对象返回的地方
另外后续加批量调用的功能,这个因为这套rpc参考以太的,以太现在已经支持了,只需要把现在每个rpc的参数,再放到一个数组中即可,这个是可嵌套的
最后大家确定的格式如下:
{
"id": 1,
"jsonrpc": "2.0",
"error":{
"description":"compound errors",
"count":1
},
"result": [
{
"result":"771AE3F8BE4B4727DB0EB594B3E1F04F4CEA8B99F8FAA1468BE68765282040E0"
},
{
"error": {
"description":"invalid transaction flags",
"information":"from is invalid",
"message": {
"decimals": "8",
"flags": 1,
"from": "jsTL48gDwm5DwBvWRXSCpB6CtwJzAnQC1f",
"local": false,
"name": "TestCoin_StrangeName",
"symbol": "15fd23aef27",
"total_supply": "10000",
"type": "IssueCoin"
}
},
"status": -278,
"type": "temINVALID"
}
],
"status": 1000,
"type": "tecCOMPOUND"
}
注意:
关于查询接口,大家同意也要支持批处理查询,但12月的提交版不考虑这个功能,因为变化会比较大,会在后面的版本支持。 好处:
查询接口修改后的返回结果:
查询成功:
{
"id": 1,
"jsonrpc": "2.0",
"result": [
{
"value": "100000000",
"currency": "SWT",
"issuer": "jjjjjjjjjjjjjjjjjjjjjhoLvTp"
}
]
}
查询失败:
{
"id": 6,
"jsonrpc": "2.0",
"result": [
{
"type": "temBAD_PARAMETER",
"status": -269,
"error": "address is not string"
}
]
}
具体细节后面还需要继续讨论。
最新的返回格式里边,这两个词用了缩写
"description" => "desc" "information" => "info"
错误信息文档描述
注:三部分用不同的方式,兼顾显示效果及程序读取(程序要读取该文档生成相应的源代码,这个格式暂定如此,之前还考虑过JSON,后来想想,JSON格式程序读取是方便了,但是人工维护起来感觉不是很方便
错误信息文档链接
错误信息文档
返回错误信息格式
另外:关于该文档本身及错误信息整理相关的可以在这个issue讨论,关于文档里边不同错误信息内容建议单开单独的issue讨论,更新文档直接在上边链接更新
TODO:
相关资源:
json
及golang