Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"inputs and outputs do not balance" - composer and validator inconsistency #133

Closed
pmiklos opened this issue Oct 6, 2018 · 2 comments
Closed

Comments

@pmiklos
Copy link
Contributor

pmiklos commented Oct 6, 2018

After posting the below multi-payment unit, I get the following validation error:

{"error":"inputs and outputs do not balance: 1000 !== 1000 + 681 + 508"}

It looks like the payment validation doesn't know which payment message was used to pay the fees. In this example, the fees are paid from the second message, still the validation assumes it was paid from the first payment message.

Expected behavior: the composer should add the fee paying message as first if the validation assumes that; or the validation should be intelligent enough to find out which message paid the fees.

I used the divisible_asset.composeAndSaveDivisibleAssetPaymentJoint function to generate this unit with an extra payment message which the composer placed in the first position.

A calculation that proves the fees are paid from the second payment:

sqlite> select sum(amount) from outputs where unit='u0EIU2LlYc87lYrM7KukLdq5/I6zMHPatpiU192m7Xk=' and is_spent=0 and asset is null;
sum(amount) = 4959

4959 - 681 - 508 = 3770

Unit that I tried to post on the testnet and resulted in the validation the error:

{ unit: 
   { version: '1.0t',
     alt: '2',
     messages: 
      [ { app: 'payment',
          payload_location: 'inline',
          payload_hash: 'c/AXJ51Jc0gAcW5PGPPDK4LUgmlOF6pC2Y1Vvp1VPwM=',
          payload: 
           { inputs: 
              [ { unit: 'wTsnuKp7J0GrC/2FcJTg17cZgYmOEIdJshX074tYFQ8=',
                  message_index: 0,
                  output_index: 1 } ],
             outputs: 
              [ { address: 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP', amount: 1000 } ] } },
        { app: 'payment',
          payload_location: 'inline',
          payload_hash: 'IPOL2dD2TyqJBu5xYRCX986Nzlk12lBcqIIJloMEPSU=',
          payload: 
           { outputs: 
              [ { address: 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP', amount: 3770 } ],
             inputs: 
              [ { unit: 'u0EIU2LlYc87lYrM7KukLdq5/I6zMHPatpiU192m7Xk=',
                  message_index: 0,
                  output_index: 1 } ] } },
        { app: 'payment',
          payload_location: 'inline',
          payload_hash: '1alxwnrl8UKWoJnH4qlWtPLLm9lngc8wHYEQ7TZxtmQ=',
          payload: 
           { asset: 'x+otCo902jUxw+coPegITxp+3B9ldj5+1h8/ojjTjLk=',
             inputs: 
              [ { type: 'issue',
                  amount: 1,
                  serial_number: 1,
                  address: 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP' } ],
             outputs: [ { address: '6YFMUDBYT7254E5HKAFT4VTXHV47PSCG', amount: 1 } ] } } ],
     authors: 
      [ { address: 'HLDTGMYTLIQHWRVXD3QLA7QAX4OQPORU',
          authentifiers: 
           { 'r.1.0': 'raXSNKWwxRzPnfRd+wnQM3L36VnwKDssMuZkx9AeI+lP2gzWzc3xcwhI8AcglS/gjsZp7yU8jnguaSDTIe7RtA==' },
          definition: 
           [ 'or',
             [ [ 'address', '6YFMUDBYT7254E5HKAFT4VTXHV47PSCG' ],
               [ 'and',
                 [ [ 'address', 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP' ],
                   [ 'has',
                     { what: 'output',
                       asset: 'x+otCo902jUxw+coPegITxp+3B9ldj5+1h8/ojjTjLk=',
                       amount_at_least: 1,
                       address: '6YFMUDBYT7254E5HKAFT4VTXHV47PSCG' } ] ] ] ] ] },
        { address: 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP',
          authentifiers: 
           { r: 'raXSNKWwxRzPnfRd+wnQM3L36VnwKDssMuZkx9AeI+lP2gzWzc3xcwhI8AcglS/gjsZp7yU8jnguaSDTIe7RtA==' } } ],
     earned_headers_commission_recipients: 
      [ { address: 'XDS4TZUHQUH5Q2N2OON27AC6CJHDG3RP',
          earned_headers_commission_share: 100 } ],
     parent_units: [ 'n0lDwsjGdmyHPOGKLaE02JYQ/1ltSQh45X46ev4WHxg=' ],
     last_ball: '7N+9RzKVq9YPVPB8duFKxMPrKhYP9GOA7PQuIyznnKA=',
     last_ball_unit: 'G1At3W8Coee+5dgqgK4BoCBHwwFWC2M47ouWv+mymdA=',
     witness_list_unit: 'TvqutGPz3T4Cs6oiChxFlclY92M2MvCvfXR5/FETato=',
     headers_commission: 681,
     payload_commission: 508,
     unit: '7xzYjADPxvRJBSkqNERzIQtYbGA79Ac0wNO6ZTdrzgM=' } }
@tonyofbyteball
Copy link
Member

The above unit breaks another rule: it has two messages with payments in bytes, which is not allowed.

		if (objValidationState.bHasBasePayment)
			return callback("can have only one base payment");
		objValidationState.bHasBasePayment = true;

The bytes payment doesn't have to be the first but it must be unique. The error message is misleading indeed since the first message is checked first but the unit is invalid anyway. You have to merge the two bytes payments in one message.

@pmiklos
Copy link
Contributor Author

pmiklos commented Oct 14, 2018

I see. I didn't know about that restriction. It's gonna be tricky to combine the base payments and issue an asset in one unit. My goal here is to sweep 1000 bytes from a smart contract and issue 1 asset in exchange all in as single unit, but it appears a difficult task to solve with the current API.

@pmiklos pmiklos closed this as completed Oct 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants