@@ -149,6 +149,135 @@ func TestNFTTransition(t *testing.T) {
149149 }, inputs ))
150150}
151151
152+ func TestChainConstrainedOutputUniqueness (t * testing.T ) {
153+ ident1 := tpkg .RandEd25519Address ()
154+
155+ inputIDs := tpkg .RandOutputIDs (1 )
156+
157+ aliasAddress := iotago .AliasAddressFromOutputID (inputIDs [0 ])
158+ aliasID := aliasAddress .AliasID ()
159+
160+ nftAddress := iotago .NFTAddressFromOutputID (inputIDs [0 ])
161+ nftID := nftAddress .NFTID ()
162+
163+ tests := []deSerializeTest {
164+ {
165+ // we transition the same Alias twice
166+ name : "transition the same Alias twice" ,
167+ source : tpkg .RandTransactionWithEssence (& iotago.TransactionEssence {
168+ NetworkID : tpkg .TestNetworkID ,
169+ Inputs : inputIDs .UTXOInputs (),
170+ Outputs : iotago.Outputs {
171+ & iotago.AliasOutput {
172+ Amount : OneMi ,
173+ AliasID : aliasID ,
174+ Conditions : iotago.UnlockConditions {
175+ & iotago.StateControllerAddressUnlockCondition {Address : ident1 },
176+ & iotago.GovernorAddressUnlockCondition {Address : ident1 },
177+ },
178+ Features : nil ,
179+ },
180+ & iotago.AliasOutput {
181+ Amount : OneMi ,
182+ AliasID : aliasID ,
183+ Conditions : iotago.UnlockConditions {
184+ & iotago.StateControllerAddressUnlockCondition {Address : ident1 },
185+ & iotago.GovernorAddressUnlockCondition {Address : ident1 },
186+ },
187+ Features : nil ,
188+ },
189+ },
190+ }),
191+ target : & iotago.Transaction {},
192+ seriErr : iotago .ErrNonUniqueChainConstrainedOutputs ,
193+ deSeriErr : nil ,
194+ },
195+ {
196+ // we transition the same NFT twice
197+ name : "transition the same NFT twice" ,
198+ source : tpkg .RandTransactionWithEssence (& iotago.TransactionEssence {
199+ NetworkID : tpkg .TestNetworkID ,
200+ Inputs : inputIDs .UTXOInputs (),
201+ Outputs : iotago.Outputs {
202+ & iotago.NFTOutput {
203+ Amount : OneMi ,
204+ NFTID : nftID ,
205+ Conditions : iotago.UnlockConditions {
206+ & iotago.AddressUnlockCondition {Address : ident1 },
207+ },
208+ Features : nil ,
209+ },
210+ & iotago.NFTOutput {
211+ Amount : OneMi ,
212+ NFTID : nftID ,
213+ Conditions : iotago.UnlockConditions {
214+ & iotago.AddressUnlockCondition {Address : ident1 },
215+ },
216+ Features : nil ,
217+ },
218+ },
219+ }),
220+ target : & iotago.Transaction {},
221+ seriErr : iotago .ErrNonUniqueChainConstrainedOutputs ,
222+ deSeriErr : nil ,
223+ },
224+ {
225+ // we transition the same Foundry twice
226+ name : "transition the same Foundry twice" ,
227+ source : tpkg .RandTransactionWithEssence (& iotago.TransactionEssence {
228+ NetworkID : tpkg .TestNetworkID ,
229+ Inputs : inputIDs .UTXOInputs (),
230+ Outputs : iotago.Outputs {
231+ & iotago.AliasOutput {
232+ Amount : OneMi ,
233+ AliasID : aliasID ,
234+ Conditions : iotago.UnlockConditions {
235+ & iotago.StateControllerAddressUnlockCondition {Address : ident1 },
236+ & iotago.GovernorAddressUnlockCondition {Address : ident1 },
237+ },
238+ Features : nil ,
239+ },
240+ & iotago.FoundryOutput {
241+ Amount : OneMi ,
242+ NativeTokens : nil ,
243+ SerialNumber : 1 ,
244+ TokenScheme : & iotago.SimpleTokenScheme {
245+ MintedTokens : big .NewInt (50 ),
246+ MeltedTokens : big .NewInt (0 ),
247+ MaximumSupply : big .NewInt (50 ),
248+ },
249+ Conditions : iotago.UnlockConditions {
250+ & iotago.ImmutableAliasUnlockCondition {Address : & aliasAddress },
251+ },
252+ Features : nil ,
253+ },
254+ & iotago.FoundryOutput {
255+ Amount : OneMi ,
256+ NativeTokens : nil ,
257+ SerialNumber : 1 ,
258+ TokenScheme : & iotago.SimpleTokenScheme {
259+ MintedTokens : big .NewInt (50 ),
260+ MeltedTokens : big .NewInt (0 ),
261+ MaximumSupply : big .NewInt (50 ),
262+ },
263+ Conditions : iotago.UnlockConditions {
264+ & iotago.ImmutableAliasUnlockCondition {Address : & aliasAddress },
265+ },
266+ Features : nil ,
267+ },
268+ },
269+ }),
270+ target : & iotago.Transaction {},
271+ seriErr : iotago .ErrNonUniqueChainConstrainedOutputs ,
272+ deSeriErr : nil ,
273+ },
274+ }
275+
276+ for _ , tt := range tests {
277+ t .Run (tt .name , tt .deSerialize )
278+ }
279+ }
280+
152281func TestCirculatingSupplyMelting (t * testing.T ) {
153282 _ , ident1 , ident1AddrKeys := tpkg .RandEd25519Identity ()
154283 aliasIdent1 := tpkg .RandAliasAddress ()
0 commit comments