Idea for ManaMarket
Posted: 31 Mar 2013, 15:57
Original Thread: http://forums.themanaworld.org/viewtopi ... =4&t=16274
o11c mentioned something similar, so I guess my idea is not as original as I thought it was
The original idea was after a player used the !add command, ManaMarket would destroy the item, but keep the item in its database. When a player used !buy, the item would be created. It's a great idea and I think many players would enjoy having multiple slots or selling multiple non-stackable items.
The problem is that in the case of the server data being rolled back to a previous time, ManaMarket will have no idea the rollback occurred, and players could potentially lose a very large sum of GPs.
I have thought of a potential solution; after every !buy, !add, !getback, !money, etc. command, ManaMarket will create a log entry detailing the transaction (which I think it already does). In addition, ManaMarket will create an item in its inventory. This item will be stackable, have very low (zero?) weight, and will be used as a reference for the state of ManaMarket in the game.
For example, ManaMarket completes transaction number 12345. In its inventory, ManaMarket has a stack of 12345 of these items. The log has 12345 transactions recorded. The server crashes and a previous save file is loaded. ManaMarket logs back in to the server and finds that it has 12340 state items. It goes through the log, and reverses transactions 12341-12345. This would allow ManaMarket to never be out of sync with the server and to have unlimited items in its "inventory".
I would suggest this state item be something that cannot drop and is a GM only item with zero weight. This would allow ManaMarket to carry a nearly unlimited number of these items and it would also ensure that a player could not buy or sell and affect the state of ManaMarket by trading the state item. I'm not sure what the limit is on stack number, but I've had 10,000 arrows before at one time, so I would think the maximum stack would be something like 65,535 or 4,294,967,295; aligning with the size of the underlying integer. This would place a fixed limit on the number of transactions. At this time, either the numbering would start over again from zero, or a second stack would be created with one more item every time the first stack reaches the maximum number and the first stack would be zeroed. Even if 10,000 is the maximum stack size, 10,000^100 = 1x10^400 transactions; enough transactions to last well beyond the heat death of the universe.
Just for fun, if the stack size is a 32 bit unsigned int, there are 1.977x10^963 unique transaction IDs, which is probably enough.
Atomicity is the original concern. The only times I see this being an issue is if ManaMarket crashes before the log could be written, but after the trade has happened. This could be solved by dividing up the transaction into sub-transactions.
When ManaMarket receives a request to trade, it will have to create the item or GP necessary to complete the trade. This would have a log entry. Then, the trade is completed, which would also have a log entry. Then, ManaMarket would destroy the item or GP, which is logged as well. This makes 3 states possible for ManaMarket: pre-trade, post-trade, and idle (normal) state. ManaMarket would be able to see that it has items or GP in its inventory after a crash and it would see that the last transaction did not complete, and would have to handle it accordingly. So, I while I don't think we can guarantee atomicity, we could guarantee that ManaMarket could never be left in an inconsistent state as long as we can guarantee the log file won't be destroyed or modified outside of ManaMarket.
o11c mentioned something similar, so I guess my idea is not as original as I thought it was

The original idea was after a player used the !add command, ManaMarket would destroy the item, but keep the item in its database. When a player used !buy, the item would be created. It's a great idea and I think many players would enjoy having multiple slots or selling multiple non-stackable items.
The problem is that in the case of the server data being rolled back to a previous time, ManaMarket will have no idea the rollback occurred, and players could potentially lose a very large sum of GPs.
I have thought of a potential solution; after every !buy, !add, !getback, !money, etc. command, ManaMarket will create a log entry detailing the transaction (which I think it already does). In addition, ManaMarket will create an item in its inventory. This item will be stackable, have very low (zero?) weight, and will be used as a reference for the state of ManaMarket in the game.
For example, ManaMarket completes transaction number 12345. In its inventory, ManaMarket has a stack of 12345 of these items. The log has 12345 transactions recorded. The server crashes and a previous save file is loaded. ManaMarket logs back in to the server and finds that it has 12340 state items. It goes through the log, and reverses transactions 12341-12345. This would allow ManaMarket to never be out of sync with the server and to have unlimited items in its "inventory".
I would suggest this state item be something that cannot drop and is a GM only item with zero weight. This would allow ManaMarket to carry a nearly unlimited number of these items and it would also ensure that a player could not buy or sell and affect the state of ManaMarket by trading the state item. I'm not sure what the limit is on stack number, but I've had 10,000 arrows before at one time, so I would think the maximum stack would be something like 65,535 or 4,294,967,295; aligning with the size of the underlying integer. This would place a fixed limit on the number of transactions. At this time, either the numbering would start over again from zero, or a second stack would be created with one more item every time the first stack reaches the maximum number and the first stack would be zeroed. Even if 10,000 is the maximum stack size, 10,000^100 = 1x10^400 transactions; enough transactions to last well beyond the heat death of the universe.
Just for fun, if the stack size is a 32 bit unsigned int, there are 1.977x10^963 unique transaction IDs, which is probably enough.
Atomicity is the original concern. The only times I see this being an issue is if ManaMarket crashes before the log could be written, but after the trade has happened. This could be solved by dividing up the transaction into sub-transactions.
When ManaMarket receives a request to trade, it will have to create the item or GP necessary to complete the trade. This would have a log entry. Then, the trade is completed, which would also have a log entry. Then, ManaMarket would destroy the item or GP, which is logged as well. This makes 3 states possible for ManaMarket: pre-trade, post-trade, and idle (normal) state. ManaMarket would be able to see that it has items or GP in its inventory after a crash and it would see that the last transaction did not complete, and would have to handle it accordingly. So, I while I don't think we can guarantee atomicity, we could guarantee that ManaMarket could never be left in an inconsistent state as long as we can guarantee the log file won't be destroyed or modified outside of ManaMarket.