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

fuel and smart gate bug fixes #364

Merged
merged 8 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ contract SmartDeployableSystem is AccessModified, EveSystem, SmartDeployableErro
}
_updateFuel(entityId);
uint256 currentFuel = DeployableFuelBalance.getFuelAmount(entityId);
if (currentFuel < 1) revert SmartDeployable_NoFuel(entityId);
if (currentFuel < ONE_UNIT_IN_WEI) revert SmartDeployable_NoFuel(entityId);
DeployableFuelBalance.setFuelAmount(entityId, currentFuel - ONE_UNIT_IN_WEI); //forces it to tick
_setDeployableState(entityId, previousState, State.ONLINE);
DeployableFuelBalance.setLastUpdatedAt(entityId, block.timestamp);
vayan marked this conversation as resolved.
Show resolved Hide resolved
_updateFuel(entityId);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ contract SmartGateSystem is EveSystem, AccessModified {
_;
}

modifier onlyOnline(uint256 smartObjectId) {
if (DeployableState.getCurrentState(smartObjectId) != State.ONLINE) {
revert SmartDeployableErrors.SmartDeployable_IncorrectState(
smartObjectId,
DeployableState.getCurrentState(smartObjectId)
);
}
_;
}

/**
* @notice Create and anchor a Smart Gate
* @param smartObjectId is smart object id of the Smart Gate
Expand Down Expand Up @@ -120,7 +130,17 @@ contract SmartGateSystem is EveSystem, AccessModified {
* @param sourceGateId is the smartObjectId of the source gate
* @param destinationGateId is the smartObjectId of the destination gate
*/
function linkSmartGates(uint256 sourceGateId, uint256 destinationGateId) public onlyAdminOrObjectOwner(sourceGateId) {
function linkSmartGates(
uint256 sourceGateId,
uint256 destinationGateId
)
public
onlyAdminOrObjectOwner(sourceGateId)
onlyAdminOrObjectOwner(destinationGateId)
onlyOnline(sourceGateId)
onlyOnline(destinationGateId)
onlyActive
{
if (isAnyGateLinked(sourceGateId, destinationGateId)) {
revert SmartGate_GateAlreadyLinked(sourceGateId, destinationGateId);
}
Expand All @@ -134,6 +154,11 @@ contract SmartGateSystem is EveSystem, AccessModified {
revert SmartGate_NotWithtinRange(sourceGateId, destinationGateId);
}

//Delete the existing records for the source and destination gate before creating a new link to avoid replacing the record
//The invalid records are not deleted during unlink because the external services are subscribed to the unlink events. If the record is deleted then the external services will not be able to notify the game
_deleteExistingLink(sourceGateId);
_deleteExistingLink(destinationGateId);
tinkrtailor marked this conversation as resolved.
Show resolved Hide resolved

//Create a 2 way link between the gates
SmartGateLinkTable.set(sourceGateId, destinationGateId, true);
SmartGateLinkTable.set(destinationGateId, sourceGateId, true);
Expand All @@ -147,7 +172,7 @@ contract SmartGateSystem is EveSystem, AccessModified {
function unlinkSmartGates(
uint256 sourceGateId,
uint256 destinationGateId
) public onlyAdminOrObjectOwner(sourceGateId) {
) public onlyAdminOrObjectOwner(sourceGateId) onlyAdminOrObjectOwner(destinationGateId) {
//Check if the gates are linked
if (!isGateLinked(sourceGateId, destinationGateId)) {
revert SmartGate_GateNotLinked(sourceGateId, destinationGateId);
Expand Down Expand Up @@ -262,6 +287,22 @@ contract SmartGateSystem is EveSystem, AccessModified {
return distanceSquaredMeters <= (maxDistance * maxDistance);
}

/**
* @notice delete the existing record if there exists a link for either source or destination gates
* @param sourceGateId is the smartObjectId of the source gate
*/
function _deleteExistingLink(uint256 sourceGateId) internal {
tinkrtailor marked this conversation as resolved.
Show resolved Hide resolved
uint256 destinationGateId;
//delete the source gate record
SmartGateLinkTableData memory linkData = SmartGateLinkTable.get(sourceGateId);
if (!linkData.isLinked) {
destinationGateId = SmartGateLinkTable.get(sourceGateId).destinationGateId;

SmartGateLinkTable.deleteRecord(sourceGateId);
SmartGateLinkTable.deleteRecord(destinationGateId);
}
}

function _entityRecordLib() internal view returns (EntityRecordLib.World memory) {
return EntityRecordLib.World({ iface: IBaseWorld(_world()), namespace: ENTITY_RECORD_DEPLOYMENT_NAMESPACE });
}
Expand Down
5 changes: 5 additions & 0 deletions mud-contracts/world/test/access/Access.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,11 @@ contract AccessTest is MudTest {

vm.startPrank(alice, bob);
// OWNER success
smartDeployable.depositFuel(56789, 100000);
smartDeployable.depositFuel(156789, 100000);
smartDeployable.bringOnline(56789);
smartDeployable.bringOnline(156789);

smartGate.configureSmartGate(56789, ResourceId.wrap(bytes32(uint256(123455667))));
smartGate.linkSmartGates(56789, 156789);
smartGate.unlinkSmartGates(56789, 156789);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,35 @@ contract smartDeployableTest is MudTest {
uint256 fuelMaxCapacity,
LocationTableData memory location
) public {
uint256 fuelAmount = 2;
vm.assume(entityId != 0);
testAnchor(entityId, fuelUnitVolume, fuelConsumptionPerMinute, fuelMaxCapacity, location);
vm.assume(fuelUnitVolume < type(uint64).max / 2);
vm.assume(fuelUnitVolume < fuelMaxCapacity);
smartDeployable.depositFuel(entityId, 1);
vm.assume(fuelMaxCapacity > fuelAmount * fuelUnitVolume);
smartDeployable.depositFuel(entityId, fuelAmount);
smartDeployable.bringOnline(entityId);
assertEq(uint8(State.ONLINE), uint8(DeployableState.getCurrentState(entityId)));
}

function testBringOnlineWith1Fuel(
uint256 entityId,
uint256 fuelUnitVolume,
uint256 fuelConsumptionPerMinute,
uint256 fuelMaxCapacity,
LocationTableData memory location
) public {
uint256 fuelAmount = 1;
vm.assume(entityId != 0);
testAnchor(entityId, fuelUnitVolume, fuelConsumptionPerMinute, fuelMaxCapacity, location);
vm.assume(fuelUnitVolume < type(uint64).max / 2);
vm.assume(fuelUnitVolume < fuelMaxCapacity);
vm.assume(fuelMaxCapacity > fuelAmount * fuelUnitVolume);
smartDeployable.depositFuel(entityId, fuelAmount);
smartDeployable.bringOnline(entityId);
assertEq(uint8(State.ANCHORED), uint8(DeployableState.getCurrentState(entityId)));
}

function testBringOffline(
uint256 entityId,
uint256 fuelUnitVolume,
Expand Down
80 changes: 62 additions & 18 deletions mud-contracts/world/test/smart-gate/SmartGateTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ import { Utils as SmartCharacterUtils } from "../../src/modules/smart-character/
import { SmartCharacterLib } from "../../src/modules/smart-character/SmartCharacterLib.sol";
import { EntityRecordData as EntityRecordCharacter } from "../../src/modules/smart-character/types.sol";
import { Utils as SmartDeployableUtils } from "../../src/modules/smart-deployable/Utils.sol";
import { IAccessSystemErrors } from "../../src/modules/access/interfaces/IAccessSystemErrors.sol";

import { SmartGateConfigTable } from "../../src/codegen/tables/SmartGateConfigTable.sol";
import { EntityRecordOffchainTableData } from "../../src/codegen/tables/EntityRecordOffchainTable.sol";
import { SmartAssemblyTable } from "../../src/codegen/tables/SmartAssemblyTable.sol";
import { DeployableState } from "../../src/codegen/tables/DeployableState.sol";
import { DeployableState, DeployableStateData } from "../../src/codegen/tables/DeployableState.sol";
import { SmartGateLinkTable, SmartGateLinkTableData } from "../../src/codegen/tables/SmartGateLinkTable.sol";

import { IERC721 } from "../../src/modules/eve-erc721-puppet/IERC721.sol";
Expand Down Expand Up @@ -161,7 +162,7 @@ contract SmartGateTest is MudTest {
100000000 * 1e18 // maxDistance
);

smartDeployable.depositFuel(smartObjectId, 1);
smartDeployable.depositFuel(smartObjectId, 100000);
smartDeployable.bringOnline(smartObjectId);

assertEq(uint256(SmartAssemblyTable.get(smartObjectId)), uint256(SmartAssemblyType.SMART_GATE));
Expand All @@ -172,18 +173,18 @@ contract SmartGateTest is MudTest {
}

function testLinkSmartGates() public {
testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
smartGate.linkSmartGates(sourceGateId, destinationGateId);
assert(smartGate.isGateLinked(sourceGateId, destinationGateId));
assert(smartGate.isGateLinked(destinationGateId, sourceGateId));
}

function tesReverttLinkSmartGates() public {
function testRevertLinkSmartGates() public {
testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
vm.expectRevert(
abi.encodeWithSelector(
SmartGateSystem.SmartGate_SameSourceAndDestination.selector,
sourceGateId,
destinationGateId
)
abi.encodeWithSelector(SmartGateSystem.SmartGate_SameSourceAndDestination.selector, sourceGateId, sourceGateId)
);
smartGate.linkSmartGates(sourceGateId, sourceGateId);
}
Expand Down Expand Up @@ -265,8 +266,58 @@ contract SmartGateTest is MudTest {
assertTrue(linkDataDC.isLinked);
}

function testLinkFromSourceAndUnlinkFromDest() public {
uint256 smartGateA = 123;
uint256 smartGateB = 124;
uint256 smartGateC = 125;

testAnchorSmartGate(smartGateA);
testAnchorSmartGate(smartGateB);
testAnchorSmartGate(smartGateC);

//link AB
smartGate.linkSmartGates(smartGateA, smartGateB);
SmartGateLinkTableData memory linkDataAB = SmartGateLinkTable.get(smartGateA);
assertTrue(linkDataAB.isLinked);

SmartGateLinkTableData memory linkDataBA = SmartGateLinkTable.get(smartGateB);
assertTrue(linkDataBA.isLinked);

//unlink BA
smartGate.unlinkSmartGates(smartGateB, smartGateA);
linkDataBA = SmartGateLinkTable.get(smartGateB);
assertFalse(linkDataBA.isLinked);

linkDataAB = SmartGateLinkTable.get(smartGateA);
assertFalse(linkDataAB.isLinked);

//link BC
smartGate.linkSmartGates(smartGateB, smartGateC);
SmartGateLinkTableData memory linkDataBC = SmartGateLinkTable.get(smartGateB);
assert(linkDataBC.isLinked);

SmartGateLinkTableData memory linkDataCB = SmartGateLinkTable.get(smartGateC);
assert(linkDataCB.isLinked);

//BA link should be replaced with BC
linkDataBA = SmartGateLinkTable.get(smartGateB);
assertFalse(linkDataBA.destinationGateId == smartGateA);
assert(linkDataBA.destinationGateId == smartGateC);

//AB link record should not exists
linkDataAB = SmartGateLinkTable.get(smartGateA);
assert(linkDataAB.destinationGateId == 0);
}

function testRevertExistingLink() public {
testLinkSmartGates();
testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
smartGate.linkSmartGates(sourceGateId, destinationGateId);

SmartGateLinkTableData memory linkData = SmartGateLinkTable.get(sourceGateId);
assertEq(linkData.destinationGateId, destinationGateId);
assertTrue(linkData.isLinked);

vm.expectRevert(
abi.encodeWithSelector(SmartGateSystem.SmartGate_GateAlreadyLinked.selector, sourceGateId, destinationGateId)
);
Expand Down Expand Up @@ -303,7 +354,7 @@ contract SmartGateTest is MudTest {
1 // maxDistance
);

smartDeployable.depositFuel(smartObjectIdA, 1);
smartDeployable.depositFuel(smartObjectIdA, 100000);
smartDeployable.bringOnline(smartObjectIdA);

smartGate.createAndAnchorSmartGate(
Expand All @@ -317,7 +368,7 @@ contract SmartGateTest is MudTest {
1 // maxDistance
);

smartDeployable.depositFuel(smartObjectIdB, 1);
smartDeployable.depositFuel(smartObjectIdB, 100000);
smartDeployable.bringOnline(smartObjectIdB);

vm.expectRevert(
Expand All @@ -342,24 +393,17 @@ contract SmartGateTest is MudTest {
}

function testCanJump() public {
testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
testLinkSmartGates();
assert(smartGate.canJump(characterId, sourceGateId, destinationGateId));
}

function testCanJumpFalse() public {
testConfigureSmartGate();

testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
testLinkSmartGates();
assert(!smartGate.canJump(characterId, sourceGateId, destinationGateId));
}

function testCanJump2way() public {
testAnchorSmartGate(sourceGateId);
testAnchorSmartGate(destinationGateId);
testLinkSmartGates();
assert(smartGate.canJump(characterId, destinationGateId, sourceGateId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ contract SmartTurretTest is MudTest {
1000000 * 1e18 // fuelMaxCapacity,
);

smartDeployable.depositFuel(smartObjectId, 1);
smartDeployable.depositFuel(smartObjectId, 100000);
smartDeployable.bringOnline(smartObjectId);

assertEq(uint256(SmartAssemblyTable.get(smartObjectId)), uint256(SmartAssemblyType.SMART_TURRET));
Expand Down
Loading
Loading