Agoric / agoric-sdk

monorepo for the Agoric Javascript smart contract platform
Apache License 2.0
327 stars 206 forks source link

odd {x, y, z} >= {y} failure in AmountMath.isGTE with AssetKind.SET #10292

Open dckc opened 2 days ago

dckc commented 2 days ago

Describe the bug

AmountMath.isGTE with AssetKind.SET fails in a case involving invitations with common descriptions but distinct instance handles.

To Reproduce

Add this to packages/ERTP/test/unitTests/mathHelpers/copySetMathHelpers.test.js and run it:

test('balance {x, y, z} >= {y}', t => {
  const x = { instance: mockHandle('Foo'), description: 'fraz' };
  const y = { instance: mockHandle('Foo'), description: 'fraz' };
  const z = { instance: mockHandle('Foo'), description: 'alan' };

  const balance = harden({ brand: mockBrand, value: makeCopySet([x, y, z]) });
  const withdraw = harden({ brand: mockBrand, value: makeCopySet([y]) });

  t.true(m.isGTE(balance, withdraw));
});

Expected behavior

test above passes

Platform Environment

375dc25

Additional context

@frazarshad discovered this while working on

He made a test PR, #10281

a ci log of that a3p test shows the original context where the problem was found

more diagnosis an an endo issue to follow

Screenshots / Logs

since ci logs expire:

2024-10-16T13:03:13.026Z SwingSet: ls: v9: Error#1: Withdrawal of { brand: Object [Alleged: Zoe Invitation brand] {}, value: [ { description: 'charter member invitation', handle: Object [Alleged: InvitationHandle] {}, installation: Object [Alleged: BundleIDInstallation] {}, instance: Object [Alleged: InstanceHandle] {} } ] } failed because the purse only contained { brand: Object [Alleged: Zoe Invitation brand] {}, value: [ { description: 'charter member invitation', handle: Object [Alleged: InvitationHandle] {}, installation: Object [Alleged: BundleIDInstallation] {}, instance: Object [Alleged: InstanceHandle] {} }, { description: 'oracle invitation', handle: Object [Alleged: InvitationHandle] {}, installation: Object [Alleged: BundleIDInstallation] {}, instance: Object [Alleged: InstanceHandle] {} }, { description: 'oracle invitation', handle: Object [Alleged: InvitationHandle] {}, installation: Object [Alleged: BundleIDInstallation] {}, instance: Object [Alleged: InstanceHandle] {} }, { description: 'Voter0', handle: Object [Alleged: InvitationHandle] {}, installation: Object [Alleged: BundleIDInstallation] {}, instance: Object [Alleged: InstanceHandle] {} } ] }
dckc commented 2 days ago

The original failure was observed in a withdraw:

https://github.com/Agoric/agoric-sdk/blob/94aaebcd255840daf13514ab1050282b985684d2/packages/smart-wallet/src/invitations.js#L140

We can see that the amount withdrawn is derived from the balance by filtering:

https://github.com/Agoric/agoric-sdk/blob/94aaebcd255840daf13514ab1050282b985684d2/packages/smart-wallet/src/invitations.js#L112-L140

interleaving is theoretically possible, but that would have shown in logs, and it doesn't.